Skip to content

Commit 13418a5

Browse files
Merge pull request #37 from mapbox/devkit_resources
[cursor] Adding bug fixes for known Cursor issues
2 parents b7baf99 + ba1813a commit 13418a5

File tree

6 files changed

+56
-60
lines changed

6 files changed

+56
-60
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ https://github.com/user-attachments/assets/8b1b8ef2-9fba-4951-bc9a-beaed4f6aff6
3535
- [Creating New Tools](#creating-new-tools)
3636
- [Environment Variables](#environment-variables)
3737
- [VERBOSE_ERRORS](#verbose_errors)
38+
- [Troubleshooting](#troubleshooting)
3839
- [Contributing](#contributing)
3940

4041
## Quick Start
@@ -558,6 +559,16 @@ Set `VERBOSE_ERRORS=true` to get detailed error messages from the MCP server. Th
558559

559560
By default, the server returns generic error messages. With verbose errors enabled, you'll receive the actual error details, which can help diagnose API connection issues, invalid parameters, or other problems.
560561

562+
## Troubleshooting
563+
564+
**Issue:** Tools fail with authentication errors
565+
566+
**Solution:** Check that your `MAPBOX_ACCESS_TOKEN` has the required scopes for the tool you're using. See the token scopes section above.
567+
568+
**Issue:** Large GeoJSON files cause slow performance
569+
570+
**Solution:** The GeoJSON preview tool may be slow with very large files. Consider simplifying geometries or using smaller datasets for preview purposes.
571+
561572
## Contributing
562573

563574
We welcome contributions to the Mapbox Development MCP Server! Please review our standards and guidelines before contributing:

src/tools/create-style-tool/CreateStyleTool.input.schema.ts

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,17 @@
33

44
import { z } from 'zod';
55

6-
// INPUT Schema - Simplified schema for creating styles
7-
// Only defines the essential required fields. Additional Mapbox Style Specification
8-
// properties (sources, layers, sprite, glyphs, etc.) are allowed via .passthrough()
6+
// INPUT Schema - Accepts a complete Mapbox Style Specification as a generic object
7+
// This avoids complex schemas with .passthrough() that break some MCP clients (Cursor + OpenAI)
98
// Full spec: https://docs.mapbox.com/mapbox-gl-js/style-spec/
10-
export const MapboxStyleInputSchema = z
11-
.object({
12-
name: z.string().describe('Human-readable name for the style (REQUIRED)'),
13-
version: z
14-
.literal(8)
15-
.describe('Style specification version number. Must be 8'),
16-
// Note: The Mapbox API requires at minimum 'version', 'name', 'sources', and 'layers'.
17-
// We only validate 'name' and 'version' here. Other fields like sources, layers, sprite,
18-
// glyphs, center, zoom, etc. are passed through without explicit validation to avoid
19-
// overwhelming clients with the full 18+ field schema.
20-
sources: z
21-
.record(z.any())
22-
.optional()
23-
.describe('Data source specifications'),
24-
layers: z.array(z.any()).optional().describe('Layers in draw order')
25-
})
26-
.passthrough()
27-
.describe(
28-
'Mapbox style input. Accepts standard Mapbox Style Specification properties. Only key fields are validated; additional properties (center, zoom, bearing, pitch, sprite, glyphs, metadata, etc.) are accepted but not explicitly defined to keep schema manageable.'
29-
);
9+
export const CreateStyleInputSchema = z.object({
10+
name: z.string().describe('Human-readable name for the style'),
11+
style: z
12+
.record(z.any())
13+
.describe(
14+
'Complete Mapbox Style Specification object. Must include: version (8), sources, layers. Optional: sprite, glyphs, center, zoom, bearing, pitch, metadata, etc. See https://docs.mapbox.com/mapbox-gl-js/style-spec/'
15+
)
16+
});
3017

3118
// Type exports
32-
export type MapboxStyleInput = z.infer<typeof MapboxStyleInputSchema>;
19+
export type CreateStyleInput = z.infer<typeof CreateStyleInputSchema>;

src/tools/create-style-tool/CreateStyleTool.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ import { getUserNameFromToken } from '../../utils/jwtUtils.js';
77
import { filterExpandedMapboxStyles } from '../../utils/styleUtils.js';
88
import { MapboxApiBasedTool } from '../MapboxApiBasedTool.js';
99
import {
10-
MapboxStyleInputSchema,
11-
MapboxStyleInput
10+
CreateStyleInputSchema,
11+
CreateStyleInput
1212
} from './CreateStyleTool.input.schema.js';
1313
import {
1414
MapboxStyleOutput,
1515
MapboxStyleOutputSchema
1616
} from './CreateStyleTool.output.schema.js';
1717

1818
export class CreateStyleTool extends MapboxApiBasedTool<
19-
typeof MapboxStyleInputSchema,
19+
typeof CreateStyleInputSchema,
2020
typeof MapboxStyleOutputSchema
2121
> {
2222
name = 'create_style_tool';
@@ -31,25 +31,31 @@ export class CreateStyleTool extends MapboxApiBasedTool<
3131

3232
constructor(params: { httpRequest: HttpRequest }) {
3333
super({
34-
inputSchema: MapboxStyleInputSchema,
34+
inputSchema: CreateStyleInputSchema,
3535
outputSchema: MapboxStyleOutputSchema,
3636
httpRequest: params.httpRequest
3737
});
3838
}
3939

4040
protected async execute(
41-
input: MapboxStyleInput,
41+
input: CreateStyleInput,
4242
accessToken?: string
4343
): Promise<CallToolResult> {
4444
const username = getUserNameFromToken(accessToken);
4545
const url = `${MapboxApiBasedTool.mapboxApiEndpoint}styles/v1/${username}?access_token=${accessToken}`;
4646

47+
// Merge name into style object for API request
48+
const payload = {
49+
...input.style,
50+
name: input.name
51+
};
52+
4753
const response = await this.httpRequest(url, {
4854
method: 'POST',
4955
headers: {
5056
'Content-Type': 'application/json'
5157
},
52-
body: JSON.stringify(input)
58+
body: JSON.stringify(payload)
5359
});
5460

5561
if (!response.ok) {

src/tools/update-style-tool/UpdateStyleTool.input.schema.ts

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,17 @@
33

44
import { z } from 'zod';
55

6-
// Simplified Mapbox Style Input Schema for updates
7-
// Only defines essential fields. Additional properties are accepted via .passthrough()
8-
export const MapboxStyleInputSchema = z
9-
.object({
10-
name: z.string().optional().describe('Human-readable name for the style'),
11-
version: z.literal(8).optional().describe('Style specification version'),
12-
sources: z
13-
.record(z.any())
14-
.optional()
15-
.describe('Data source specifications'),
16-
layers: z.array(z.any()).optional().describe('Layers in draw order')
17-
})
18-
.passthrough()
19-
.describe(
20-
'Mapbox style properties to update. Accepts standard Mapbox Style Specification properties.'
21-
);
22-
6+
// INPUT Schema - Accepts a complete Mapbox Style Specification as a generic object
7+
// This avoids complex schemas with .passthrough() that break some MCP clients (Cursor + OpenAI)
238
export const UpdateStyleInputSchema = z.object({
249
styleId: z.string().describe('Style ID to update'),
2510
name: z.string().optional().describe('New name for the style'),
26-
style: MapboxStyleInputSchema.optional().describe(
27-
'Updated Mapbox style specification object'
28-
)
11+
style: z
12+
.record(z.any())
13+
.optional()
14+
.describe(
15+
'Complete Mapbox Style Specification object to update. Must include: version (8), sources, layers. Optional: sprite, glyphs, center, zoom, bearing, pitch, metadata, etc. See https://docs.mapbox.com/mapbox-gl-js/style-spec/'
16+
)
2917
});
3018

3119
export type UpdateStyleInput = z.infer<typeof UpdateStyleInputSchema>;

test/tools/create-style-tool/CreateStyleTool.test.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ describe('CreateStyleTool', () => {
2929
});
3030

3131
it('should have correct input schema', async () => {
32-
const { MapboxStyleInputSchema } = await import(
32+
const { CreateStyleInputSchema } = await import(
3333
'../../../src/tools/create-style-tool/CreateStyleTool.input.schema.js'
3434
);
35-
expect(MapboxStyleInputSchema).toBeDefined();
35+
expect(CreateStyleInputSchema).toBeDefined();
3636
});
3737
});
3838

@@ -50,9 +50,11 @@ describe('CreateStyleTool', () => {
5050

5151
await new CreateStyleTool({ httpRequest }).run({
5252
name: 'Test Style',
53-
version: 8,
54-
sources: {},
55-
layers: []
53+
style: {
54+
version: 8,
55+
sources: {},
56+
layers: []
57+
}
5658
});
5759
assertHeadersSent(mockHttpRequest);
5860
});
@@ -66,9 +68,11 @@ describe('CreateStyleTool', () => {
6668

6769
const result = await new CreateStyleTool({ httpRequest }).run({
6870
name: 'Test Style',
69-
version: 8,
70-
sources: {},
71-
layers: []
71+
style: {
72+
version: 8,
73+
sources: {},
74+
layers: []
75+
}
7276
});
7377

7478
expect(result.isError).toBe(true);

test/tools/update-style-tool/UpdateStyleTool.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ describe('UpdateStyleTool', () => {
2929
});
3030

3131
it('should have correct input schema', async () => {
32-
const { MapboxStyleInputSchema } = await import(
32+
const { UpdateStyleInputSchema } = await import(
3333
'../../../src/tools/update-style-tool/UpdateStyleTool.input.schema.js'
3434
);
35-
expect(MapboxStyleInputSchema).toBeDefined();
35+
expect(UpdateStyleInputSchema).toBeDefined();
3636
});
3737
});
3838

0 commit comments

Comments
 (0)