From 829fec4df5fb9cf0e09fa9f7b90286694326aa3f Mon Sep 17 00:00:00 2001 From: Mofei Zhu <13761509829@163.com> Date: Thu, 25 Sep 2025 16:51:56 +0300 Subject: [PATCH 1/2] annotation --- package-lock.json | 2 +- package.json | 3 ++- src/tools/BaseTool.ts | 19 ++++++++++++++----- .../bounding-box-tool/BoundingBoxTool.ts | 7 +++++++ .../CountryBoundingBoxTool.ts | 7 +++++++ .../CoordinateConversionTool.ts | 7 +++++++ .../create-style-tool/CreateStyleTool.ts | 7 +++++++ .../create-token-tool/CreateTokenTool.ts | 7 +++++++ .../delete-style-tool/DeleteStyleTool.ts | 7 +++++++ .../GeojsonPreviewTool.ts | 7 +++++++ .../GetMapboxDocSourceTool.ts | 7 +++++++ src/tools/list-styles-tool/ListStylesTool.ts | 7 +++++++ src/tools/list-tokens-tool/ListTokensTool.ts | 7 +++++++ .../preview-style-tool/PreviewStyleTool.ts | 7 +++++++ .../retrieve-style-tool/RetrieveStyleTool.ts | 7 +++++++ .../style-builder-tool/StyleBuilderTool.ts | 7 +++++++ .../StyleComparisonTool.ts | 7 +++++++ src/tools/tilequery-tool/TilequeryTool.ts | 7 +++++++ .../update-style-tool/UpdateStyleTool.ts | 7 +++++++ 19 files changed, 129 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 49d2e04..d3fbc12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "@mapbox/mcp-devkit-server", "version": "0.4.0", - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.17.5", "zod": "^3.25.42" diff --git a/package.json b/package.json index 1aa9e96..9a767a8 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "build": "npm run prepare && npm run sync-manifest-version && tshy && npm run generate-version && node scripts/build-helpers.cjs copy-json && node scripts/add-shebang.cjs", "generate-version": "node scripts/build-helpers.cjs generate-version", "sync-manifest-version": "node scripts/build-helpers.cjs sync-manifest-version", - "dev": "tsc -p tsconfig.json --watch" + "dev": "tsc -p tsconfig.json --watch", + "dev:inspect": "npm run build && npx @modelcontextprotocol/inspector -e MAPBOX_ACCESS_TOKEN=\"$MAPBOX_ACCESS_PRIVATE_TOKEN\" node dist/esm/index.js" }, "lint-staged": { "*.{js,jsx,ts,tsx}": "eslint --fix", diff --git a/src/tools/BaseTool.ts b/src/tools/BaseTool.ts index 5ecbf9d..8080cfa 100644 --- a/src/tools/BaseTool.ts +++ b/src/tools/BaseTool.ts @@ -3,6 +3,7 @@ import { RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js'; import { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js'; +import { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'; import { z, ZodTypeAny } from 'zod'; const ContentItemSchema = z.union([ @@ -28,6 +29,7 @@ export type ToolOutput = z.infer; export abstract class BaseTool { abstract readonly name: string; abstract readonly description: string; + abstract readonly annotations: ToolAnnotations; readonly inputSchema: InputSchema; protected server: McpServer | null = null; @@ -101,12 +103,19 @@ export abstract class BaseTool { */ installTo(server: McpServer): RegisteredTool { this.server = server; - return server.tool( + + return server.registerTool( this.name, - this.description, - (this.inputSchema as unknown as z.ZodObject>) - .shape, - (args, extra) => this.run(args, extra) + { + description: this.description, + inputSchema: ( + this.inputSchema as unknown as z.ZodObject< + Record + > + ).shape, + annotations: this.annotations + }, + (args: any, extra: any) => this.run(args, extra) ); } diff --git a/src/tools/bounding-box-tool/BoundingBoxTool.ts b/src/tools/bounding-box-tool/BoundingBoxTool.ts index c2c7c4e..2cbaa3c 100644 --- a/src/tools/bounding-box-tool/BoundingBoxTool.ts +++ b/src/tools/bounding-box-tool/BoundingBoxTool.ts @@ -16,6 +16,13 @@ export class BoundingBoxTool extends BaseTool { readonly name = 'bounding_box_tool'; readonly description = 'Calculates bounding box of given GeoJSON content, returns as [minX, minY, maxX, maxY]'; + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false, + title: 'Calculate GeoJSON Bounding Box Tool' + }; constructor() { super({ inputSchema: BoundingBoxSchema }); diff --git a/src/tools/bounding-box-tool/CountryBoundingBoxTool.ts b/src/tools/bounding-box-tool/CountryBoundingBoxTool.ts index 2765e14..e834169 100644 --- a/src/tools/bounding-box-tool/CountryBoundingBoxTool.ts +++ b/src/tools/bounding-box-tool/CountryBoundingBoxTool.ts @@ -11,6 +11,13 @@ export class CountryBoundingBoxTool extends BaseTool< readonly name = 'country_bounding_box_tool'; readonly description = 'Gets bounding box for a country by its ISO 3166-1 country code, returns as [minX, minY, maxX, maxY].'; + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false, + title: 'Get Country Bounding Box Tool' + }; private boundariesData: Record = boundariesData as unknown as Record< diff --git a/src/tools/coordinate-conversion-tool/CoordinateConversionTool.ts b/src/tools/coordinate-conversion-tool/CoordinateConversionTool.ts index 346a6e5..aab9c64 100644 --- a/src/tools/coordinate-conversion-tool/CoordinateConversionTool.ts +++ b/src/tools/coordinate-conversion-tool/CoordinateConversionTool.ts @@ -10,6 +10,13 @@ export class CoordinateConversionTool extends BaseTool< readonly name = 'coordinate_conversion_tool'; readonly description = 'Converts coordinates between WGS84 (longitude/latitude) and EPSG:3857 (Web Mercator) coordinate systems'; + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false, + title: 'Convert Coordinates Tool' + }; constructor() { super({ inputSchema: CoordinateConversionSchema }); diff --git a/src/tools/create-style-tool/CreateStyleTool.ts b/src/tools/create-style-tool/CreateStyleTool.ts index 4a60cb4..f1dbdb7 100644 --- a/src/tools/create-style-tool/CreateStyleTool.ts +++ b/src/tools/create-style-tool/CreateStyleTool.ts @@ -11,6 +11,13 @@ export class CreateStyleTool extends MapboxApiBasedTool< > { name = 'create_style_tool'; description = 'Create a new Mapbox style'; + readonly annotations = { + readOnlyHint: false, + destructiveHint: false, + idempotentHint: false, + openWorldHint: true, + title: 'Create Mapbox Style Tool' + }; constructor(private fetch: typeof globalThis.fetch = fetchClient) { super({ inputSchema: CreateStyleSchema }); diff --git a/src/tools/create-token-tool/CreateTokenTool.ts b/src/tools/create-token-tool/CreateTokenTool.ts index 0b2f15b..d242550 100644 --- a/src/tools/create-token-tool/CreateTokenTool.ts +++ b/src/tools/create-token-tool/CreateTokenTool.ts @@ -11,6 +11,13 @@ export class CreateTokenTool extends MapboxApiBasedTool< readonly name = 'create_token_tool'; readonly description = 'Create a new Mapbox public access token with specified scopes and optional URL restrictions.'; + readonly annotations = { + readOnlyHint: false, + destructiveHint: false, + idempotentHint: false, + openWorldHint: true, + title: 'Create Mapbox Token Tool' + }; constructor(private fetch: typeof globalThis.fetch = fetchClient) { super({ inputSchema: CreateTokenSchema }); diff --git a/src/tools/delete-style-tool/DeleteStyleTool.ts b/src/tools/delete-style-tool/DeleteStyleTool.ts index e66830f..1be3a4c 100644 --- a/src/tools/delete-style-tool/DeleteStyleTool.ts +++ b/src/tools/delete-style-tool/DeleteStyleTool.ts @@ -10,6 +10,13 @@ export class DeleteStyleTool extends MapboxApiBasedTool< > { name = 'delete_style_tool'; description = 'Delete a Mapbox style by ID'; + readonly annotations = { + readOnlyHint: false, + destructiveHint: true, + idempotentHint: true, + openWorldHint: true, + title: 'Delete Mapbox Style Tool' + }; constructor(private fetch: typeof globalThis.fetch = fetchClient) { super({ inputSchema: DeleteStyleSchema }); diff --git a/src/tools/geojson-preview-tool/GeojsonPreviewTool.ts b/src/tools/geojson-preview-tool/GeojsonPreviewTool.ts index 38cf3ef..cc573cd 100644 --- a/src/tools/geojson-preview-tool/GeojsonPreviewTool.ts +++ b/src/tools/geojson-preview-tool/GeojsonPreviewTool.ts @@ -9,6 +9,13 @@ export class GeojsonPreviewTool extends BaseTool { name = 'geojson_preview_tool'; description = 'Generate a geojson.io URL to visualize GeoJSON data. Returns only the URL link.'; + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false, + title: 'Preview GeoJSON Data Tool' + }; constructor() { super({ inputSchema: GeojsonPreviewSchema }); diff --git a/src/tools/get-mapbox-doc-source-tool/GetMapboxDocSourceTool.ts b/src/tools/get-mapbox-doc-source-tool/GetMapboxDocSourceTool.ts index 0bf875f..e1df7f2 100644 --- a/src/tools/get-mapbox-doc-source-tool/GetMapboxDocSourceTool.ts +++ b/src/tools/get-mapbox-doc-source-tool/GetMapboxDocSourceTool.ts @@ -11,6 +11,13 @@ export class GetMapboxDocSourceTool extends BaseTool< name = 'get_latest_mapbox_docs_tool'; description = 'Get the latest official Mapbox documentation, APIs, SDKs, and developer resources directly from Mapbox. Always up-to-date, comprehensive coverage of all current Mapbox services including mapping, navigation, search, geocoding, and mobile SDKs. Use this for accurate, official Mapbox information instead of web search.'; + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: true, + title: 'Get Mapbox Documentation Tool' + }; constructor(private fetch: typeof globalThis.fetch = fetchClient) { super({ inputSchema: GetMapboxDocSourceSchema }); diff --git a/src/tools/list-styles-tool/ListStylesTool.ts b/src/tools/list-styles-tool/ListStylesTool.ts index 124e689..d0d1b52 100644 --- a/src/tools/list-styles-tool/ListStylesTool.ts +++ b/src/tools/list-styles-tool/ListStylesTool.ts @@ -8,6 +8,13 @@ export class ListStylesTool extends MapboxApiBasedTool< name = 'list_styles_tool'; description = 'List styles for a Mapbox account. Use limit parameter to avoid large responses (recommended: limit=5-10). Use start parameter for pagination.'; + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: true, + title: 'List Mapbox Styles Tool' + }; constructor(private fetch: typeof globalThis.fetch = fetchClient) { super({ inputSchema: ListStylesSchema }); diff --git a/src/tools/list-tokens-tool/ListTokensTool.ts b/src/tools/list-tokens-tool/ListTokensTool.ts index 2e235d4..5f8d6b2 100644 --- a/src/tools/list-tokens-tool/ListTokensTool.ts +++ b/src/tools/list-tokens-tool/ListTokensTool.ts @@ -8,6 +8,13 @@ export class ListTokensTool extends MapboxApiBasedTool< readonly name = 'list_tokens_tool'; readonly description = 'List Mapbox access tokens for the authenticated user with optional filtering and pagination. When using pagination, the "start" parameter must be obtained from the "next_start" field of the previous response (it is not a token ID)'; + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: true, + title: 'List Mapbox Tokens Tool' + }; constructor(private fetchImpl: typeof fetch = fetchClient) { super({ inputSchema: ListTokensSchema }); diff --git a/src/tools/preview-style-tool/PreviewStyleTool.ts b/src/tools/preview-style-tool/PreviewStyleTool.ts index 564d334..852ed6c 100644 --- a/src/tools/preview-style-tool/PreviewStyleTool.ts +++ b/src/tools/preview-style-tool/PreviewStyleTool.ts @@ -9,6 +9,13 @@ export class PreviewStyleTool extends BaseTool { readonly name = 'preview_style_tool'; readonly description = 'Generate preview URL for a Mapbox style using an existing public token'; + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false, + title: 'Preview Mapbox Style Tool' + }; constructor() { super({ inputSchema: PreviewStyleSchema }); diff --git a/src/tools/retrieve-style-tool/RetrieveStyleTool.ts b/src/tools/retrieve-style-tool/RetrieveStyleTool.ts index ca19b87..a8167da 100644 --- a/src/tools/retrieve-style-tool/RetrieveStyleTool.ts +++ b/src/tools/retrieve-style-tool/RetrieveStyleTool.ts @@ -11,6 +11,13 @@ export class RetrieveStyleTool extends MapboxApiBasedTool< > { name = 'retrieve_style_tool'; description = 'Retrieve a specific Mapbox style by ID'; + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: true, + title: 'Retrieve Mapbox Style Tool' + }; constructor(private fetch: typeof globalThis.fetch = fetchClient) { super({ inputSchema: RetrieveStyleSchema }); diff --git a/src/tools/style-builder-tool/StyleBuilderTool.ts b/src/tools/style-builder-tool/StyleBuilderTool.ts index 43e89a7..47d3585 100644 --- a/src/tools/style-builder-tool/StyleBuilderTool.ts +++ b/src/tools/style-builder-tool/StyleBuilderTool.ts @@ -53,6 +53,13 @@ const SOURCE_LAYER_GEOMETRY: Record< export class StyleBuilderTool extends BaseTool { name = 'style_builder_tool'; private currentSourceLayer?: string; // Track current source layer for better error messages + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false, + title: 'Build Mapbox Style JSON Tool' + }; description = `Generate Mapbox style JSON for creating new styles or updating existing ones. The tool intelligently resolves layer types and filter properties using Streets v8 data. diff --git a/src/tools/style-comparison-tool/StyleComparisonTool.ts b/src/tools/style-comparison-tool/StyleComparisonTool.ts index 1aec199..2aad35f 100644 --- a/src/tools/style-comparison-tool/StyleComparisonTool.ts +++ b/src/tools/style-comparison-tool/StyleComparisonTool.ts @@ -11,6 +11,13 @@ export class StyleComparisonTool extends BaseTool< readonly name = 'style_comparison_tool'; readonly description = 'Generate a comparison URL for comparing two Mapbox styles side-by-side'; + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false, + title: 'Compare Mapbox Styles Tool' + }; constructor() { super({ inputSchema: StyleComparisonSchema }); diff --git a/src/tools/tilequery-tool/TilequeryTool.ts b/src/tools/tilequery-tool/TilequeryTool.ts index 9210fdd..f5e75ca 100644 --- a/src/tools/tilequery-tool/TilequeryTool.ts +++ b/src/tools/tilequery-tool/TilequeryTool.ts @@ -6,6 +6,13 @@ export class TilequeryTool extends MapboxApiBasedTool { name = 'tilequery_tool'; description = 'Query vector and raster data from Mapbox tilesets at geographic coordinates'; + readonly annotations = { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: true, + title: 'Mapbox Tilequery Tool' + }; constructor(private fetch: typeof globalThis.fetch = fetchClient) { super({ inputSchema: TilequerySchema }); diff --git a/src/tools/update-style-tool/UpdateStyleTool.ts b/src/tools/update-style-tool/UpdateStyleTool.ts index f062c13..b487322 100644 --- a/src/tools/update-style-tool/UpdateStyleTool.ts +++ b/src/tools/update-style-tool/UpdateStyleTool.ts @@ -11,6 +11,13 @@ export class UpdateStyleTool extends MapboxApiBasedTool< > { name = 'update_style_tool'; description = 'Update an existing Mapbox style'; + readonly annotations = { + readOnlyHint: false, + destructiveHint: false, + idempotentHint: false, + openWorldHint: true, + title: 'Update Mapbox Style Tool' + }; constructor(private fetch: typeof globalThis.fetch = fetchClient) { super({ inputSchema: UpdateStyleSchema }); From f6f87fd5bdd2a9113a3b323e1ff0660bb4fd1013 Mon Sep 17 00:00:00 2001 From: Mofei Zhu <13761509829@163.com> Date: Thu, 25 Sep 2025 16:52:05 +0300 Subject: [PATCH 2/2] 0.4.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d3fbc12..6a5b346 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mapbox/mcp-devkit-server", - "version": "0.4.0", + "version": "0.4.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mapbox/mcp-devkit-server", - "version": "0.4.0", + "version": "0.4.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.17.5", diff --git a/package.json b/package.json index 9a767a8..b6b5e0d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mapbox/mcp-devkit-server", - "version": "0.4.0", + "version": "0.4.1", "description": "Mapbox MCP devkit server", "main": "./dist/commonjs/index.js", "module": "./dist/esm/index.js",