Command Palette

Search for a command to run...

UnylyUnyly
Browse all

Json Reader

FreeNot checked

MCP server for reading, querying, and filtering local JSON files with extended JSONPath syntax, supporting sorting, aggregations, and complex conditions.

GitHubEmbed

About

MCP server for reading, querying, and filtering local JSON files with extended JSONPath syntax, supporting sorting, aggregations, and complex conditions.

README

A bounded-memory Model Context Protocol server for querying large or complex local JSON files.

MCP JSON Reader streams tokens from disk instead of unmarshaling the whole file. It supports exact JSON Pointer paths, a documented forward-streaming JSONPath profile, reusable file handles, and bounded pagination over local stdio.

[!IMPORTANT] Version 2 is a breaking Go rewrite. The former npm package, JSON5 support, query/filter tools, and proprietary query operations are gone.

Features

  • Streams JSON, JSONL, and JSON-seq files of any size with fixed memory caps
  • Exact JSON Pointer and forward-streaming JSONPath queries
  • Reusable process-scoped file handles with cursor pagination
  • os.Root path confinement; no network transport or URL input
  • Structured, machine-readable tool errors

[!NOTE] JSONC and JSON5 support is planned for a future release. Compressed input, SQL, jq, and network URLs are out of scope.

Install

Requires Go 1.26.5 or later.

go install github.com/oovz/mcp-json-reader/v2/cmd/[email protected]

From an untagged checkout:

CGO_ENABLED=0 go build -trimpath -o bin/mcp-json-reader ./cmd/mcp-json-reader

Pick a root directory. Every requested file must stay inside it, including after symlink resolution.

mcp-json-reader --root /workspace/data

MCP_JSON_ROOT works in place of --root. On Windows, use absolute paths for both the executable and the root when the client does not inherit your PATH.

Register the server with an MCP client:

{
  "mcpServers": {
    "json-reader": {
      "command": "mcp-json-reader",
      "args": ["--root", "/workspace/data"]
    }
  }
}
For AI agents

This server lets a coding agent read local JSON, JSONL, and JSON-seq files without loading them into memory. Hand it a root directory and call three tools: json_open, json_read, json_close.

Open a file and get a handle:

{ "path": "orders.jsonl", "format": "auto", "validation": "probe" }

Read by handle…

{ "file_id": "jf_...", "language": "pointer", "query": "/orders/0/id" }

…or open a path implicitly and query in one call:

{ "path": "orders.jsonl", "format": "jsonl", "language": "jsonpath", "query": "$[*].id", "max_items": 100 }

Page through large results by passing the cursor returned in the previous response:

{ "cursor": "jc_..." }

Close the handle when done (close is idempotent):

{ "file_id": "jf_..." }

See the reference below for tool schemas, formats, limits, and error codes.

Tools

json_open

Open and inspect a file without materializing it. Returns a process-scoped handle plus the fixed format, validation coverage, and source metadata.

{ "path": "orders.jsonl", "format": "auto", "validation": "probe" }

validation has two modes: probe examines a bounded prefix (large files return complete: false and can still fail later), full streams and validates the complete file without materializing it. Explicit formats are authoritative—a file opened as json is never silently reinterpreted as JSONL.

json_read

Read from a handle, or open a path implicitly and query in one call. Matches contain an RFC 6901 path and a JSON value:

{
  "file_id": "jf_...",
  "language": "jsonpath",
  "query": "$[*].id",
  "items": [
    {"path": "/0/id", "value": 101},
    {"path": "/1/id", "value": 102}
  ],
  "complete": false,
  "next_cursor": "jc_...",
  "stats": {"returned": 2, "skipped": 0}
}

Continue with the opaque cursor by itself: {"cursor": "jc_..."}. Cursors are single-use, process-scoped, bound to the source fingerprint and original query, and expire after inactivity. Each continuation rescans from the beginning and skips previously returned matches, keeping cursor state small at the cost of repeated I/O.

Pagination is driven by max_items. max_result_bytes is a hard limit on the complete serialized response; it does not split a value or create a page automatically. If the envelope exceeds the limit, lower max_items or raise the server cap.

An implicit read closes its hidden file handle when the result is complete. While paginated, the response includes a file_id only for cleanup via json_close; continue with next_cursor, not by starting another read from that file_id.

Pointers accept plain (/orders/0/id) and URI-fragment (#/orders/0/id) forms. Use ~1 for / and ~0 for ~ inside a member name. See the JSONPath profile for supported selectors, filter semantics, and deliberate limits.

json_close

{ "file_id": "jf_..." }

Returns {"file_id":"jf_...","closed":true}. Repeating it returns the same file_id with closed: false. Cancellation stops waiting for json_close, but a close that has started is not rolled back: the handle remains unavailable and cleanup finishes after any active read releases its lease.

Formats

Value Meaning
auto Detect from a bounded sample and extension. Never guesses JSONC or JSON5.
json Exactly one standard JSON value. Any JSON root type is valid.
jsonl Every physical LF/CRLF-delimited record must contain exactly one standard JSON value. Interior blank lines are invalid; final LF is optional. Records form a virtual array.
json-seq Zero or more values prefixed by ASCII RS 0x1E. Consecutive separators create an invalid empty record. A top-level number must be followed by JSON whitespace. Records form a virtual array; the empty byte stream is valid.

Auto-detection rules: an RS at byte zero identifies json-seq; .jsonl and .ndjson identify jsonl; multiple independently valid line-aligned values identify jsonl; ambiguous one-line values and unknown extensions default to json. Once selected, a handle's format never changes.

Resource limits

Defaults can be changed with CLI flags. Per-read max_items and max_result_bytes may only lower server caps.

Limit Default
Path bytes 32 KiB
Query bytes 16 KiB
Encoded bytes inside one string token 1 MiB
Number bytes 1 KiB
Nesting depth 256
Members per object 100,000
Retained key bytes per object 8 MiB
Retained key bytes across active nested objects 32 MiB
Record bytes 64 MiB
Candidate bytes 8 MiB
Serialized read result 4 MiB
Items per page 1,000
Scan time 30 seconds
Probe prefix 4 MiB / 32 records
Open handles 32
Stored cursors 128
Concurrent scans 4
Handle / cursor idle TTL 15 minutes / 5 minutes

Run mcp-json-reader -help for the corresponding flags.

Errors

Tool failures use isError: true. The same machine-readable object appears in structuredContent and as JSON text for older clients.

{
  "code": "FORMAT_MISMATCH",
  "message": "expected one JSON document, but found another top-level value",
  "expected_format": "json",
  "likely_formats": ["jsonl"],
  "retry": {"format": "jsonl"}
}
Code Meaning
UNSUPPORTED_FORMAT The requested format name is not supported.
FORMAT_MISMATCH The selected framing does not match the observed source.
SYNTAX_ERROR A standard JSON value or frame is malformed.
UNSUPPORTED_SYNTAX A recognized non-standard construct, currently JSON comments, was found.
QUERY_SYNTAX_ERROR A Pointer or JSONPath expression is malformed.
UNSUPPORTED_QUERY_FEATURE A Pointer or JSONPath feature is outside this server's profile.
RESOURCE_LIMIT_EXCEEDED A configured parser, result, time, handle, cursor, or concurrency limit was reached.
SOURCE_CHANGED File identity, size, or modification time changed after open.
HANDLE_EXPIRED A handle or cursor is closed, expired, consumed, or otherwise unavailable.
INVALID_ARGUMENT Tool fields are missing, conflicting, empty, or outside their allowed range.
ACCESS_DENIED The requested path is outside the configured root or escapes through a link.
IO_ERROR The source or configured root could not be read.
CANCELLED The client cancelled the operation.
INTERNAL_ERROR The server could not complete an internal operation.

Development

Prerequisites

  • Go 1.26.5 or later (go version)
  • A C compiler (GCC, Clang, or MSVC) is required only for the race detector (go test -race)

Get the source

git clone https://github.com/oovz/mcp-json-reader.git
cd mcp-json-reader
go mod download

Build

go build -trimpath ./cmd/mcp-json-reader
# or a static binary with no CGO runtime requirement:
CGO_ENABLED=0 go build -trimpath -o bin/mcp-json-reader ./cmd/mcp-json-reader

Run locally

./bin/mcp-json-reader --root ./tests

The server speaks MCP over stdio. Point any MCP client at the built binary with --root set to a directory of JSON files. The tests/ folder ships fixtures (mock.json, mock-large.json, mock-edge-cases.json) you can query immediately.

Test

# formatting and vet
gofmt -l cmd internal
go vet ./...

# full unit and integration suite
go test ./...
# run cases in a random order to catch order-dependent state
go test -shuffle=on ./...
# race detector (requires CGO and a C compiler)
go test -race ./...

Fuzz

Seeded fuzz targets cover Pointer and JSONPath compilation, strict document validation, and both record framers. The normal test suite runs their seed corpus; you can also run each target for a bounded interval:

go test ./internal/query -run=^$ -fuzz=FuzzCompileQueries -fuzztime=10s
go test ./internal/stream -run=^$ -fuzz=FuzzValidateDocument -fuzztime=10s
go test ./internal/stream -run=^$ -fuzz=FuzzRecordFramers -fuzztime=10s

What CI runs

CI runs on Ubuntu, Windows, and macOS with Go 1.26.x. The checks are go mod verify, go mod tidy -diff, gofmt -l, go vet, go test ./... -count=1, go build -trimpath ./cmd/mcp-json-reader, plus a separate race-detector job (go test -race ./... -count=1). Run the same commands locally before pushing.

Standards

  • MCP transport and tools: MCP 2025-11-25; the pinned Go SDK also negotiates 2025-06-18, 2025-03-26, and 2024-11-05
  • Standard JSON: RFC 8259, with invalid UTF-8 and duplicate names rejected
  • JSON Pointer: RFC 6901
  • JSONPath: RFC 9535, documented streaming profile
  • JSON text sequences: RFC 7464

from github.com/oovz/mcp-json-reader

Installing Json Reader

This server has no published package — it is built from source. Open the repository and follow its README.

▸ github.com/oovz/mcp-json-reader

FAQ

Is Json Reader MCP free?

Yes, Json Reader MCP is free — one-click install via Unyly at no cost.

Does Json Reader need an API key?

No, Json Reader runs without API keys or environment variables.

Is Json Reader hosted or self-hosted?

Self-hosted: the server runs locally on your machine via the install command above.

How do I install Json Reader in Claude Desktop, Claude Code or Cursor?

Open Json Reader on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

Related MCPs

Compare Json Reader with

Not sure what to pick?

Find your stack in 60 seconds

Author?

Embed badge for your README

Browse similar

All development MCPs