|
| 1 | +// Copyright (c) Mapbox, Inc. |
| 2 | +// Licensed under the MIT License. |
| 3 | + |
| 4 | +import type { PromptMessage } from '@modelcontextprotocol/sdk/types.js'; |
| 5 | +import { BasePrompt, type PromptArgument } from './BasePrompt.js'; |
| 6 | + |
| 7 | +/** |
| 8 | + * Prompt for systematically debugging Mapbox integration issues |
| 9 | + * |
| 10 | + * This prompt guides users through a comprehensive troubleshooting workflow: |
| 11 | + * 1. Verify token validity and scopes |
| 12 | + * 2. Check style configuration and existence |
| 13 | + * 3. Validate GeoJSON if applicable |
| 14 | + * 4. Test API endpoints |
| 15 | + * 5. Review error messages and provide solutions |
| 16 | + */ |
| 17 | +export class DebugMapboxIntegrationPrompt extends BasePrompt { |
| 18 | + readonly name = 'debug-mapbox-integration'; |
| 19 | + readonly description = |
| 20 | + 'Systematic troubleshooting workflow for Mapbox integration issues. Diagnoses token problems, style errors, API issues, and provides actionable solutions.'; |
| 21 | + |
| 22 | + readonly arguments: ReadonlyArray<PromptArgument> = [ |
| 23 | + { |
| 24 | + name: 'issue_description', |
| 25 | + description: |
| 26 | + 'Description of the problem (e.g., "map not loading", "401 error")', |
| 27 | + required: true |
| 28 | + }, |
| 29 | + { |
| 30 | + name: 'error_message', |
| 31 | + description: 'Exact error message from console or logs, if available', |
| 32 | + required: false |
| 33 | + }, |
| 34 | + { |
| 35 | + name: 'style_id', |
| 36 | + description: 'Mapbox style ID being used, if applicable', |
| 37 | + required: false |
| 38 | + }, |
| 39 | + { |
| 40 | + name: 'environment', |
| 41 | + description: |
| 42 | + 'Where the issue occurs: "development", "production", "staging"', |
| 43 | + required: false |
| 44 | + } |
| 45 | + ]; |
| 46 | + |
| 47 | + getMessages(args: Record<string, string>): PromptMessage[] { |
| 48 | + const issueDescription = args['issue_description']; |
| 49 | + const errorMessage = args['error_message']; |
| 50 | + const styleId = args['style_id']; |
| 51 | + const environment = args['environment'] || 'development'; |
| 52 | + |
| 53 | + let instructionText = `Debug Mapbox integration issue: "${issueDescription}" |
| 54 | +${errorMessage ? `\nError message: "${errorMessage}"` : ''} |
| 55 | +${styleId ? `Style ID: ${styleId}` : ''} |
| 56 | +Environment: ${environment} |
| 57 | +
|
| 58 | +Let's systematically diagnose and fix this issue. |
| 59 | +
|
| 60 | +## Phase 1: Token Verification |
| 61 | +
|
| 62 | +First, verify that tokens are properly configured: |
| 63 | +
|
| 64 | +1. **List all tokens** |
| 65 | + - Use list_tokens_tool to see all available tokens |
| 66 | + - Check the output carefully |
| 67 | +
|
| 68 | +2. **Analyze token issues** |
| 69 | + Look for common problems: |
| 70 | + - ❌ **No tokens exist**: Need to create tokens first |
| 71 | + - ❌ **Wrong token type**: Using secret token (sk.*) in client code |
| 72 | + - ❌ **Missing scopes**: Token doesn't have required scopes for the operation |
| 73 | + - ❌ **URL restrictions**: Token is restricted to different URLs than where it's being used |
| 74 | + - ❌ **Revoked token**: Token may have been revoked |
| 75 | +
|
| 76 | +3. **Check required scopes** |
| 77 | + Based on the issue, verify the token has the correct scopes: |
| 78 | +`; |
| 79 | + |
| 80 | + if (errorMessage && errorMessage.includes('401')) { |
| 81 | + instructionText += ` - **401 Unauthorized** typically means: |
| 82 | + * Token is invalid or revoked |
| 83 | + * Token is missing required scopes |
| 84 | + * Token is not set correctly (check: mapboxgl.accessToken = '...') |
| 85 | +`; |
| 86 | + } else if (errorMessage && errorMessage.includes('403')) { |
| 87 | + instructionText += ` - **403 Forbidden** typically means: |
| 88 | + * Token lacks required scope for this operation |
| 89 | + * URL restriction blocks this domain |
| 90 | + * Rate limit exceeded |
| 91 | +`; |
| 92 | + } else { |
| 93 | + instructionText += ` - Displaying maps: needs \`styles:read\`, \`fonts:read\` |
| 94 | + - Creating styles: needs \`styles:write\` |
| 95 | + - Listing styles: needs \`styles:list\` |
| 96 | + - Managing tokens: needs \`tokens:read\` or \`tokens:write\` |
| 97 | +`; |
| 98 | + } |
| 99 | + |
| 100 | + if (styleId) { |
| 101 | + instructionText += ` |
| 102 | +## Phase 2: Style Verification |
| 103 | +
|
| 104 | +Since a style ID was provided, let's verify it exists and is valid: |
| 105 | +
|
| 106 | +1. **List user's styles** |
| 107 | + - Use list_styles_tool to see all available styles |
| 108 | + - Check if "${styleId}" appears in the list |
| 109 | +
|
| 110 | +2. **Analyze style issues** |
| 111 | + - ❌ **Style not found**: Style ID may be incorrect or from different account |
| 112 | + - ❌ **Style from wrong account**: Using someone else's private style |
| 113 | + - ❌ **Malformed style ID**: Should be in format "mapbox://styles/username/style-id" |
| 114 | +
|
| 115 | +`; |
| 116 | + } else { |
| 117 | + instructionText += ` |
| 118 | +## Phase 2: Style Verification |
| 119 | +
|
| 120 | +No style ID provided. If the issue involves a specific style: |
| 121 | +1. Ask the user for the style ID they're trying to use |
| 122 | +2. Use list_styles_tool to verify it exists |
| 123 | +3. Check the style configuration |
| 124 | +
|
| 125 | +`; |
| 126 | + } |
| 127 | + |
| 128 | + instructionText += `## Phase 3: Common Error Pattern Matching |
| 129 | +
|
| 130 | +Analyze the error and provide specific solutions: |
| 131 | +
|
| 132 | +`; |
| 133 | + |
| 134 | + if (errorMessage) { |
| 135 | + instructionText += `Based on the error message "${errorMessage}", check for: |
| 136 | +
|
| 137 | +`; |
| 138 | + |
| 139 | + if ( |
| 140 | + errorMessage.toLowerCase().includes('401') || |
| 141 | + errorMessage.toLowerCase().includes('unauthorized') |
| 142 | + ) { |
| 143 | + instructionText += `### 401 Unauthorized Solutions: |
| 144 | +1. **Token not set**: Verify \`mapboxgl.accessToken = 'your-token'\` is called before creating the map |
| 145 | +2. **Invalid token**: The token may be malformed, revoked, or expired |
| 146 | +3. **Check token validity**: Use list_tokens_tool to verify the token exists |
| 147 | +4. **Environment variable**: If using env vars, ensure MAPBOX_ACCESS_TOKEN is set correctly |
| 148 | +
|
| 149 | +`; |
| 150 | + } |
| 151 | + |
| 152 | + if ( |
| 153 | + errorMessage.toLowerCase().includes('403') || |
| 154 | + errorMessage.toLowerCase().includes('forbidden') |
| 155 | + ) { |
| 156 | + instructionText += `### 403 Forbidden Solutions: |
| 157 | +1. **URL restriction**: Token is restricted to different URLs |
| 158 | + - Development: Check token allows http://localhost:* |
| 159 | + - Production: Check token allows your domain |
| 160 | +2. **Missing scope**: Token needs additional scopes |
| 161 | + - Use list_tokens_tool to check current scopes |
| 162 | + - Use update_token_tool to add required scopes |
| 163 | +3. **Rate limit**: Check if you've exceeded API rate limits |
| 164 | +
|
| 165 | +`; |
| 166 | + } |
| 167 | + |
| 168 | + if ( |
| 169 | + errorMessage.toLowerCase().includes('style') || |
| 170 | + errorMessage.toLowerCase().includes('404') |
| 171 | + ) { |
| 172 | + instructionText += `### Style Not Found Solutions: |
| 173 | +1. **Wrong style URL**: Verify format is "mapbox://styles/username/style-id" |
| 174 | +2. **Private style**: Ensure token has access to this style |
| 175 | +3. **Style deleted**: Check if style still exists using list_styles_tool |
| 176 | +4. **Typo in style ID**: Double-check the style ID spelling |
| 177 | +
|
| 178 | +`; |
| 179 | + } |
| 180 | + |
| 181 | + if ( |
| 182 | + errorMessage.toLowerCase().includes('source') || |
| 183 | + errorMessage.toLowerCase().includes('layer') |
| 184 | + ) { |
| 185 | + instructionText += `### Layer/Source Error Solutions: |
| 186 | +1. **Source not defined**: Ensure source is added before layers that reference it |
| 187 | +2. **Invalid layer type**: Check layer type matches source geometry |
| 188 | +3. **Missing required property**: Verify all required layer properties are set |
| 189 | +4. **Use get_reference_tool**: Get 'style-spec-reference' for layer requirements |
| 190 | +
|
| 191 | +`; |
| 192 | + } |
| 193 | + } else { |
| 194 | + instructionText += `### General debugging steps: |
| 195 | +
|
| 196 | +**If map isn't displaying:** |
| 197 | +1. Check browser console for errors |
| 198 | +2. Verify container div exists: \`<div id="map"></div>\` |
| 199 | +3. Ensure container has dimensions set in CSS: \`#map { height: 400px; }\` |
| 200 | +4. Confirm token is set before map initialization |
| 201 | +5. Check network tab for failed API requests |
| 202 | +
|
| 203 | +**If map loads but looks wrong:** |
| 204 | +1. Verify style ID is correct |
| 205 | +2. Check if custom layers are properly configured |
| 206 | +3. Ensure zoom/center coordinates are valid |
| 207 | +4. Review layer order and visibility |
| 208 | +
|
| 209 | +**If getting rate limit errors:** |
| 210 | +1. Check token usage in Mapbox dashboard |
| 211 | +2. Consider implementing request caching |
| 212 | +3. Review rate limit documentation |
| 213 | +4. Upgrade plan if needed |
| 214 | +
|
| 215 | +`; |
| 216 | + } |
| 217 | + |
| 218 | + instructionText += `## Phase 4: Testing & Validation |
| 219 | +
|
| 220 | +Run these diagnostic checks: |
| 221 | +
|
| 222 | +1. **Test token directly** |
| 223 | + - Use the token to list_styles_tool or list_tokens_tool |
| 224 | + - If these calls fail, the token itself is the issue |
| 225 | +
|
| 226 | +2. **Generate test preview** |
| 227 | + - If a style exists, use preview_style_tool to generate a working preview |
| 228 | + - Compare the working preview with the broken implementation |
| 229 | +
|
| 230 | +3. **Check documentation** |
| 231 | + - Use get_reference_tool with: |
| 232 | + * 'style-spec-reference' for style JSON issues |
| 233 | + * 'token-scopes-reference' for token scope questions |
| 234 | + * 'streets-v8-fields-reference' for data layer questions |
| 235 | +
|
| 236 | +## Phase 5: Solution Summary |
| 237 | +
|
| 238 | +After completing diagnostics, provide: |
| 239 | +
|
| 240 | +1. **Root cause identified**: Clearly state what the problem is |
| 241 | +2. **Immediate fix**: Step-by-step instructions to resolve the issue |
| 242 | +3. **Prevention**: How to avoid this issue in the future |
| 243 | +4. **Additional resources**: Relevant documentation links |
| 244 | +
|
| 245 | +## Phase 6: Verification |
| 246 | +
|
| 247 | +After applying fixes: |
| 248 | +
|
| 249 | +1. **Retest the integration** |
| 250 | + - Clear browser cache if testing in development |
| 251 | + - Check console for any new errors |
| 252 | + - Verify map loads and displays correctly |
| 253 | +
|
| 254 | +2. **Monitor for issues** |
| 255 | + - Watch for similar errors in production |
| 256 | + - Set up error tracking (Sentry, etc.) |
| 257 | + - Review Mapbox dashboard for usage patterns |
| 258 | +
|
| 259 | +--- |
| 260 | +
|
| 261 | +Begin the diagnostic process now. Run each phase systematically and present findings clearly to the user.`; |
| 262 | + |
| 263 | + return [ |
| 264 | + { |
| 265 | + role: 'user', |
| 266 | + content: { |
| 267 | + type: 'text', |
| 268 | + text: instructionText |
| 269 | + } |
| 270 | + } |
| 271 | + ]; |
| 272 | + } |
| 273 | +} |
0 commit comments