From 00daa6ad74acaeb04200681ef1cee5cdf45410d2 Mon Sep 17 00:00:00 2001 From: Mofei Zhu <13761509829@163.com> Date: Wed, 3 Sep 2025 13:11:38 +0300 Subject: [PATCH 1/7] improve style preview --- manifest.json | 2 +- package-lock.json | 4 +- package.json | 2 +- .../list-styles-tool/ListStylesTool.schema.ts | 11 +- src/tools/list-styles-tool/ListStylesTool.ts | 3 +- .../PreviewStyleTool.schema.ts | 5 + .../PreviewStyleTool.test.ts | 104 ++++++------------ .../preview-style-tool/PreviewStyleTool.ts | 40 ++----- 8 files changed, 64 insertions(+), 107 deletions(-) diff --git a/manifest.json b/manifest.json index 2b6c6d4..4187694 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "dxt_version": "0.1", "name": "@mapbox/mcp-devkit-server", "display_name": "Mapbox MCP DevKit Server", - "version": "0.3.0", + "version": "0.3.1", "description": "Mapbox MCP devkit server", "author": { "name": "Mapbox, Inc." diff --git a/package-lock.json b/package-lock.json index b26410f..85dc55a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mapbox/mcp-devkit-server", - "version": "0.3.0", + "version": "0.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mapbox/mcp-devkit-server", - "version": "0.3.0", + "version": "0.3.1", "license": "BSD-3-Clause", "dependencies": { "@modelcontextprotocol/sdk": "^1.12.1", diff --git a/package.json b/package.json index 1ea9560..33d26b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mapbox/mcp-devkit-server", - "version": "0.3.0", + "version": "0.3.1", "description": "Mapbox MCP devkit server", "main": "dist/index.js", "module": "dist/index-esm.js", diff --git a/src/tools/list-styles-tool/ListStylesTool.schema.ts b/src/tools/list-styles-tool/ListStylesTool.schema.ts index 0b682c7..eb5de47 100644 --- a/src/tools/list-styles-tool/ListStylesTool.schema.ts +++ b/src/tools/list-styles-tool/ListStylesTool.schema.ts @@ -4,8 +4,15 @@ export const ListStylesSchema = z.object({ limit: z .number() .optional() - .describe('Maximum number of styles to return (default: no limit)'), - start: z.string().optional().describe('Start token for pagination') + .describe( + 'Maximum number of styles to return (recommended: 10-50 to avoid token limits, default: no limit)' + ), + start: z + .string() + .optional() + .describe( + 'Start token for pagination (use the "start" value from previous response)' + ) }); export type ListStylesInput = z.infer; diff --git a/src/tools/list-styles-tool/ListStylesTool.ts b/src/tools/list-styles-tool/ListStylesTool.ts index 0c62ba9..faca9a4 100644 --- a/src/tools/list-styles-tool/ListStylesTool.ts +++ b/src/tools/list-styles-tool/ListStylesTool.ts @@ -5,7 +5,8 @@ export class ListStylesTool extends MapboxApiBasedTool< typeof ListStylesSchema > { name = 'list_styles_tool'; - description = 'List all styles for a Mapbox account'; + description = + 'List styles for a Mapbox account. Use limit parameter to avoid large responses (recommended: limit=5-10). Use start parameter for pagination.'; constructor() { super({ inputSchema: ListStylesSchema }); diff --git a/src/tools/preview-style-tool/PreviewStyleTool.schema.ts b/src/tools/preview-style-tool/PreviewStyleTool.schema.ts index 5254fda..7397d6f 100644 --- a/src/tools/preview-style-tool/PreviewStyleTool.schema.ts +++ b/src/tools/preview-style-tool/PreviewStyleTool.schema.ts @@ -2,6 +2,11 @@ import { z } from 'zod'; export const PreviewStyleSchema = z.object({ styleId: z.string().describe('Style ID to preview'), + accessToken: z + .string() + .describe( + 'Mapbox public access token (required, must start with pk.* and have styles:read permission). Secret tokens (sk.*) cannot be used as they cannot be exposed in browser URLs. Please use an existing public token or get one from list_tokens_tool or create one with create_token_tool with styles:read permission.' + ), title: z .boolean() .optional() diff --git a/src/tools/preview-style-tool/PreviewStyleTool.test.ts b/src/tools/preview-style-tool/PreviewStyleTool.test.ts index 7867dae..83e2b4a 100644 --- a/src/tools/preview-style-tool/PreviewStyleTool.test.ts +++ b/src/tools/preview-style-tool/PreviewStyleTool.test.ts @@ -1,43 +1,14 @@ // Use a token with valid JWT format for tests process.env.MAPBOX_ACCESS_TOKEN = - 'eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; + 'pk.eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; -import { ListTokensTool } from '../list-tokens-tool/ListTokensTool.js'; import { PreviewStyleTool } from './PreviewStyleTool.js'; describe('PreviewStyleTool', () => { - let mockListTokensTool: jest.SpyInstance; - - beforeEach(() => { - // Mock the ListTokensTool.run method - mockListTokensTool = jest - .spyOn(ListTokensTool.prototype, 'run') - .mockResolvedValue({ - isError: false, - content: [ - { - type: 'text', - text: JSON.stringify({ - tokens: [ - { - id: 'cktest123', - note: 'Public token for testing', - usage: 'pk', - token: - 'pk.eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIn0.public_token', - scopes: ['styles:read', 'fonts:read'] - } - ], - count: 1 - }) - } - ] - }); - }); + const TEST_ACCESS_TOKEN = + 'pk.eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; - afterEach(() => { - jest.restoreAllMocks(); - }); + // No setup needed since we use user-provided tokens directly describe('tool metadata', () => { it('should have correct name and description', () => { @@ -54,8 +25,11 @@ describe('PreviewStyleTool', () => { }); }); - it('fetches public token and returns preview URL', async () => { - const result = await new PreviewStyleTool().run({ styleId: 'test-style' }); + it('uses user-provided public token and returns preview URL', async () => { + const result = await new PreviewStyleTool().run({ + styleId: 'test-style', + accessToken: TEST_ACCESS_TOKEN + }); expect(result.isError).toBe(false); expect(result.content[0]).toMatchObject({ @@ -64,16 +38,12 @@ describe('PreviewStyleTool', () => { '/styles/v1/test-user/test-style.html?access_token=pk.' ) }); - - // Verify that ListTokensTool was called with correct parameters - expect(mockListTokensTool).toHaveBeenCalledWith({ - usage: 'pk' - }); }); it('includes styleId in URL', async () => { const result = await new PreviewStyleTool().run({ - styleId: 'my-custom-style' + styleId: 'my-custom-style', + accessToken: TEST_ACCESS_TOKEN }); expect(result.content[0]).toMatchObject({ @@ -85,6 +55,7 @@ describe('PreviewStyleTool', () => { it('includes title parameter when provided', async () => { const result = await new PreviewStyleTool().run({ styleId: 'test-style', + accessToken: TEST_ACCESS_TOKEN, title: true }); @@ -97,6 +68,7 @@ describe('PreviewStyleTool', () => { it('includes zoomwheel parameter when provided', async () => { const result = await new PreviewStyleTool().run({ styleId: 'test-style', + accessToken: TEST_ACCESS_TOKEN, zoomwheel: false }); @@ -108,7 +80,8 @@ describe('PreviewStyleTool', () => { it('includes fresh parameter for secure access', async () => { const result = await new PreviewStyleTool().run({ - styleId: 'test-style' + styleId: 'test-style', + accessToken: TEST_ACCESS_TOKEN }); expect(result.content[0]).toMatchObject({ @@ -117,51 +90,42 @@ describe('PreviewStyleTool', () => { }); }); - it('handles token listing failure', async () => { - mockListTokensTool.mockResolvedValueOnce({ - isError: true, - content: [ - { - type: 'text', - text: 'Token listing failed' - } - ] + it('rejects secret tokens', async () => { + const result = await new PreviewStyleTool().run({ + styleId: 'test-style', + accessToken: + 'sk.eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIn0.secret_token' }); - const result = await new PreviewStyleTool().run({ styleId: 'test-style' }); - expect(result.isError).toBe(true); expect(result.content[0]).toMatchObject({ type: 'text', - text: expect.stringContaining('Failed to retrieve public tokens') + text: expect.stringContaining( + 'Invalid access token. Only public tokens (starting with pk.*) are allowed' + ) }); }); - it('handles no public tokens found', async () => { - mockListTokensTool.mockResolvedValueOnce({ - isError: false, - content: [ - { - type: 'text', - text: JSON.stringify({ - tokens: [], - count: 0 - }) - } - ] + it('rejects temporary tokens', async () => { + const result = await new PreviewStyleTool().run({ + styleId: 'test-style', + accessToken: 'tk.eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIn0.temp_token' }); - const result = await new PreviewStyleTool().run({ styleId: 'test-style' }); - expect(result.isError).toBe(true); expect(result.content[0]).toMatchObject({ type: 'text', - text: expect.stringContaining('No public tokens found') + text: expect.stringContaining( + 'Invalid access token. Only public tokens (starting with pk.*) are allowed' + ) }); }); it('returns URL on success', async () => { - const result = await new PreviewStyleTool().run({ styleId: 'test-style' }); + const result = await new PreviewStyleTool().run({ + styleId: 'test-style', + accessToken: TEST_ACCESS_TOKEN + }); expect(result.isError).toBe(false); expect(result.content).toHaveLength(1); diff --git a/src/tools/preview-style-tool/PreviewStyleTool.ts b/src/tools/preview-style-tool/PreviewStyleTool.ts index 6cd27b0..083b057 100644 --- a/src/tools/preview-style-tool/PreviewStyleTool.ts +++ b/src/tools/preview-style-tool/PreviewStyleTool.ts @@ -1,13 +1,11 @@ +import { BaseTool } from '../BaseTool.js'; import { MapboxApiBasedTool } from '../MapboxApiBasedTool.js'; -import { ListTokensTool } from '../list-tokens-tool/ListTokensTool.js'; import { PreviewStyleSchema, PreviewStyleInput } from './PreviewStyleTool.schema.js'; -export class PreviewStyleTool extends MapboxApiBasedTool< - typeof PreviewStyleSchema -> { +export class PreviewStyleTool extends BaseTool { readonly name = 'preview_style_tool'; readonly description = 'Generate preview URL for a Mapbox style using an existing public token'; @@ -17,37 +15,19 @@ export class PreviewStyleTool extends MapboxApiBasedTool< } protected async execute( - input: PreviewStyleInput, - accessToken?: string + input: PreviewStyleInput ): Promise<{ type: 'text'; text: string }> { - const username = MapboxApiBasedTool.getUserNameFromToken(accessToken); - - // Get list of tokens to find a public token - const listTokensTool = new ListTokensTool(); - const tokensResult = await listTokensTool.run({ - usage: 'pk' // Filter for public tokens only - }); - - if (tokensResult.isError) { - throw new Error('Failed to retrieve public tokens'); - } - - // Extract tokens from the response - const firstContent = tokensResult.content[0]; - if (firstContent.type !== 'text') { - throw new Error('Unexpected response format from list tokens'); - } - const tokensData = JSON.parse(firstContent.text); - const publicTokens = tokensData.tokens; - - if (!publicTokens || publicTokens.length === 0) { + // Validate that the provided token is a public token + if (!input.accessToken.startsWith('pk.')) { throw new Error( - 'No public tokens found. Please create a public token first.' + 'Invalid access token. Only public tokens (starting with pk.*) are allowed for preview URLs. Secret tokens (sk.*) cannot be used as they cannot be exposed in browser URLs.' ); } - // Use the first available public token - const publicToken = publicTokens[0].token; + const username = MapboxApiBasedTool.getUserNameFromToken(input.accessToken); + + // Use the user-provided public token + const publicToken = input.accessToken; // Build URL for the embeddable HTML endpoint const params = new URLSearchParams(); From f05423f76e26c77394a00a8e6517e1e9416df035 Mon Sep 17 00:00:00 2001 From: Mofei Zhu <13761509829@163.com> Date: Wed, 3 Sep 2025 13:13:16 +0300 Subject: [PATCH 2/7] improve style preview --- src/tools/list-styles-tool/ListStylesTool.schema.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/list-styles-tool/ListStylesTool.schema.ts b/src/tools/list-styles-tool/ListStylesTool.schema.ts index eb5de47..e2715ba 100644 --- a/src/tools/list-styles-tool/ListStylesTool.schema.ts +++ b/src/tools/list-styles-tool/ListStylesTool.schema.ts @@ -5,7 +5,7 @@ export const ListStylesSchema = z.object({ .number() .optional() .describe( - 'Maximum number of styles to return (recommended: 10-50 to avoid token limits, default: no limit)' + 'Maximum number of styles to return (recommended: 5-10 to avoid token limits, default: no limit)' ), start: z .string() From b5797ab3eb28603b27a896952ceb5f1b65634b08 Mon Sep 17 00:00:00 2001 From: Mofei Zhu <13761509829@163.com> Date: Wed, 3 Sep 2025 13:28:47 +0300 Subject: [PATCH 3/7] improve style preview --- .../tool-naming-convention.test.ts.snap | 2 +- .../list-styles-tool/ListStylesTool.test.ts | 4 +++- .../PreviewStyleTool.test.ts | 22 +++++++++++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/tools/__snapshots__/tool-naming-convention.test.ts.snap b/src/tools/__snapshots__/tool-naming-convention.test.ts.snap index a1edcc3..97e36e9 100644 --- a/src/tools/__snapshots__/tool-naming-convention.test.ts.snap +++ b/src/tools/__snapshots__/tool-naming-convention.test.ts.snap @@ -39,7 +39,7 @@ exports[`Tool Naming Convention should maintain consistent tool list (snapshot t }, { "className": "ListStylesTool", - "description": "List all styles for a Mapbox account", + "description": "List styles for a Mapbox account. Use limit parameter to avoid large responses (recommended: limit=5-10). Use start parameter for pagination.", "toolName": "list_styles_tool", }, { diff --git a/src/tools/list-styles-tool/ListStylesTool.test.ts b/src/tools/list-styles-tool/ListStylesTool.test.ts index c8dca67..1a8fc7a 100644 --- a/src/tools/list-styles-tool/ListStylesTool.test.ts +++ b/src/tools/list-styles-tool/ListStylesTool.test.ts @@ -17,7 +17,9 @@ describe('ListStylesTool', () => { it('should have correct name and description', () => { const tool = new ListStylesTool(); expect(tool.name).toBe('list_styles_tool'); - expect(tool.description).toBe('List all styles for a Mapbox account'); + expect(tool.description).toBe( + 'List styles for a Mapbox account. Use limit parameter to avoid large responses (recommended: limit=5-10). Use start parameter for pagination.' + ); }); it('should have correct input schema', () => { diff --git a/src/tools/preview-style-tool/PreviewStyleTool.test.ts b/src/tools/preview-style-tool/PreviewStyleTool.test.ts index 83e2b4a..f9fef06 100644 --- a/src/tools/preview-style-tool/PreviewStyleTool.test.ts +++ b/src/tools/preview-style-tool/PreviewStyleTool.test.ts @@ -1,14 +1,32 @@ // Use a token with valid JWT format for tests process.env.MAPBOX_ACCESS_TOKEN = - 'pk.eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; + 'eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; +import { MapboxApiBasedTool } from '../MapboxApiBasedTool.js'; import { PreviewStyleTool } from './PreviewStyleTool.js'; describe('PreviewStyleTool', () => { const TEST_ACCESS_TOKEN = 'pk.eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; - // No setup needed since we use user-provided tokens directly + beforeEach(() => { + // Mock getUserNameFromToken to handle pk. prefixed tokens + jest + .spyOn(MapboxApiBasedTool, 'getUserNameFromToken') + .mockImplementation((token) => { + // If token starts with pk., we expect it to be a prefixed token + if (token && token.startsWith('pk.')) { + // For test token, return 'test-user' + return 'test-user'; + } + // For non-prefixed tokens, return 'test-user' as well + return 'test-user'; + }); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); describe('tool metadata', () => { it('should have correct name and description', () => { From ee6b589655ac330da7ef7129f58ebeef567027eb Mon Sep 17 00:00:00 2001 From: Mofei Zhu <13761509829@163.com> Date: Wed, 3 Sep 2025 13:33:49 +0300 Subject: [PATCH 4/7] improve style preview --- src/tools/list-styles-tool/ListStylesTool.test.ts | 2 +- src/tools/preview-style-tool/PreviewStyleTool.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/list-styles-tool/ListStylesTool.test.ts b/src/tools/list-styles-tool/ListStylesTool.test.ts index 1a8fc7a..b4148ac 100644 --- a/src/tools/list-styles-tool/ListStylesTool.test.ts +++ b/src/tools/list-styles-tool/ListStylesTool.test.ts @@ -1,6 +1,6 @@ // Use a token with valid JWT format for tests process.env.MAPBOX_ACCESS_TOKEN = - 'eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; + 'sk.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; import { setupFetch, diff --git a/src/tools/preview-style-tool/PreviewStyleTool.test.ts b/src/tools/preview-style-tool/PreviewStyleTool.test.ts index f9fef06..fa66f45 100644 --- a/src/tools/preview-style-tool/PreviewStyleTool.test.ts +++ b/src/tools/preview-style-tool/PreviewStyleTool.test.ts @@ -1,6 +1,6 @@ // Use a token with valid JWT format for tests process.env.MAPBOX_ACCESS_TOKEN = - 'eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; + 'sk.eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; import { MapboxApiBasedTool } from '../MapboxApiBasedTool.js'; import { PreviewStyleTool } from './PreviewStyleTool.js'; From 94187655c7cf45a727241196de0880fe944f7509 Mon Sep 17 00:00:00 2001 From: Mofei Zhu <13761509829@163.com> Date: Wed, 3 Sep 2025 13:44:11 +0300 Subject: [PATCH 5/7] clean test --- .../PreviewStyleTool.test.ts | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/tools/preview-style-tool/PreviewStyleTool.test.ts b/src/tools/preview-style-tool/PreviewStyleTool.test.ts index fa66f45..50f6eca 100644 --- a/src/tools/preview-style-tool/PreviewStyleTool.test.ts +++ b/src/tools/preview-style-tool/PreviewStyleTool.test.ts @@ -2,31 +2,11 @@ process.env.MAPBOX_ACCESS_TOKEN = 'sk.eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; -import { MapboxApiBasedTool } from '../MapboxApiBasedTool.js'; import { PreviewStyleTool } from './PreviewStyleTool.js'; describe('PreviewStyleTool', () => { const TEST_ACCESS_TOKEN = - 'pk.eyJhbGciOiJIUzI1NiJ9.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; - - beforeEach(() => { - // Mock getUserNameFromToken to handle pk. prefixed tokens - jest - .spyOn(MapboxApiBasedTool, 'getUserNameFromToken') - .mockImplementation((token) => { - // If token starts with pk., we expect it to be a prefixed token - if (token && token.startsWith('pk.')) { - // For test token, return 'test-user' - return 'test-user'; - } - // For non-prefixed tokens, return 'test-user' as well - return 'test-user'; - }); - }); - - afterEach(() => { - jest.restoreAllMocks(); - }); + 'pk.eyJ1IjoidGVzdC11c2VyIiwiYSI6InRlc3QtYXBpIn0.signature'; describe('tool metadata', () => { it('should have correct name and description', () => { From 0e355ae274fdb5ce577888feb9baf5ba4176a77f Mon Sep 17 00:00:00 2001 From: Mofei Zhu <13761509829@163.com> Date: Wed, 3 Sep 2025 13:50:51 +0300 Subject: [PATCH 6/7] clean test --- src/tools/preview-style-tool/PreviewStyleTool.schema.ts | 4 ++++ src/tools/preview-style-tool/PreviewStyleTool.ts | 7 ------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/tools/preview-style-tool/PreviewStyleTool.schema.ts b/src/tools/preview-style-tool/PreviewStyleTool.schema.ts index 7397d6f..eec52c3 100644 --- a/src/tools/preview-style-tool/PreviewStyleTool.schema.ts +++ b/src/tools/preview-style-tool/PreviewStyleTool.schema.ts @@ -4,6 +4,10 @@ export const PreviewStyleSchema = z.object({ styleId: z.string().describe('Style ID to preview'), accessToken: z .string() + .startsWith( + 'pk.', + 'Invalid access token. Only public tokens (starting with pk.*) are allowed for preview URLs. Secret tokens (sk.*) cannot be used as they cannot be exposed in browser URLs.' + ) .describe( 'Mapbox public access token (required, must start with pk.* and have styles:read permission). Secret tokens (sk.*) cannot be used as they cannot be exposed in browser URLs. Please use an existing public token or get one from list_tokens_tool or create one with create_token_tool with styles:read permission.' ), diff --git a/src/tools/preview-style-tool/PreviewStyleTool.ts b/src/tools/preview-style-tool/PreviewStyleTool.ts index 083b057..32783cd 100644 --- a/src/tools/preview-style-tool/PreviewStyleTool.ts +++ b/src/tools/preview-style-tool/PreviewStyleTool.ts @@ -17,13 +17,6 @@ export class PreviewStyleTool extends BaseTool { protected async execute( input: PreviewStyleInput ): Promise<{ type: 'text'; text: string }> { - // Validate that the provided token is a public token - if (!input.accessToken.startsWith('pk.')) { - throw new Error( - 'Invalid access token. Only public tokens (starting with pk.*) are allowed for preview URLs. Secret tokens (sk.*) cannot be used as they cannot be exposed in browser URLs.' - ); - } - const username = MapboxApiBasedTool.getUserNameFromToken(input.accessToken); // Use the user-provided public token From b4b54bae476627578212dd7b1ddbe725aa3337e7 Mon Sep 17 00:00:00 2001 From: Mofei Zhu <13761509829@163.com> Date: Wed, 3 Sep 2025 13:52:28 +0300 Subject: [PATCH 7/7] clean test --- .../StyleComparisonTool.schema.ts | 4 ++++ .../style-comparison-tool/StyleComparisonTool.ts | 16 ---------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/tools/style-comparison-tool/StyleComparisonTool.schema.ts b/src/tools/style-comparison-tool/StyleComparisonTool.schema.ts index 6f51be4..aa62aec 100644 --- a/src/tools/style-comparison-tool/StyleComparisonTool.schema.ts +++ b/src/tools/style-comparison-tool/StyleComparisonTool.schema.ts @@ -13,6 +13,10 @@ export const StyleComparisonSchema = z.object({ ), accessToken: z .string() + .startsWith( + 'pk.', + 'Invalid token type. Style comparison requires a public token (pk.*) that can be used in browser URLs. Secret tokens (sk.*) cannot be exposed in client-side applications. Please provide a public token with styles:read permission.' + ) .describe( 'Mapbox public access token (required, must start with pk.* and have styles:read permission). Secret tokens (sk.*) cannot be used as they cannot be exposed in browser URLs. Please use a public token or create one with styles:read permission.' ), diff --git a/src/tools/style-comparison-tool/StyleComparisonTool.ts b/src/tools/style-comparison-tool/StyleComparisonTool.ts index 334a858..1aec199 100644 --- a/src/tools/style-comparison-tool/StyleComparisonTool.ts +++ b/src/tools/style-comparison-tool/StyleComparisonTool.ts @@ -16,19 +16,6 @@ export class StyleComparisonTool extends BaseTool< super({ inputSchema: StyleComparisonSchema }); } - /** - * Validates that the token is a public token - */ - private validatePublicToken(token: string): void { - if (!token.startsWith('pk.')) { - throw new Error( - `Invalid token type. Style comparison requires a public token (pk.*) that can be used in browser URLs. ` + - `Secret tokens (sk.*) cannot be exposed in client-side applications. ` + - `Please provide a public token with styles:read permission.` - ); - } - } - /** * Processes style input to extract username/styleId format */ @@ -61,9 +48,6 @@ export class StyleComparisonTool extends BaseTool< protected async execute( input: StyleComparisonInput ): Promise<{ type: 'text'; text: string }> { - // Validate that we have a public token - this.validatePublicToken(input.accessToken); - // Process style IDs to get username/styleId format const beforeStyleId = this.processStyleId(input.before, input.accessToken); const afterStyleId = this.processStyleId(input.after, input.accessToken);