Skip to main content
Glama

JSON MCP Boilerplate

by ricleedo

json_extract

Extract specific data from JSON files using paths, filters, patterns, or slices to retrieve targeted values, filter by conditions, or transform JSON elements for focused analysis.

Instructions

Extract specific data using paths, filters, patterns, or slices from JSON files. Always use this tool when you need to retrieve particular values, filter arrays/objects by conditions, search for patterns, or slice data. Ideal for targeted data extraction, data transformation, and focused analysis of specific JSON elements.

Input Schema

NameRequiredDescriptionDefault
default_valueNoFallback if path not found
endNoArray slice end index
file_pathYesPath to the JSON file
filterNoJS condition to filter results (e.g., 'item.age > 18')
keysNoSpecific object keys to extract
pathNoDot notation path to target
patternNoRegex pattern to search for
search_typeNoWhat to search when using pattern
startNoArray slice start index

Input Schema (JSON Schema)

{ "properties": { "default_value": { "description": "Fallback if path not found" }, "end": { "description": "Array slice end index", "type": "number" }, "file_path": { "description": "Path to the JSON file", "type": "string" }, "filter": { "description": "JS condition to filter results (e.g., 'item.age > 18')", "type": "string" }, "keys": { "description": "Specific object keys to extract", "items": { "type": "string" }, "type": "array" }, "path": { "description": "Dot notation path to target", "type": "string" }, "pattern": { "description": "Regex pattern to search for", "type": "string" }, "search_type": { "description": "What to search when using pattern", "enum": [ "key", "value", "both" ], "type": "string" }, "start": { "description": "Array slice start index", "type": "number" } }, "required": [ "file_path" ], "type": "object" }

Implementation Reference

  • The core handler function for the "json_extract" tool. It processes the input parameters to load a JSON file, navigate to a specific path, apply optional filters (using JS conditions), regex pattern searches (on keys/values), array slicing, specific key extraction, handles default values, truncates large outputs, and returns the result as a formatted JSON string in a text content block.
    file_path, path, filter, pattern, search_type, start, end, keys, default_value, }) => { try { const data = readJSONFile(file_path); let target = path ? getValueByPath(data, path) : data; // If path was specified but not found, return default value if (path && target === undefined) { const output = default_value !== undefined ? default_value : null; return { content: [ { type: "text", text: JSON.stringify( { result: output, message: `Path not found: ${path}, returning default value`, }, null, 2 ), }, ], }; } // Apply filter if specified if (filter) { target = filterObject(target, filter); } // Apply pattern search if specified if (pattern) { const results: any[] = []; const flags = "gi"; // Case-insensitive by default const regex = new RegExp(pattern, flags); const searchFor = search_type || "both"; function searchObject(obj: any, currentPath: string = ""): void { if (Array.isArray(obj)) { obj.forEach((item, index) => { searchObject(item, `${currentPath}[${index}]`); }); } else if (typeof obj === "object" && obj !== null) { Object.entries(obj).forEach(([key, value]) => { const newPath = currentPath ? `${currentPath}.${key}` : key; if ( (searchFor === "key" || searchFor === "both") && regex.test(key) ) { results.push({ type: "key", path: newPath, key, value }); } if (searchFor === "value" || searchFor === "both") { if (value === null && pattern === "null") { results.push({ type: "value", path: newPath, key, value }); } else if (typeof value === "string" && regex.test(value)) { results.push({ type: "value", path: newPath, key, value }); } else if ( typeof value === "number" && regex.test(value.toString()) ) { results.push({ type: "value", path: newPath, key, value }); } else if ( typeof value === "boolean" && regex.test(value.toString()) ) { results.push({ type: "value", path: newPath, key, value }); } } searchObject(value, newPath); }); } } searchObject(target); target = results; } // Apply slicing if specified if ((start !== undefined || end !== undefined) && Array.isArray(target)) { const sliceStart = start || 0; const sliceEnd = end || target.length; target = target.slice(sliceStart, sliceEnd); } // Extract specific keys if specified if ( keys && typeof target === "object" && target !== null && !Array.isArray(target) ) { const extracted: any = {}; keys.forEach((key) => { if (key in target) { extracted[key] = target[key]; } }); target = extracted; } const truncatedTarget = truncateForOutput(target); let outputText = JSON.stringify(truncatedTarget, null, 2); // Replace quoted truncation messages with unquoted text for markdown-like output outputText = outputText.replace( /"\.\.\.(\d+) more items"/g, "...$1 more items" ); outputText = outputText.replace( /"\.\.\.(\d+) more properties": "\.\.\.?"/g, "...$1 more properties" ); return { content: [{ type: "text", text: outputText }], }; } catch (error: any) { return { content: [{ type: "text", text: `Error: ${error.message}` }], }; } }
  • Zod input schema defining all parameters for the json_extract tool, including required file_path and optional path, filter, pattern, search_type, slicing indices, keys to extract, and default_value.
    { file_path: z.string().describe("Path to the JSON file"), path: z.string().optional().describe("Dot notation path to target"), filter: z .string() .optional() .describe("JS condition to filter results (e.g., 'item.age > 18')"), pattern: z.string().optional().describe("Regex pattern to search for"), search_type: z .enum(["key", "value", "both"]) .optional() .describe("What to search when using pattern"), start: z.number().optional().describe("Array slice start index"), end: z.number().optional().describe("Array slice end index"), keys: z .array(z.string()) .optional() .describe("Specific object keys to extract"), default_value: z.any().optional().describe("Fallback if path not found"), }, async ({
  • src/index.ts:298-456 (registration)
    Registration of the json_extract tool on the MCP server using server.tool(), including the tool name, detailed description, input schema, and handler function.
    server.tool( "json_extract", "Extract specific data using paths, filters, patterns, or slices from JSON files. Always use this tool when you need to retrieve particular values, filter arrays/objects by conditions, search for patterns, or slice data. Ideal for targeted data extraction, data transformation, and focused analysis of specific JSON elements.", { file_path: z.string().describe("Path to the JSON file"), path: z.string().optional().describe("Dot notation path to target"), filter: z .string() .optional() .describe("JS condition to filter results (e.g., 'item.age > 18')"), pattern: z.string().optional().describe("Regex pattern to search for"), search_type: z .enum(["key", "value", "both"]) .optional() .describe("What to search when using pattern"), start: z.number().optional().describe("Array slice start index"), end: z.number().optional().describe("Array slice end index"), keys: z .array(z.string()) .optional() .describe("Specific object keys to extract"), default_value: z.any().optional().describe("Fallback if path not found"), }, async ({ file_path, path, filter, pattern, search_type, start, end, keys, default_value, }) => { try { const data = readJSONFile(file_path); let target = path ? getValueByPath(data, path) : data; // If path was specified but not found, return default value if (path && target === undefined) { const output = default_value !== undefined ? default_value : null; return { content: [ { type: "text", text: JSON.stringify( { result: output, message: `Path not found: ${path}, returning default value`, }, null, 2 ), }, ], }; } // Apply filter if specified if (filter) { target = filterObject(target, filter); } // Apply pattern search if specified if (pattern) { const results: any[] = []; const flags = "gi"; // Case-insensitive by default const regex = new RegExp(pattern, flags); const searchFor = search_type || "both"; function searchObject(obj: any, currentPath: string = ""): void { if (Array.isArray(obj)) { obj.forEach((item, index) => { searchObject(item, `${currentPath}[${index}]`); }); } else if (typeof obj === "object" && obj !== null) { Object.entries(obj).forEach(([key, value]) => { const newPath = currentPath ? `${currentPath}.${key}` : key; if ( (searchFor === "key" || searchFor === "both") && regex.test(key) ) { results.push({ type: "key", path: newPath, key, value }); } if (searchFor === "value" || searchFor === "both") { if (value === null && pattern === "null") { results.push({ type: "value", path: newPath, key, value }); } else if (typeof value === "string" && regex.test(value)) { results.push({ type: "value", path: newPath, key, value }); } else if ( typeof value === "number" && regex.test(value.toString()) ) { results.push({ type: "value", path: newPath, key, value }); } else if ( typeof value === "boolean" && regex.test(value.toString()) ) { results.push({ type: "value", path: newPath, key, value }); } } searchObject(value, newPath); }); } } searchObject(target); target = results; } // Apply slicing if specified if ((start !== undefined || end !== undefined) && Array.isArray(target)) { const sliceStart = start || 0; const sliceEnd = end || target.length; target = target.slice(sliceStart, sliceEnd); } // Extract specific keys if specified if ( keys && typeof target === "object" && target !== null && !Array.isArray(target) ) { const extracted: any = {}; keys.forEach((key) => { if (key in target) { extracted[key] = target[key]; } }); target = extracted; } const truncatedTarget = truncateForOutput(target); let outputText = JSON.stringify(truncatedTarget, null, 2); // Replace quoted truncation messages with unquoted text for markdown-like output outputText = outputText.replace( /"\.\.\.(\d+) more items"/g, "...$1 more items" ); outputText = outputText.replace( /"\.\.\.(\d+) more properties": "\.\.\.?"/g, "...$1 more properties" ); return { content: [{ type: "text", text: outputText }], }; } catch (error: any) { return { content: [{ type: "text", text: `Error: ${error.message}` }], }; } } );
  • Helper function filterObject used by json_extract to filter arrays or objects based on a JavaScript condition string (e.g., 'item.age > 18').
    function filterObject(obj: any, condition: string): any { try { // For arrays: item, index are available // For objects: value, key, index are available const conditionFn = new Function( "item", "key", "index", "value", `return ${condition}` ); if (Array.isArray(obj)) { return obj.filter((item, index) => conditionFn(item, undefined, index, item) ); } else if (typeof obj === "object" && obj !== null) { const result: any = {}; Object.entries(obj).forEach(([key, value], index) => { if (conditionFn(value, key, index, value)) { result[key] = value; } }); return result; } return obj; } catch (error: any) { throw new Error(`Invalid filter condition: ${error.message}`); } }
  • Helper function getValueByPath used by json_extract to navigate to a nested value using dot notation path (e.g., 'users.0.name').
    function getValueByPath(obj: any, path: string): any { return path.split(".").reduce((current, key) => { if (current === null || current === undefined) return undefined; if (Array.isArray(current) && !isNaN(Number(key))) { return current[Number(key)]; } return current[key]; }, obj); }

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ricleedo/JSON-MCP-Boilerplate'

If you have feedback or need assistance with the MCP directory API, please join our Discord server