DEV Community

Cover image for Inspecting Apache Parquet Footers & Debugging MCP (mcp.json) Configs Entirely In-Browser
Jason Y. (dev_in_the_fog)
Jason Y. (dev_in_the_fog)

Posted on Edited on

Inspecting Apache Parquet Footers & Debugging MCP (mcp.json) Configs Entirely In-Browser

Modern AI and data engineering workflows constantly force us to inspect two things that should never be uploaded to random third-party web servers:

  1. Production .parquet / .sqlite snapshots containing customer records, feature-store vectors, or billing rows when you just want to check column types, null counts, or 20 sample rows.
  2. Model Context Protocol (mcp.json) configs and JSON-RPC 2.0 payloads containing live ANTHROPIC_API_KEY, GITHUB_PERSONAL_ACCESS_TOKEN, database DSNs, and tool schemas for Claude Desktop, Cursor, or custom MCP servers.

Here is how both formats work under the hood—and how you can inspect, validate, and sanitize them 100% locally inside browser RAM with zero backend requests.


Part 1: How Browser-Native Apache Parquet Inspection Works

Unlike CSV or NDJSON—where reading the schema or row count requires scanning from byte 0—Apache Parquet puts its entire table catalog at the end of the file:

+---------------------------------------------------+
| Magic Bytes: "PAR1" (4 bytes)                     |
+---------------------------------------------------+
| Row Group 0 (Column Chunks: ZSTD / SNAPPY pages)  |
| Row Group 1 ...                                   |
+---------------------------------------------------+
| FileMetaData (Compact Thrift-encoded binary)      |
|   - SchemaElement[] (column names, logical types) |
|   - RowGroup[] (byte offsets, num_rows, min/max)  |
+---------------------------------------------------+
| Footer Length (uint32 little-endian, 4 bytes)     |
| Magic Bytes: "PAR1" (4 bytes)                     |
+---------------------------------------------------+
Enter fullscreen mode Exit fullscreen mode

Because browsers support zero-copy Blob.slice(size - 8, size), a client-side viewer can:

  1. Read the final 8 bytes to verify "PAR1" and grab the Footer Length.
  2. Slice just [size - 8 - footerLen, size - 8] and decode the Thrift FileMetaData in milliseconds—even on large files.
  3. Decompress only the first Row Group's pages in WebAssembly/JS RAM to render interactive table rows, column statistics, and instant SQL/filter previews—without sending a single packet over the network.

Try dropping any .parquet or .sqlite file into the In-Memory Apache Parquet & SQLite Viewer with Chrome DevTools → Network open: outbound upload traffic stays strictly 0 B.


Part 2: Catching Silent mcp.json Bugs & Redacting Secrets Before Sharing

If you build or wire up Model Context Protocol (MCP) servers across Claude Desktop (claude_desktop_config.json), Cursor (.cursor/mcp.json), or Windsurf, three tiny configuration mistakes account for 90% of "Server disconnected" startup failures:

1. Windows npx Spawning Without cmd /c

On macOS/Linux, "command": "npx" resolves cleanly via POSIX execvp. On Windows, npx is npx.cmd—spawning it directly in several MCP hosts throws ENOENT unless wrapped as:

{
  "mcpServers": {
    "postgres-local": {
      "command": "cmd",
      "args": ["/c", "npx", "-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost:5432/app"],
      "env": {
        "PGPASSWORD": "REDACTED_SECRET"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Stdout Pollution Breaking JSON-RPC 2.0 Framing

Stdio MCP transport expects strictly newline-delimited JSON-RPC 2.0 messages on stdout. A single stray console.log("Connected to DB") or dotenv banner printed to stdout instead of stderr (console.error) corrupts the JSON-RPC stream immediately.

3. Leaking env Tokens in GitHub Issues & Slack

Developers routinely paste their mcpServers block into GitHub issues when debugging tool-call schemas (tools/list, tools/call), accidentally exposing live tokens inside "env" or DSN connection strings inside "args".

To make MCP setup and sharing painless, I built the MCP Config Builder, Secret Masker & JSON-RPC Inspector:

  • Generates cross-platform (macOS/Linux vs Windows cmd /c) mcp.json templates
  • Automatically masks sensitive env keys and connection-string credentials into safe <REDACTED> placeholders before you copy-paste into issues or docs
  • Validates raw MCP JSON-RPC 2.0 request/response envelopes (initialize, tools/list, tools/call) client-side

Part of a Zero-Upload Developer Suite

Both utilities live inside NerdKit (global-utils.com) alongside 60+ client-side engineering tools—including an LLM GPU VRAM & MLA/GQA Calculator (open-source CLI on GitHub) and a Client-Side HAR Waterfall & Secret Redactor.

Feedback and feature requests for new MCP or data-engineering inspectors are super welcome!

Top comments (2)

Collapse
 
crtdrops profile image
Israel Negrete Lepe •

Good to see you again, @dev_in_the_fog. Of the three, stdout pollution is the one I'd underline: it's a framing bug dressed up as a config problem. Stdio MCP delimits messages by newline (the spec also says a message must not contain embedded newlines), so the receiver trusts that every line is exactly one message. One stray console.log breaks that trust. Same family as the TCP bug I wrote about in "A read is not a frame", where my own test client counted one acknowledgment per read and lost the second one whenever two arrived in the same segment.

That makes me curious about how your JSON-RPC inspector reports it. When one line in a captured stream fails to parse, does it point at that line and keep validating from the next newline, or reject the whole stream? Knowing that line 3 broke and lines 4 onward were fine is what tells you it was a stray log, not a broken server.

Collapse
 
x1y1co profile image
X1Y1 •

Small thing in the Windows example: @modelcontextprotocol/server-postgres is one of the archived reference servers, and npm now marks it deprecated with "no security guarantees". Worth swapping it for a maintained Postgres server in the snippet, since people copy these straight into their configs and the old name keeps spreading that way.

⌂ 换网址