Skip to content
Open
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
- Optional detailed mode includes example requests and responses
- Complements `get_latest_mapbox_docs_tool` by providing structured API reference data
- No API access required - works with curated endpoint definitions
- **API Request Validator Tool**: New `validate_api_request_tool` validates API requests before sending them
- Validates required parameters are present
- Checks parameter types (string, number, boolean, array, object)
- Validates enum constraints for parameters with allowed values
- Verifies token has required scopes for operations
- Detects extra/unknown parameters with warnings
- Returns detailed validation results with specific error messages
- Helps prevent failed API calls by catching issues early

### Documentation

Expand Down
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,46 @@ The `MAPBOX_ACCESS_TOKEN` environment variable is required. **Each tool requires
- "What scopes do I need for the Styles API?"
- "How do I use the directions API? Show me examples"

**validate_api_request_tool** - Validate Mapbox API requests before sending them. Checks that requests have all required parameters, correct types, valid enum values, and required token scopes. Returns detailed validation results to help catch errors early.

> **Note:** This tool validates against a curated list of known Mapbox APIs. Newer APIs may not be included until the endpoint definitions are updated. If you encounter a "not found" error for a valid API, refer to the official [Mapbox API documentation](https://docs.mapbox.com/api/) or open an issue to request adding the new API.

**Features:**

- Validates required vs optional parameters
- Checks parameter types (string, number, boolean, array, object)
- Validates enum constraints (e.g., routing profiles must be "driving", "walking", etc.)
- Verifies token has required scopes
- Detects unknown/extra parameters with warnings
- Provides specific error messages for each issue

**Example prompts:**

- "Validate this geocoding request: {parameters}"
- "Check if my token has the right scopes for creating a style"
- "Is this directions API request valid?"
- "What's wrong with this API request?"

**test_api_request_tool** - Execute actual Mapbox API requests and generate code examples. Makes real HTTP calls to test endpoints and returns actual responses, with optional code generation showing how to replicate the call in curl, JavaScript, and Python.

**Features:**

- Makes real HTTP requests to Mapbox APIs
- Returns actual API responses with status codes and headers
- Generates code snippets in multiple languages (curl, JavaScript, Python)
- Shows execution timing and rate limit information
- Masks access tokens in generated code for security
- Supports all HTTP methods (GET, POST, PUT, PATCH, DELETE)
- Handles path, query, and body parameters

**Example prompts:**

- "Test the geocoding API with query 'San Francisco'"
- "Make a request to list my styles and show me the curl command"
- "Call the directions API from Paris to Lyon and generate code examples"
- "Test creating a token and show me how to do it in JavaScript"
- "Execute a tilequery request and generate Python code"

### Reference Tools

**get_reference_tool** - Access static Mapbox reference documentation and schemas. This tool provides essential reference information that helps AI assistants understand Mapbox concepts and build correct styles and tokens.
Expand Down
2 changes: 2 additions & 0 deletions src/tools/toolRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { StyleBuilderTool } from './style-builder-tool/StyleBuilderTool.js';
import { StyleComparisonTool } from './style-comparison-tool/StyleComparisonTool.js';
import { TilequeryTool } from './tilequery-tool/TilequeryTool.js';
import { UpdateStyleTool } from './update-style-tool/UpdateStyleTool.js';
import { ValidateApiRequestTool } from './validate-api-request-tool/ValidateApiRequestTool.js';
import { ValidateExpressionTool } from './validate-expression-tool/ValidateExpressionTool.js';
import { ValidateGeojsonTool } from './validate-geojson-tool/ValidateGeojsonTool.js';
import { ValidateStyleTool } from './validate-style-tool/ValidateStyleTool.js';
Expand Down Expand Up @@ -55,6 +56,7 @@ export const CORE_TOOLS = [
new GetFeedbackTool({ httpRequest }),
new ListFeedbackTool({ httpRequest }),
new TilequeryTool({ httpRequest }),
new ValidateApiRequestTool(),
new ValidateExpressionTool(),
new ValidateGeojsonTool(),
new ValidateStyleTool()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { z } from 'zod';

export const ValidateApiRequestInputSchema = z.object({
api: z
.string()
.describe(
'API name to validate against (e.g., "geocoding", "styles", "tokens")'
),
operation: z
.string()
.describe(
'Operation ID to validate (e.g., "forward-geocode", "create-style")'
),
parameters: z
.object({
path: z
.record(z.any())
.optional()
.describe('Path parameters as key-value pairs'),
query: z
.record(z.any())
.optional()
.describe('Query parameters as key-value pairs'),
body: z
.record(z.any())
.optional()
.describe('Body parameters as key-value pairs')
})
.describe('Request parameters to validate'),
tokenScopes: z
.array(z.string())
.optional()
.describe(
'Token scopes to validate (optional). If provided, checks if token has required scopes for the operation.'
)
});

export type ValidateApiRequestInput = z.infer<
typeof ValidateApiRequestInputSchema
>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { z } from 'zod';

const ValidationIssueSchema = z.object({
type: z.enum(['error', 'warning']),
field: z.string(),
message: z.string(),
expected: z.string().optional(),
received: z.any().optional()
});

const ParameterValidationSchema = z.object({
provided: z.number(),
required: z.number(),
optional: z.number(),
missing: z.array(z.string()),
extra: z.array(z.string())
});

const ScopeValidationSchema = z.object({
hasRequired: z.boolean(),
required: z.array(z.string()),
provided: z.array(z.string()).optional(),
missing: z.array(z.string()).optional()
});

// Output schema defines only the structured content
export const ValidateApiRequestOutputSchema = z.object({
valid: z.boolean(),
operation: z.object({
api: z.string(),
operation: z.string(),
method: z.string(),
endpoint: z.string()
}),
issues: z.array(ValidationIssueSchema),
parameters: z.object({
path: ParameterValidationSchema.optional(),
query: ParameterValidationSchema.optional(),
body: ParameterValidationSchema.optional()
}),
scopes: ScopeValidationSchema.optional()
});

export type ValidateApiRequestOutput = z.infer<
typeof ValidateApiRequestOutputSchema
>;
Loading