json_parser
Process JSON by parsing, validating, querying specific fields using dot-notation, or summarizing structure.
Instructions
Parse, validate, and query JSON data.
Modes:
"parse": Parse a JSON string and return it formatted.
"query": Extract a specific field using dot-notation (e.g., "data.users[0].name").
"validate": Check if a string is valid JSON and describe its structure.
"summarize": Return a schema-like summary of a JSON object's structure.
Examples:
Parse: '{"a":1,"b":2}' → pretty-printed object
Query: '{"users":[{"name":"Alice"}]}' with path "users[0].name" → "Alice"
Validate: '{"a":1}' → {"valid": true, "type": "object", "keys": ["a"]}
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| json | Yes | The JSON string to process. | |
| operation | No | The operation to perform on the JSON data. | parse |
| path | No | Dot-notation path for query mode (e.g., "users[0].name"). |
Implementation Reference
- src/tools/json-parser.ts:41-177 (handler)The main handler function for the json_parser tool. It accepts a JSON string and an operation (parse/query/validate/summarize), parses the JSON, and executes the requested operation. Uses auxiliary helper functions queryJson and summarizeStructure.
async ({ json, operation, path: queryPath }) => { try { let parsed: unknown; // Attempt to parse JSON try { parsed = JSON.parse(json); } catch (parseErr: any) { return { content: [ { type: "text" as const, text: JSON.stringify( { valid: false, error: parseErr.message, hint: "Check for trailing commas, unquoted keys, or single quotes.", }, null, 2 ), }, ], }; } switch (operation) { case "parse": { return { content: [ { type: "text" as const, text: JSON.stringify(parsed, null, 2), }, ], }; } case "query": { if (!queryPath) { return { content: [ { type: "text" as const, text: 'Error: "path" parameter is required for query operation.', }, ], isError: true, }; } const result = queryJson(parsed, queryPath); return { content: [ { type: "text" as const, text: JSON.stringify( { path: queryPath, found: true, value: result, type: Array.isArray(result) ? "array" : result === null ? "null" : typeof result, }, null, 2 ), }, ], }; } case "validate": { return { content: [ { type: "text" as const, text: JSON.stringify( { valid: true, type: Array.isArray(parsed) ? "array" : parsed === null ? "null" : typeof parsed, ...(Array.isArray(parsed) ? { length: parsed.length, itemTypes: [...new Set(parsed.map((i) => typeof i))] } : typeof parsed === "object" && parsed !== null ? { keys: Object.keys(parsed as object), keyCount: Object.keys(parsed as object).length } : { value: parsed }), }, null, 2 ), }, ], }; } case "summarize": { const summary = summarizeStructure(parsed); return { content: [ { type: "text" as const, text: JSON.stringify(summary, null, 2), }, ], }; } default: return { content: [ { type: "text" as const, text: `Error: Unknown operation '${operation}'.`, }, ], isError: true, }; } } catch (err: any) { return { content: [ { type: "text" as const, text: `JSON Parser Error: ${err.message}`, }, ], isError: true, }; } } - src/tools/json-parser.ts:28-40 (schema)Zod schema definitions for the json_parser tool: json (string), operation (enum: parse/query/validate/summarize, defaults to parse), and path (optional string for query mode).
{ json: z.string().describe("The JSON string to process."), operation: z .enum(["parse", "query", "validate", "summarize"]) .default("parse") .describe("The operation to perform on the JSON data."), path: z .string() .optional() .describe( 'Dot-notation path for query mode (e.g., "users[0].name").' ), }, - src/tools/json-parser.ts:13-179 (registration)The registerJsonParserTool function that registers the tool with the MCP server using server.tool("json_parser", ...). Also called from src/index.ts at line 54.
export function registerJsonParserTool(server: McpServer): void { server.tool( "json_parser", `Parse, validate, and query JSON data. Modes: - "parse": Parse a JSON string and return it formatted. - "query": Extract a specific field using dot-notation (e.g., "data.users[0].name"). - "validate": Check if a string is valid JSON and describe its structure. - "summarize": Return a schema-like summary of a JSON object's structure. Examples: - Parse: '{"a":1,"b":2}' → pretty-printed object - Query: '{"users":[{"name":"Alice"}]}' with path "users[0].name" → "Alice" - Validate: '{"a":1}' → {"valid": true, "type": "object", "keys": ["a"]}`, { json: z.string().describe("The JSON string to process."), operation: z .enum(["parse", "query", "validate", "summarize"]) .default("parse") .describe("The operation to perform on the JSON data."), path: z .string() .optional() .describe( 'Dot-notation path for query mode (e.g., "users[0].name").' ), }, async ({ json, operation, path: queryPath }) => { try { let parsed: unknown; // Attempt to parse JSON try { parsed = JSON.parse(json); } catch (parseErr: any) { return { content: [ { type: "text" as const, text: JSON.stringify( { valid: false, error: parseErr.message, hint: "Check for trailing commas, unquoted keys, or single quotes.", }, null, 2 ), }, ], }; } switch (operation) { case "parse": { return { content: [ { type: "text" as const, text: JSON.stringify(parsed, null, 2), }, ], }; } case "query": { if (!queryPath) { return { content: [ { type: "text" as const, text: 'Error: "path" parameter is required for query operation.', }, ], isError: true, }; } const result = queryJson(parsed, queryPath); return { content: [ { type: "text" as const, text: JSON.stringify( { path: queryPath, found: true, value: result, type: Array.isArray(result) ? "array" : result === null ? "null" : typeof result, }, null, 2 ), }, ], }; } case "validate": { return { content: [ { type: "text" as const, text: JSON.stringify( { valid: true, type: Array.isArray(parsed) ? "array" : parsed === null ? "null" : typeof parsed, ...(Array.isArray(parsed) ? { length: parsed.length, itemTypes: [...new Set(parsed.map((i) => typeof i))] } : typeof parsed === "object" && parsed !== null ? { keys: Object.keys(parsed as object), keyCount: Object.keys(parsed as object).length } : { value: parsed }), }, null, 2 ), }, ], }; } case "summarize": { const summary = summarizeStructure(parsed); return { content: [ { type: "text" as const, text: JSON.stringify(summary, null, 2), }, ], }; } default: return { content: [ { type: "text" as const, text: `Error: Unknown operation '${operation}'.`, }, ], isError: true, }; } } catch (err: any) { return { content: [ { type: "text" as const, text: `JSON Parser Error: ${err.message}`, }, ], isError: true, }; } } ); } - src/tools/json-parser.ts:185-205 (helper)Helper function queryJson that navigates a JSON object using a dot-notation path, supporting array index notation like "users[0].name".
export function queryJson(data: unknown, path: string): unknown { const parts = path.replace(/\[(\d+)\]/g, ".$1").split("."); let current: unknown = data; for (const part of parts) { if (part === "") continue; if ( current === null || current === undefined || typeof current !== "object" ) { return undefined; } current = (current as Record<string, unknown>)[part]; } return current; } - src/tools/json-parser.ts:210-247 (helper)Helper function summarizeStructure that generates a schema-like summary of a JSON value's structure, with a maximum depth of 5 levels.
export function summarizeStructure(data: unknown, depth: number = 0): unknown { const MAX_DEPTH = 5; if (depth > MAX_DEPTH) return "[max depth reached]"; if (data === null) return { type: "null" }; if (typeof data !== "object") return { type: typeof data }; if (Array.isArray(data)) { if (data.length === 0) return { type: "array", length: 0 }; return { type: "array", length: data.length, itemSchema: summarizeStructure(data[0], depth + 1), ...(data.length > 1 ? { sampleItems: 2, items: [summarizeStructure(data[0], depth + 1)] } : {}), }; } const record = data as Record<string, unknown>; const keys = Object.keys(record); const schema: Record<string, unknown> = { type: "object", keys }; if (keys.length > 0) { schema.properties = {}; for (const key of keys.slice(0, 10)) { (schema.properties as Record<string, unknown>)[key] = summarizeStructure(record[key], depth + 1); } if (keys.length > 10) { (schema.properties as Record<string, unknown>)[ "...andMore" ] = `${keys.length - 10} additional keys`; } } return schema; }