Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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",
Expand Down
19 changes: 14 additions & 5 deletions src/tools/BaseTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
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([
Expand All @@ -28,6 +29,7 @@
export abstract class BaseTool<InputSchema extends ZodTypeAny> {
abstract readonly name: string;
abstract readonly description: string;
abstract readonly annotations: ToolAnnotations;

readonly inputSchema: InputSchema;
protected server: McpServer | null = null;
Expand All @@ -41,7 +43,7 @@
*/
async run(
rawInput: unknown,
extra?: RequestHandlerExtra<any, any>

Check warning on line 46 in src/tools/BaseTool.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 46 in src/tools/BaseTool.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
): Promise<z.infer<typeof OutputSchema>> {
try {
const input = this.inputSchema.parse(rawInput);
Expand Down Expand Up @@ -101,12 +103,19 @@
*/
installTo(server: McpServer): RegisteredTool {
this.server = server;
return server.tool(

return server.registerTool(
this.name,
this.description,
(this.inputSchema as unknown as z.ZodObject<Record<string, z.ZodTypeAny>>)
.shape,
(args, extra) => this.run(args, extra)
{
description: this.description,
inputSchema: (
this.inputSchema as unknown as z.ZodObject<
Record<string, z.ZodTypeAny>
>
).shape,
annotations: this.annotations
},
(args: any, extra: any) => this.run(args, extra)

Check warning on line 118 in src/tools/BaseTool.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 118 in src/tools/BaseTool.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
);
}

Expand Down
7 changes: 7 additions & 0 deletions src/tools/bounding-box-tool/BoundingBoxTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ export class BoundingBoxTool extends BaseTool<typeof BoundingBoxSchema> {
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 });
Expand Down
7 changes: 7 additions & 0 deletions src/tools/bounding-box-tool/CountryBoundingBoxTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, [number, number, number, number]> =
boundariesData as unknown as Record<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
7 changes: 7 additions & 0 deletions src/tools/create-style-tool/CreateStyleTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
7 changes: 7 additions & 0 deletions src/tools/create-token-tool/CreateTokenTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
7 changes: 7 additions & 0 deletions src/tools/delete-style-tool/DeleteStyleTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
> {
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 });
Expand All @@ -18,7 +25,7 @@
protected async execute(
input: DeleteStyleInput,
accessToken?: string
): Promise<any> {

Check warning on line 28 in src/tools/delete-style-tool/DeleteStyleTool.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
const username = MapboxApiBasedTool.getUserNameFromToken(accessToken);
const url = `${MapboxApiBasedTool.mapboxApiEndpoint}styles/v1/${username}/${input.styleId}?access_token=${accessToken}`;

Expand Down
7 changes: 7 additions & 0 deletions src/tools/geojson-preview-tool/GeojsonPreviewTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ export class GeojsonPreviewTool extends BaseTool<typeof GeojsonPreviewSchema> {
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 });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
7 changes: 7 additions & 0 deletions src/tools/list-styles-tool/ListStylesTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
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 });
Expand All @@ -16,7 +23,7 @@
protected async execute(
input: ListStylesInput,
accessToken?: string
): Promise<any> {

Check warning on line 26 in src/tools/list-styles-tool/ListStylesTool.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
const username = MapboxApiBasedTool.getUserNameFromToken(accessToken);

// Build query parameters
Expand Down
7 changes: 7 additions & 0 deletions src/tools/list-tokens-tool/ListTokensTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
7 changes: 7 additions & 0 deletions src/tools/preview-style-tool/PreviewStyleTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ export class PreviewStyleTool extends BaseTool<typeof PreviewStyleSchema> {
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 });
Expand Down
7 changes: 7 additions & 0 deletions src/tools/retrieve-style-tool/RetrieveStyleTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
> {
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 });
Expand All @@ -19,7 +26,7 @@
protected async execute(
input: RetrieveStyleInput,
accessToken?: string
): Promise<any> {

Check warning on line 29 in src/tools/retrieve-style-tool/RetrieveStyleTool.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
const username = MapboxApiBasedTool.getUserNameFromToken(accessToken);
const url = `${MapboxApiBasedTool.mapboxApiEndpoint}styles/v1/${username}/${input.styleId}?access_token=${accessToken}`;

Expand Down
7 changes: 7 additions & 0 deletions src/tools/style-builder-tool/StyleBuilderTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@
export class StyleBuilderTool extends BaseTool<typeof StyleBuilderToolSchema> {
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.
Expand Down Expand Up @@ -341,7 +348,7 @@
style.zoom = 2;

// Build the import configuration
const importConfig: any = {

Check warning on line 351 in src/tools/style-builder-tool/StyleBuilderTool.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
id: 'basemap',
url: 'mapbox://styles/mapbox/standard'
};
Expand Down
7 changes: 7 additions & 0 deletions src/tools/style-comparison-tool/StyleComparisonTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
7 changes: 7 additions & 0 deletions src/tools/tilequery-tool/TilequeryTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ export class TilequeryTool extends MapboxApiBasedTool<typeof TilequerySchema> {
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 });
Expand Down
7 changes: 7 additions & 0 deletions src/tools/update-style-tool/UpdateStyleTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
Loading