Skip to main content
Glama

json_filter

Extract specific fields from JSON data using a shape object. Input a file path (local or URL) and define the shape to filter and retrieve only desired fields, supporting nested and array-based extraction.

Instructions

Filter JSON data using a shape object to extract only the fields you want. Provide filePath (local file or HTTP/HTTPS URL) and shape parameters.

Input Schema

NameRequiredDescriptionDefault
chunkIndexNoIndex of chunk to retrieve (0-based). If filtered data exceeds 400KB, it will be automatically chunked. Defaults to 0 if not specified.
filePathYesPath to the JSON file (local) or HTTP/HTTPS URL to filter
shapeNoShape object (formatted as valid JSON) defining what fields to extract. Use 'true' to include a field, or nested objects for deep extraction. Examples: 1. Extract single field: {"type": true} 2. Extract multiple fields: {"type": true, "version": true, "source": true} 3. Extract nested fields: {"appState": {"gridSize": true, "viewBackgroundColor": true}} 4. Extract from arrays: {"elements": {"type": true, "x": true, "y": true}} - applies to each array item 5. Complex nested extraction: { "type": true, "version": true, "appState": { "gridSize": true, "viewBackgroundColor": true }, "elements": { "type": true, "text": true, "x": true, "y": true, "boundElements": { "type": true, "id": true } } } Note: - Arrays are automatically handled - the shape is applied to each item in the array. - Use json_schema tool to analyse the JSON file schema before using this tool. - Use json_dry_run tool to get a size breakdown of your desired json shape before using this tool.

Input Schema (JSON Schema)

{ "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": false, "properties": { "chunkIndex": { "description": "Index of chunk to retrieve (0-based). If filtered data exceeds 400KB, it will be automatically chunked. Defaults to 0 if not specified.", "type": "number" }, "filePath": { "description": "Path to the JSON file (local) or HTTP/HTTPS URL to filter", "type": "string" }, "shape": { "description": "Shape object (formatted as valid JSON) defining what fields to extract. Use 'true' to include a field, or nested objects for deep extraction.\n\nExamples:\n1. Extract single field: {\"type\": true}\n2. Extract multiple fields: {\"type\": true, \"version\": true, \"source\": true}\n3. Extract nested fields: {\"appState\": {\"gridSize\": true, \"viewBackgroundColor\": true}}\n4. Extract from arrays: {\"elements\": {\"type\": true, \"x\": true, \"y\": true}} - applies to each array item\n5. Complex nested extraction: {\n \"type\": true,\n \"version\": true,\n \"appState\": {\n \"gridSize\": true,\n \"viewBackgroundColor\": true\n },\n \"elements\": {\n \"type\": true,\n \"text\": true,\n \"x\": true,\n \"y\": true,\n \"boundElements\": {\n \"type\": true,\n \"id\": true\n }\n }\n}\n\nNote: \n- Arrays are automatically handled - the shape is applied to each item in the array.\n- Use json_schema tool to analyse the JSON file schema before using this tool.\n- Use json_dry_run tool to get a size breakdown of your desired json shape before using this tool.\n" } }, "required": [ "filePath" ], "type": "object" }

Implementation Reference

  • Core handler function implementing the json_filter tool logic: ingests JSON from file/URL using strategy pattern, parses JSON, recursively extracts fields using shape definition (handles nested objects and arrays), checks size and chunks if >400KB using line-based splitting, returns filtered data or chunk with metadata or error.
    async function processJsonFilter(input: JsonFilterInput): Promise<JsonFilterResult> { try { // Use strategy pattern to ingest JSON content const ingestionResult = await jsonIngestionContext.ingest(input.filePath); if (!ingestionResult.success) { // Map strategy errors to existing error format for backward compatibility return { success: false, error: ingestionResult.error }; } // Parse JSON let parsedData: any; try { parsedData = JSON.parse(ingestionResult.content); } catch (error) { return { success: false, error: { type: 'invalid_json', message: 'Invalid JSON format in content', details: error } }; } // Apply shape filter try { const filteredData = extractWithShape(parsedData, input.shape); // Convert filtered data to JSON string to check size const filteredJson = JSON.stringify(filteredData, null, 2); const filteredSize = new TextEncoder().encode(filteredJson).length; // Define chunking threshold (400KB) const CHUNK_THRESHOLD = 400 * 1024; // If under threshold, return all data if (filteredSize <= CHUNK_THRESHOLD) { return { success: true, filteredData }; } // Calculate total chunks needed const totalChunks = Math.ceil(filteredSize / CHUNK_THRESHOLD); const chunkIndex = input.chunkIndex ?? 0; // Default to 0 // Validate chunk index if (chunkIndex >= totalChunks || chunkIndex < 0) { return { success: false, error: { type: 'validation_error', message: `Invalid chunkIndex ${chunkIndex}. Must be between 0 and ${totalChunks - 1}`, details: { chunkIndex, totalChunks } } }; } // Line-based chunking const lines = filteredJson.split('\n'); const linesPerChunk = Math.ceil(lines.length / totalChunks); const startLine = chunkIndex * linesPerChunk; const endLine = Math.min(startLine + linesPerChunk, lines.length); // Extract chunk as text const chunkText = lines.slice(startLine, endLine).join('\n'); return { success: true, filteredData: chunkText, // Return as string when chunking chunkInfo: { chunkIndex, totalChunks } }; } catch (error) { return { success: false, error: { type: 'validation_error', message: 'Failed to apply shape filter', details: error } }; } } catch (error) { return { success: false, error: { type: 'validation_error', message: 'Unexpected error during processing', details: error } }; } }
  • src/index.ts:563-681 (registration)
    MCP server.tool registration for 'json_filter': defines tool name, description, input Zod schema (filePath, shape as unknown/JSON, optional chunkIndex), and handler that parses shape if string, validates input, calls processJsonFilter, formats response as text content (JSON or chunk string + metadata), handles errors.
    server.tool( "json_filter", "Filter JSON data using a shape object to extract only the fields you want. Provide filePath (local file or HTTP/HTTPS URL) and shape parameters.", { filePath: z.string().describe("Path to the JSON file (local) or HTTP/HTTPS URL to filter"), shape: z.unknown().describe(`Shape object (formatted as valid JSON) defining what fields to extract. Use 'true' to include a field, or nested objects for deep extraction. Examples: 1. Extract single field: {"type": true} 2. Extract multiple fields: {"type": true, "version": true, "source": true} 3. Extract nested fields: {"appState": {"gridSize": true, "viewBackgroundColor": true}} 4. Extract from arrays: {"elements": {"type": true, "x": true, "y": true}} - applies to each array item 5. Complex nested extraction: { "type": true, "version": true, "appState": { "gridSize": true, "viewBackgroundColor": true }, "elements": { "type": true, "text": true, "x": true, "y": true, "boundElements": { "type": true, "id": true } } } Note: - Arrays are automatically handled - the shape is applied to each item in the array. - Use json_schema tool to analyse the JSON file schema before using this tool. - Use json_dry_run tool to get a size breakdown of your desired json shape before using this tool. `), chunkIndex: z.number().optional().describe("Index of chunk to retrieve (0-based). If filtered data exceeds 400KB, it will be automatically chunked. Defaults to 0 if not specified.") }, async ({ filePath, shape, chunkIndex }) => { try { // If shape is a string, parse it as JSON let parsedShape = shape; if (typeof shape === 'string') { try { parsedShape = JSON.parse(shape); } catch (e) { return { content: [ { type: "text", text: `Error: Invalid JSON in shape parameter: ${e instanceof Error ? e.message : String(e)}` } ], isError: true }; } } const validatedInput = JsonFilterInputSchema.parse({ filePath, shape: parsedShape, chunkIndex }); const result = await processJsonFilter(validatedInput); if (result.success) { // Check if chunking is active if (result.chunkInfo) { // Return chunk data + metadata as separate content items return { content: [ { type: "text", text: result.filteredData // This is already a string when chunking }, { type: "text", text: JSON.stringify(result.chunkInfo) } ] }; } else { // No chunking - return as normal JSON return { content: [ { type: "text", text: JSON.stringify(result.filteredData, null, 2) } ] }; } } else { return { content: [ { type: "text", text: `Error: ${result.error.message}` } ], isError: true }; } } catch (error) { return { content: [ { type: "text", text: `Validation error: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } );
  • Zod input schema for json_filter tool validating filePath (local/URL), shape object, optional chunkIndex.
    const JsonFilterInputSchema = z.object({ filePath: z.string().min(1, "File path or HTTP/HTTPS URL is required").refine( (val) => val.length > 0 && (val.startsWith('./') || val.startsWith('/') || val.startsWith('http://') || val.startsWith('https://') || !val.includes('/')), "Must be a valid file path or HTTP/HTTPS URL" ), shape: z.any().describe("Shape object defining what to extract"), chunkIndex: z.number().int().min(0).optional().describe("Index of chunk to retrieve (0-based)") });
  • TypeScript result type for json_filter: success with filteredData (object or chunk string) and optional chunkInfo, or failure with error.
    type JsonFilterResult = { readonly success: true; readonly filteredData: any; readonly chunkInfo?: { readonly chunkIndex: number; readonly totalChunks: number; }; } | { readonly success: false; readonly error: JsonSchemaError; };
  • Key helper function for recursive shape-based extraction: applies shape to objects (include if true or recurse), handles arrays by mapping over elements.
    /** * Extract data from object based on shape definition */ function extractWithShape(data: any, shape: Shape): any { if (Array.isArray(data)) { return data.map(item => extractWithShape(item, shape)); } const result: any = {}; for (const key in shape) { const rule = shape[key]; if (rule === true) { result[key] = data[key]; } else if (typeof rule === 'object' && data[key] !== undefined) { result[key] = extractWithShape(data[key], rule); } } return result; }

Other Tools

Related 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/kehvinbehvin/json-mcp'

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