| export {}; |
| import { describe, it } from "node:test"; | ||
| import assert from "node:assert/strict"; | ||
| import { SchemaGenerator } from "./generator.js"; | ||
| import { DcpSchema } from "./schema.js"; | ||
| import { DcpEncoder } from "./encoder.js"; | ||
| import { FieldMapping } from "./mapping.js"; | ||
| const userSamples = [ | ||
| { | ||
| id: "u001", | ||
| name: "Alice Johnson", | ||
| email: "alice@example.com", | ||
| role: "admin", | ||
| score: 95, | ||
| active: true, | ||
| profile: { | ||
| bio: "Platform engineer, 10 years experience", | ||
| avatar_url: "https://cdn.example.com/avatars/alice.png", | ||
| preferences: { | ||
| theme: "dark", | ||
| locale: "en-US", | ||
| notifications: { email: true, push: false, sms: false }, | ||
| }, | ||
| }, | ||
| teams: [ | ||
| { id: "t01", name: "Infrastructure", role: "lead" }, | ||
| { id: "t02", name: "Security", role: "member" }, | ||
| ], | ||
| recent_activity: [ | ||
| { | ||
| action: "deploy", | ||
| target: "api-v2", | ||
| timestamp: "2026-03-28T14:30:00Z", | ||
| metadata: { env: "production", version: "2.1.0" }, | ||
| }, | ||
| { | ||
| action: "review", | ||
| target: "PR#412", | ||
| timestamp: "2026-03-27T09:15:00Z", | ||
| metadata: { verdict: "approved" }, | ||
| }, | ||
| ], | ||
| }, | ||
| { | ||
| id: "u002", | ||
| name: "Bob Smith", | ||
| email: "bob@example.com", | ||
| role: "user", | ||
| score: 72, | ||
| active: true, | ||
| profile: { | ||
| bio: "Junior dev, learning the ropes", | ||
| avatar_url: "https://cdn.example.com/avatars/bob.png", | ||
| preferences: { | ||
| theme: "light", | ||
| locale: "ja-JP", | ||
| notifications: { email: true, push: true, sms: false }, | ||
| }, | ||
| }, | ||
| teams: [{ id: "t03", name: "Frontend", role: "member" }], | ||
| recent_activity: [ | ||
| { | ||
| action: "commit", | ||
| target: "feature/navbar", | ||
| timestamp: "2026-03-28T16:00:00Z", | ||
| metadata: { files_changed: 3 }, | ||
| }, | ||
| ], | ||
| }, | ||
| { | ||
| id: "u003", | ||
| name: "Charlie Brown", | ||
| email: "charlie@example.com", | ||
| role: "user", | ||
| score: 88, | ||
| active: false, | ||
| profile: { | ||
| bio: "On sabbatical", | ||
| avatar_url: null, | ||
| preferences: { | ||
| theme: "dark", | ||
| locale: "en-GB", | ||
| notifications: { email: false, push: false, sms: false }, | ||
| }, | ||
| }, | ||
| teams: [], | ||
| recent_activity: [], | ||
| }, | ||
| ]; | ||
| describe("Nested DCP Encoding", () => { | ||
| it("generates nestSchemas on DcpSchemaDef", () => { | ||
| const gen = new SchemaGenerator(); | ||
| const draft = gen.fromSamples(userSamples, { domain: "search_users" }); | ||
| assert.ok(draft.schema.nestSchemas, "schema should have nestSchemas"); | ||
| assert.ok(draft.schema.nestSchemas["teams"], "teams nestSchema should exist"); | ||
| assert.ok(draft.schema.nestSchemas["recent_activity"], "recent_activity nestSchema should exist"); | ||
| const teamsSub = draft.schema.nestSchemas["teams"]; | ||
| assert.equal(teamsSub.schema.id, "search_users.teams:v1"); | ||
| assert.ok(teamsSub.schema.fields.length > 0); | ||
| assert.ok(teamsSub.mapping.paths); | ||
| }); | ||
| it("encodes array-of-objects with $R references (no preamble)", () => { | ||
| const gen = new SchemaGenerator(); | ||
| const draft = gen.fromSamples(userSamples, { domain: "search_users" }); | ||
| const schema = new DcpSchema(draft.schema); | ||
| const mapping = new FieldMapping(draft.mapping); | ||
| const encoder = new DcpEncoder(schema, mapping); | ||
| const batch = encoder.encode(userSamples); | ||
| const output = DcpEncoder.toString(batch); | ||
| const lines = output.split("\n"); | ||
| // First line is the main header (no preamble) | ||
| const mainHeader = JSON.parse(lines[0]); | ||
| assert.equal(mainHeader[0], "$S"); | ||
| assert.equal(mainHeader[1], "search_users:v1"); | ||
| // Alice's row | ||
| const aliceRow = JSON.parse(lines[1]); | ||
| const teamsIdx = mainHeader.indexOf("teams") - 2; | ||
| const teamsVal = aliceRow[teamsIdx]; | ||
| // teams: ["$R", "search_users.teams:v1", [row1], [row2]] | ||
| assert.ok(Array.isArray(teamsVal), "teams should be array"); | ||
| assert.equal(teamsVal[0], "$R", "nested field starts with $R"); | ||
| assert.ok(teamsVal[1].startsWith("search_users.teams:"), "$R references sub-schema ID"); | ||
| assert.equal(teamsVal.length, 4, "$R + schemaId + 2 team rows"); | ||
| assert.ok(Array.isArray(teamsVal[2]), "team row 1 is an array"); | ||
| }); | ||
| it("handles empty arrays as $R with no rows", () => { | ||
| const gen = new SchemaGenerator(); | ||
| const draft = gen.fromSamples(userSamples, { domain: "search_users" }); | ||
| const schema = new DcpSchema(draft.schema); | ||
| const mapping = new FieldMapping(draft.mapping); | ||
| const encoder = new DcpEncoder(schema, mapping); | ||
| const batch = encoder.encode(userSamples); | ||
| const lines = DcpEncoder.toString(batch).split("\n"); | ||
| const mainHeader = JSON.parse(lines[0]); | ||
| // Charlie's row (3rd data row) | ||
| const charlieRow = JSON.parse(lines[3]); | ||
| const teamsIdx = mainHeader.indexOf("teams") - 2; | ||
| // Empty → ["$R", "search_users.teams:v1"] | ||
| const teamsVal = charlieRow[teamsIdx]; | ||
| assert.ok(Array.isArray(teamsVal), "empty teams should be array"); | ||
| assert.equal(teamsVal[0], "$R", "starts with $R"); | ||
| assert.equal(teamsVal.length, 2, "$R + schemaId only, no rows"); | ||
| }); | ||
| it("nestSchemas persist in schema JSON (serializable)", () => { | ||
| const gen = new SchemaGenerator(); | ||
| const draft = gen.fromSamples(userSamples, { domain: "search_users" }); | ||
| // Round-trip: serialize → parse → DcpSchema | ||
| const json = JSON.stringify(draft.schema); | ||
| const parsed = JSON.parse(json); | ||
| const restored = new DcpSchema(parsed); | ||
| assert.ok(restored.def.nestSchemas, "nestSchemas survives round-trip"); | ||
| assert.ok(restored.def.nestSchemas["teams"]); | ||
| // Encode with restored schema | ||
| const mapping = new FieldMapping(draft.mapping); | ||
| const encoder = new DcpEncoder(restored, mapping); | ||
| const batch = encoder.encode(userSamples); | ||
| const lines = DcpEncoder.toString(batch).split("\n"); | ||
| const row = JSON.parse(lines[1]); | ||
| const header = JSON.parse(lines[0]); | ||
| const teamsIdx = header.indexOf("teams") - 2; | ||
| assert.equal(row[teamsIdx][0], "$R", "$R works after schema round-trip"); | ||
| }); | ||
| it("produces smaller output than JSON", () => { | ||
| const gen = new SchemaGenerator(); | ||
| const draft = gen.fromSamples(userSamples, { domain: "search_users" }); | ||
| const schema = new DcpSchema(draft.schema); | ||
| const mapping = new FieldMapping(draft.mapping); | ||
| const encoder = new DcpEncoder(schema, mapping); | ||
| const batch = encoder.encode(userSamples); | ||
| const dcpOutput = DcpEncoder.toString(batch); | ||
| const jsonOutput = JSON.stringify(userSamples); | ||
| const reduction = (1 - dcpOutput.length / jsonOutput.length) * 100; | ||
| console.log(`JSON: ${jsonOutput.length} chars, DCP: ${dcpOutput.length} chars, reduction: ${reduction.toFixed(1)}%`); | ||
| assert.ok(reduction > 10, `expected >10% reduction, got ${reduction.toFixed(1)}%`); | ||
| }); | ||
| it("scales: 30+ records exceed 30% reduction", () => { | ||
| const gen = new SchemaGenerator(); | ||
| const draft = gen.fromSamples(userSamples, { domain: "search_users" }); | ||
| const schema = new DcpSchema(draft.schema); | ||
| const mapping = new FieldMapping(draft.mapping); | ||
| const encoder = new DcpEncoder(schema, mapping); | ||
| const scaled = []; | ||
| for (let i = 0; i < 30; i++) { | ||
| const s = JSON.parse(JSON.stringify(userSamples[i % 3])); | ||
| s.id = `u${String(i).padStart(3, "0")}`; | ||
| scaled.push(s); | ||
| } | ||
| const batch = encoder.encode(scaled); | ||
| const dcpOutput = DcpEncoder.toString(batch); | ||
| const jsonOutput = JSON.stringify(scaled); | ||
| const reduction = (1 - dcpOutput.length / jsonOutput.length) * 100; | ||
| assert.ok(reduction > 30, `30 records: expected >30% reduction, got ${reduction.toFixed(1)}%`); | ||
| }); | ||
| }); | ||
| //# sourceMappingURL=encoder.test.js.map |
| {"version":3,"file":"encoder.test.js","sourceRoot":"","sources":["../src/encoder.test.ts"],"names":[],"mappings":"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"} |
| # DCP Gateway — MCP Transparent Compression Proxy | ||
| A generic proxy that sits between any MCP client and any MCP server, automatically compressing tool responses into DCP positional arrays. No server modification required. No client configuration beyond pointing at the gateway. | ||
| ``` | ||
| MCP Client (Claude Code, Cursor, custom agent) | ||
| │ | ||
| ▼ | ||
| ┌──────────────────────────┐ | ||
| │ DCP Gateway │ | ||
| │ │ | ||
| │ tools/list → compress tool definitions | ||
| │ tools/call → intercept JSON response → DCP encode | ||
| │ schema cache + TTL │ | ||
| │ preset loader │ | ||
| └──────────────────────────┘ | ||
| │ | ||
| ▼ | ||
| MCP Server (any — engram, GitHub, DB, Slack, ...) | ||
| ``` | ||
| ## Problem | ||
| MCP servers return JSON. Every record repeats the same keys: | ||
| ```json | ||
| [ | ||
| {"id":"abc","score":0.95,"title":"Port conflict fix","tags":["docker"]}, | ||
| {"id":"def","score":0.82,"title":"Config path gotcha","tags":["config"]}, | ||
| {"id":"ghi","score":0.71,"title":"Build cache issue","tags":["ci"]} | ||
| ] | ||
| ``` | ||
| The LLM pays for every repeated `"id"`, `"score"`, `"title"`, `"tags"`. For 10 records, that's 10x key overhead. The LLM extracts the same information from a positional array at a fraction of the token cost. | ||
| The gateway eliminates this overhead transparently — the server doesn't know, the client doesn't care. | ||
| ## How it works | ||
| ### Phase 1: Schema learning (first call) | ||
| ``` | ||
| Client → tools/call("search", {query: "docker"}) → Gateway → Server | ||
| Server → JSON response → Gateway | ||
| Gateway: | ||
| 1. Pass JSON response to Client unchanged | ||
| 2. Feed JSON to SchemaGenerator (no LLM, pure structure analysis) | ||
| 3. Cache: tool="search" → schema {id, fields, mapping} | ||
| ``` | ||
| The first call is a pass-through. The gateway observes the response structure and prepares an encoder for next time. | ||
| ### Phase 2: DCP encoding (subsequent calls) | ||
| ``` | ||
| Client → tools/call("search", {query: "port"}) → Gateway → Server | ||
| Server → JSON response → Gateway | ||
| Gateway: | ||
| 1. Encode JSON → DCP using cached schema | ||
| 2. Return DCP to Client | ||
| ["$S","search-result:v1",4,"id","score","title","tags"] | ||
| ["abc",0.95,"Port conflict fix","docker"] | ||
| ["def",0.82,"Config path gotcha","config"] | ||
| ``` | ||
| 40-70% token reduction. Every call after the first. | ||
| ### Phase 3: Tool definition compression | ||
| ``` | ||
| Client → tools/list → Gateway → Server | ||
| Server → tool definitions (name, description, parameters) → Gateway | ||
| Gateway: | ||
| 1. Strip JSON Schema meta-fields ($schema, additionalProperties) | ||
| 2. Shorten verbose descriptions | ||
| 3. Drop parameter descriptions that restate the key name | ||
| 4. Return compressed definitions to Client | ||
| ``` | ||
| ~19% reduction on tool definitions. This runs on every LLM turn — tool definitions ship with every request. | ||
| ## Schema cache | ||
| Each tool's inferred schema is cached with a TTL: | ||
| ``` | ||
| schema_cache { | ||
| tool_name: string // "mcp_engram_engram_pull" | ||
| schema: DcpSchema // {id, fields, mapping} | ||
| last_used: timestamp // updated on every hit | ||
| hit_count: number // lifetime usage | ||
| ttl: duration // default: 30 days | ||
| } | ||
| ``` | ||
| - **Used tools**: `last_used` refreshes on every call → TTL resets → schema lives indefinitely | ||
| - **Unused tools**: TTL expires → schema evicted → next call triggers re-inference | ||
| - **Schema drift**: if JSON structure changes (new fields, type mismatch), gateway detects and re-infers | ||
| No manual cleanup. No unbounded growth. The cache self-regulates. | ||
| ## Presets — first-call DCP | ||
| The schema learning phase means the first call returns uncompressed JSON. For known MCP servers, presets eliminate this warm-up: | ||
| ``` | ||
| presets/ | ||
| github.json # GitHub MCP server schemas | ||
| engram.json # engram MCP server schemas | ||
| filesystem.json # filesystem MCP server schemas | ||
| custom/ | ||
| my-api.json # user-defined presets | ||
| ``` | ||
| Preset format: | ||
| ```json | ||
| { | ||
| "server": "github", | ||
| "tools": { | ||
| "search_repositories": { | ||
| "id": "gh-repo-search:v1", | ||
| "fields": ["full_name", "description", "stars", "language", "updated_at"] | ||
| }, | ||
| "list_issues": { | ||
| "id": "gh-issues:v1", | ||
| "fields": ["number", "title", "state", "labels", "author", "created_at"] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
| With a preset loaded, the gateway DCP-encodes from the very first call. Presets are external files — add, remove, or update without rebuilding. | ||
| Presets can be contributed by the community. If you use an MCP server regularly, export its schema and share it. | ||
| ## What gets compressed, what doesn't | ||
| | Response type | Gateway action | Why | | ||
| |---|---|---| | ||
| | JSON array of objects | DCP encode | Repeated keys eliminated — maximum savings | | ||
| | Nested objects (e.g. `profile.preferences.theme`) | Flatten to top-level columns | Dot-path resolved at encoding time | | ||
| | Array-of-objects fields (e.g. `teams`, `recent_activity`) | Nested `$S` encode | Sub-schema generated per field; items become positional rows | | ||
| | Single JSON object | DCP encode if >5 fields | Smaller objects have negligible overhead | | ||
| | Plain text | Pass through | Not structured — nothing to compress | | ||
| | Error response | Pass through | Errors must be readable as-is | | ||
| | Binary / base64 | Pass through | Not text — DCP doesn't apply | | ||
| The gateway never breaks a response. If encoding fails or the response isn't JSON, it passes through unchanged. | ||
| ### Nested DCP encoding | ||
| The encoder converts array-of-objects fields using `$R` references. Sub-schemas are stored in the schema cache as `nestSchemas`, not repeated in every output: | ||
| ``` | ||
| ["$S","search_users:v1","id","name","role","teams","recent_activity"] | ||
| ["u001","Alice","admin", | ||
| ["$R","search_users.teams:v1", | ||
| ["t01","Infrastructure","lead"], | ||
| ["t02","Security","member"]], | ||
| ["$R","search_users.recent_activity:v1", | ||
| ["deploy",{"env":"production","version":"2.1.0"},"api-v2","2026-03-28T14:30:00Z"]]] | ||
| ["u003","Charlie","user", | ||
| ["$R","search_users.teams:v1"], | ||
| ["$R","search_users.recent_activity:v1"]] | ||
| ``` | ||
| The schema cache entry for `search_users` contains the full `nestSchemas`: | ||
| ```json | ||
| { | ||
| "$dcp": "schema", | ||
| "id": "search_users:v1", | ||
| "nestSchemas": { | ||
| "teams": { "schema": { "id": "search_users.teams:v1", "fields": ["id","name","role"], ... }, "mapping": ... }, | ||
| "recent_activity": { "schema": { "id": "search_users.recent_activity:v1", "fields": ["action","metadata","target","timestamp"], ... }, "mapping": ... } | ||
| } | ||
| } | ||
| ``` | ||
| This fits the gateway's existing flow naturally: | ||
| 1. **Phase 1** (first call): `SchemaGenerator.fromSamples()` infers root schema + `nestSchemas` → cached together | ||
| 2. **Phase 2** (subsequent): `DcpEncoder` reads `nestSchemas` from the cached schema → emits `$R` references | ||
| Key design decisions: | ||
| - **Sub-schema depth is capped at 0** (top-level fields only within nested objects). Heterogeneous nested objects (e.g. variable `metadata` keys) stay as opaque JSON to avoid sparse column explosion. | ||
| - **Empty arrays** → `["$R", "schema-id"]` with no rows. Type information preserved via schema ID. | ||
| - **Static vs dynamic**: The gateway uses static `nestSchemas` (stored in cache). A dynamic alternative (inline `$S` preamble before the main header) was also implemented and may be useful for standalone/streaming scenarios where no schema cache exists. | ||
| ## Transport | ||
| MCP uses two transports: | ||
| | Transport | Gateway acts as | Implementation | | ||
| |---|---|---| | ||
| | **stdio** | Pipe relay — reads server stdout, writes to client stdin | Spawn child process, intercept streams | | ||
| | **SSE** | HTTP proxy — POST to server, SSE to client | HTTP middleware | | ||
| Both transports carry the same JSON-RPC messages. The gateway's DCP logic is transport-agnostic — it operates on the parsed JSON-RPC layer. | ||
| ### stdio configuration | ||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "my-server": { | ||
| "command": "npx", | ||
| "args": ["dcp-gateway", "--server", "node", "path/to/mcp-server.js"] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
| From the client's perspective, `dcp-gateway` is the MCP server. The gateway spawns the real server as a child process. | ||
| ### SSE configuration | ||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "my-server": { | ||
| "url": "http://localhost:3200/sse", | ||
| "note": "DCP gateway proxying to upstream MCP server at :3100" | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
| ## Metrics | ||
| The gateway tracks compression statistics per tool: | ||
| ``` | ||
| dcp-gateway stats: | ||
| engram_pull: 87 calls, avg 68% reduction, schema: engram-recall:v1 | ||
| github_search: 23 calls, avg 52% reduction, schema: gh-search:v1 | ||
| db_query: 156 calls, avg 71% reduction, schema: db-rows:v1 | ||
| web_fetch: 12 calls, pass-through (plain text) | ||
| Total saved: ~2.4M tokens (estimated) | ||
| ``` | ||
| These metrics serve two purposes: | ||
| 1. **User visibility** — prove the gateway is doing something useful | ||
| 2. **DCP validation** — real-world compression ratios across diverse MCP servers | ||
| ## Scope and non-goals | ||
| **What the gateway does:** | ||
| - Transparent DCP compression of MCP tool responses | ||
| - Tool definition compression via tools/list interception | ||
| - Schema learning, caching, and preset loading | ||
| - Compression metrics | ||
| **What the gateway does not do:** | ||
| - Authentication, authorization, or token forwarding (the MCP gateway spec's primary concern) | ||
| - Session management or affinity | ||
| - Data loss prevention or content inspection | ||
| - Modification of tool call arguments (no queryType injection — server-agnostic means server-unaware) | ||
| - LLM system prompt or output control (outside MCP protocol scope) | ||
| The gateway is a compression layer, not a security layer. It can coexist with an enterprise MCP gateway that handles auth and audit — DCP gateway handles efficiency, enterprise gateway handles governance. | ||
| ## Relation to existing work | ||
| | Component | Role | | ||
| |---|---| | ||
| | **dcp-wrap** | Library — `dcpEncode()`, `SchemaGenerator`, CLI. The engine inside the gateway. | | ||
| | **mcp-server-contract.md** | Convention for MCP servers that natively support DCP via `queryType`. Ideal but requires server modification. | | ||
| | **picoclaw-hook** | Framework-specific hook (PicoClaw only). Proof of concept for the gateway pattern. | | ||
| | **DCP Gateway** | Framework-agnostic proxy. Works with any MCP server, no modification needed. Generalizes what picoclaw-hook proved. | | ||
| The gateway uses dcp-wrap internally. If an MCP server already supports `queryType: "agent"`, the gateway can inject it — but this is optional optimization, not a requirement. | ||
| ## Implementation plan | ||
| ### Phase 1: stdio proxy + response encoding | ||
| - Spawn MCP server as child process | ||
| - Relay JSON-RPC messages | ||
| - Intercept `tools/call` responses → SchemaGenerator → DCP encode | ||
| - Schema cache with TTL | ||
| ### Phase 2: tools/list compression + presets | ||
| - Intercept `tools/list` → compress descriptions and schemas | ||
| - Load preset files at startup | ||
| - Preset file format and community contribution model | ||
| ### Phase 3: SSE transport + metrics | ||
| - HTTP proxy mode for SSE-based MCP servers | ||
| - Per-tool compression statistics | ||
| - Stats endpoint or CLI command | ||
| ### Phase 4: multi-server aggregation | ||
| - Single gateway fronting multiple MCP servers | ||
| - Unified schema cache across all backends | ||
| - Client sees one MCP endpoint with all tools available |
| # MCP Server DCP Contract | ||
| How to build MCP tools that support compact output for AI agents — reducing token cost by 40-70% without breaking human-readable defaults. | ||
| This applies to **any MCP server** consumed by **any agent framework** (PicoClaw, Claude Code, Cursor, custom agents). The patterns here are not framework-specific. | ||
| ## The problem | ||
| Most MCP tools return human-readable text: | ||
| ``` | ||
| [1] DCP formatter placement: OUT-side... | ||
| hits=2 weight=-2.58 status=recent relevance=0.345 | ||
| tags: why, dcp, formatter, architecture | ||
| id: a7b5dce9-... | ||
| ``` | ||
| Every field label (`hits=`, `weight=`, `status=`, `tags:`, `id:`) repeats per record. For 10 records, that's 10x overhead. The LLM pays for all of it, then extracts the same information that a positional array conveys in a fraction of the tokens: | ||
| ``` | ||
| ["$S","engram-recall:v1",7,"id","relevance","summary","tags","hitCount","weight","status"] | ||
| ["a7b5dce9","0.345","DCP formatter placement: OUT-side...","why,dcp,formatter,architecture",2,-2.58,"recent"] | ||
| ``` | ||
| Same data. 70% fewer tokens. The LLM reads both equally well. | ||
| ## The contract: `queryType` parameter | ||
| Add a `queryType` parameter to any tool that returns structured data: | ||
| ```typescript | ||
| server.tool("my_search", { | ||
| query: z.string(), | ||
| queryType: z.enum(["human", "agent"]).optional() | ||
| .describe("'agent' returns DCP compact format. Default: 'human'."), | ||
| }, async ({ query, queryType }) => { | ||
| const results = await search(query); | ||
| if (queryType === "agent") { | ||
| return { content: [{ type: "text", text: dcpEncode(results, schema) }] }; | ||
| } | ||
| return { content: [{ type: "text", text: formatHuman(results) }] }; | ||
| }); | ||
| ``` | ||
| - `human` (default): verbose natural language. Compatible with everything. | ||
| - `agent`: DCP positional arrays. 40-70% token reduction. | ||
| The consumer decides. The LLM doesn't need to know — agent frameworks inject `queryType: "agent"` automatically via hooks or middleware. | ||
| ## Schema design rules | ||
| ### 1. Do not use `additionalProperties: false` | ||
| Agent frameworks inject parameters at runtime via hooks. If your schema blocks unexpected properties, injection fails. | ||
| ```typescript | ||
| // BAD — blocks parameter injection | ||
| server.tool("my_tool", z.object({ | ||
| query: z.string(), | ||
| }).strict(), handler); // .strict() = additionalProperties: false | ||
| // GOOD — allows parameter injection | ||
| server.tool("my_tool", z.object({ | ||
| query: z.string(), | ||
| queryType: z.enum(["human", "agent"]).optional(), | ||
| }), handler); | ||
| ``` | ||
| Real failure mode: a `before_tool` hook injects `queryType: "agent"`, but the framework validates against the original schema and rejects the call with `"unexpected property"`. The tool never executes. | ||
| **Best practice:** Define `queryType` explicitly rather than relying on open schemas. This documents the capability and makes the tool self-describing. | ||
| ### 2. Add `queryType` to every search/list tool | ||
| Not just the main query tool — any tool that returns structured data: | ||
| ```typescript | ||
| const dcpParam = z.enum(["human", "agent"]).optional() | ||
| .describe("'agent' returns DCP compact format. Default: 'human'."); | ||
| server.tool("my_pull", { query: z.string(), queryType: dcpParam }, pullHandler); | ||
| server.tool("my_ls", { tag: z.string().optional(), queryType: dcpParam }, lsHandler); | ||
| server.tool("my_status", { /* no queryType — small fixed payload */ }, statusHandler); | ||
| ``` | ||
| **Rule of thumb:** if the tool returns >5 records or >500 chars, it should accept `queryType`. | ||
| Tools with small, fixed-structure responses (status checks, config reads) don't need it — the overhead of adding DCP format exceeds the savings. | ||
| ### 3. Handle null arguments | ||
| LLMs (Claude, GPT) sometimes send `null` instead of `{}` for tools with all-optional parameters. MCP SDKs often reject this: | ||
| ``` | ||
| Tool call: my_status(null) | ||
| MCP error: "expected record, received null" | ||
| ``` | ||
| Defend against this: | ||
| ```typescript | ||
| // Option A: have at least one parameter with a default | ||
| server.tool("my_status", { | ||
| projectId: z.string().optional().describe("Project filter"), | ||
| }, handler); // LLM sends {} or {"projectId":"..."}, rarely null | ||
| // Option B: guard in handler | ||
| server.tool("my_status", {}, async (params) => { | ||
| const args = params ?? {}; | ||
| // ... | ||
| }); | ||
| ``` | ||
| ### 4. Separate data format from output density | ||
| If your tool already has a `format` parameter for data format, don't overload it: | ||
| ```typescript | ||
| server.tool("export", { | ||
| format: z.enum(["json", "csv"]), // what the data looks like | ||
| queryType: z.enum(["human", "agent"]), // how dense the output is | ||
| }, handler); | ||
| ``` | ||
| `format` controls structure. `queryType` controls verbosity. They're orthogonal. | ||
| ## The DCP output format | ||
| When `queryType: "agent"`, return DCP positional arrays: | ||
| ```typescript | ||
| import { dcpEncode } from "dcp-wrap"; | ||
| const schema = { id: "my-results:v1", fields: ["id", "score", "title", "tags"] }; | ||
| function formatAgent(results: Record<string, unknown>[]): string { | ||
| return dcpEncode(results, schema); | ||
| } | ||
| ``` | ||
| Output: | ||
| ``` | ||
| ["$S","my-results:v1",4,"id","score","title","tags"] | ||
| ["abc",0.95,"Port conflict fix","docker,networking"] | ||
| ["def",0.82,"Config path gotcha","config,paths"] | ||
| ``` | ||
| The `$S` header declares the schema once. Each row is a positional array — no key repetition. The LLM reads positional data as well as keyed JSON, at a fraction of the token cost. | ||
| If you don't want a dependency on dcp-wrap, format manually: | ||
| ```typescript | ||
| function formatAgent(results: any[]): string { | ||
| const header = `["$S","my-results:v1",${fields.length},${fields.map(f => `"${f}"`).join(",")}]`; | ||
| const rows = results.map(r => JSON.stringify(fields.map(f => r[f] ?? null))); | ||
| return [header, ...rows].join("\n"); | ||
| } | ||
| ``` | ||
| ## Why this matters | ||
| Without the `queryType` contract: | ||
| - External hooks can only observe text output, not compress it | ||
| - Every agent framework must parse every tool's text format independently | ||
| - Token costs scale linearly with output verbosity | ||
| With the `queryType` contract: | ||
| - One parameter, one convention across all MCP servers | ||
| - Agent frameworks inject it once — no per-tool configuration | ||
| - 40-70% token reduction, measured in production (engram MCP: 5649 → 1697 chars, 10 results) | ||
| - Human format stays default — nothing breaks for consumers that don't support DCP | ||
| ## Checklist for MCP server authors | ||
| - [ ] Tools returning structured data accept `queryType: "human" | "agent"` parameter | ||
| - [ ] `human` is the default — omitting `queryType` returns human-readable text | ||
| - [ ] `agent` returns DCP positional arrays with `$S` header | ||
| - [ ] No `additionalProperties: false` / `.strict()` on tool schemas | ||
| - [ ] Null arguments handled gracefully (no crash on `null` params) | ||
| - [ ] `queryType` is separate from any existing `format` parameter | ||
| ## References | ||
| - [DCP Specification](https://dcp-docs.pages.dev/dcp/specification) — full protocol design | ||
| - [dcp-wrap](https://github.com/hiatamaworkshop/dcp-wrap) — encoder/decoder library + CLI | ||
| - [PicoClaw integration](./picoclaw-integration.md) — framework-specific hook setup |
@@ -37,3 +37,11 @@ import { DcpSchema } from "./schema.js"; | ||
| static toString(batch: EncodedBatch): string; | ||
| /** | ||
| * Encode a single field value. | ||
| * If nestSchemas has a sub-schema for this field: | ||
| * Array-of-objects → ["$R", schemaId, ...rows] | ||
| * Empty array → ["$R", schemaId] (no rows) | ||
| * Otherwise → pass through | ||
| */ | ||
| private encodeFieldValue; | ||
| private detectMask; | ||
| } |
+38
-3
@@ -0,1 +1,3 @@ | ||
| import { DcpSchema } from "./schema.js"; | ||
| import { FieldMapping } from "./mapping.js"; | ||
| /** | ||
@@ -74,5 +76,8 @@ * One-step DCP encode. No schema file, no generator, no mapping. | ||
| const header = JSON.stringify(headerArr); | ||
| // Build rows | ||
| // Build rows (nested arrays use $R references) | ||
| const rows = resolvedBatch.map((resolved) => { | ||
| const row = activeFields.map((f) => resolved[f] ?? null); | ||
| const row = activeFields.map((f) => { | ||
| const val = resolved[f] ?? null; | ||
| return this.encodeFieldValue(f, val); | ||
| }); | ||
| return JSON.stringify(row); | ||
@@ -85,3 +90,3 @@ }); | ||
| const resolved = this.mapping.resolve(record); | ||
| return this.schema.fields.map((f) => resolved[f] ?? null); | ||
| return this.schema.fields.map((f) => this.encodeFieldValue(f, resolved[f] ?? null)); | ||
| } | ||
@@ -94,2 +99,32 @@ /** Render encoded batch as a string (header + rows, newline-separated). */ | ||
| } | ||
| /** | ||
| * Encode a single field value. | ||
| * If nestSchemas has a sub-schema for this field: | ||
| * Array-of-objects → ["$R", schemaId, ...rows] | ||
| * Empty array → ["$R", schemaId] (no rows) | ||
| * Otherwise → pass through | ||
| */ | ||
| encodeFieldValue(fieldName, value) { | ||
| const nest = this.schema.def.nestSchemas?.[fieldName]; | ||
| if (!nest) | ||
| return value; | ||
| if (!Array.isArray(value)) | ||
| return value; | ||
| const subSchema = new DcpSchema(nest.schema); | ||
| const sid = subSchema.id; | ||
| if (value.length === 0) { | ||
| return ["$R", sid]; | ||
| } | ||
| // Check items are objects | ||
| if (!value.every((item) => typeof item === "object" && item !== null && !Array.isArray(item))) { | ||
| return value; | ||
| } | ||
| const subMapping = new FieldMapping(nest.mapping); | ||
| const subEncoder = new DcpEncoder(subSchema, subMapping); | ||
| const subBatch = subEncoder.encode(value); | ||
| if (!subBatch.header) | ||
| return ["$R", sid]; | ||
| const rowArrs = subBatch.rows.map((r) => JSON.parse(r)); | ||
| return ["$R", sid, ...rowArrs]; | ||
| } | ||
| detectMask(resolvedBatch) { | ||
@@ -96,0 +131,0 @@ let mask = 0; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"encoder.js","sourceRoot":"","sources":["../src/encoder.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"encoder.js","sourceRoot":"","sources":["../src/encoder.ts"],"names":[],"mappings":"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"} |
+61
-6
@@ -46,2 +46,9 @@ import { flattenKeys } from "./mapping.js"; | ||
| } | ||
| /** Check if a value is a homogeneous array of objects (candidate for nested DCP). */ | ||
| function isArrayOfObjects(values) { | ||
| const nonNull = values.filter((v) => v != null); | ||
| if (nonNull.length === 0) | ||
| return false; | ||
| return nonNull.every((v) => Array.isArray(v) && v.length > 0 && v.every((item) => typeof item === "object" && item !== null && !Array.isArray(item))); | ||
| } | ||
| function inferType(values) { | ||
@@ -105,4 +112,17 @@ const nonNull = values.filter((v) => v != null); | ||
| const maxDepth = options.maxDepth ?? 3; | ||
| const maxFields = options.maxFields ?? 20; | ||
| const maxFields = options.maxFields ?? Infinity; | ||
| const minPresence = options.minPresence ?? 0.1; | ||
| // Step 0.5: Detect array-of-objects fields (before flattening) | ||
| const arrayObjectFields = new Map(); | ||
| for (const sample of samples) { | ||
| for (const [key, value] of Object.entries(sample)) { | ||
| if (Array.isArray(value) && | ||
| value.length > 0 && | ||
| value.every((item) => typeof item === "object" && item !== null && !Array.isArray(item))) { | ||
| if (!arrayObjectFields.has(key)) | ||
| arrayObjectFields.set(key, []); | ||
| arrayObjectFields.get(key).push(value); | ||
| } | ||
| } | ||
| } | ||
| // Step 1: Flatten and collect per-path values | ||
@@ -166,9 +186,22 @@ const pathValues = new Map(); | ||
| // Step 4: Deduplicate field names | ||
| const seenNames = new Map(); | ||
| // Use the full source path (dot-separated) as prefix for disambiguation | ||
| // e.g. user.url → user_url, milestone.url → milestone_url | ||
| const seenNames = new Set(); | ||
| for (const field of analyzed) { | ||
| const count = seenNames.get(field.schemaName) ?? 0; | ||
| if (count > 0) { | ||
| field.schemaName = `${field.schemaName}_${count}`; | ||
| if (seenNames.has(field.schemaName)) { | ||
| // Use parent path segments as prefix to disambiguate | ||
| const parts = field.sourcePath.split("."); | ||
| if (parts.length > 1) { | ||
| field.schemaName = `${parts[parts.length - 2]}_${parts[parts.length - 1]}`; | ||
| } | ||
| // If still colliding, append incrementing suffix | ||
| let candidate = field.schemaName; | ||
| let i = 2; | ||
| while (seenNames.has(candidate)) { | ||
| candidate = `${field.schemaName}_${i}`; | ||
| i++; | ||
| } | ||
| field.schemaName = candidate; | ||
| } | ||
| seenNames.set(field.schemaName, count + 1); | ||
| seenNames.add(field.schemaName); | ||
| } | ||
@@ -181,5 +214,26 @@ // Step 5: Build schema and mapping | ||
| const fieldReports = []; | ||
| const nestSchemas = {}; | ||
| for (const f of analyzed) { | ||
| types[f.schemaName] = f.typeInfo; | ||
| paths[f.schemaName] = f.sourcePath; | ||
| // Generate sub-schema for array-of-objects fields → nestSchemas | ||
| const aoSamples = arrayObjectFields.get(f.sourcePath); | ||
| if (aoSamples && aoSamples.length > 0) { | ||
| const allItems = aoSamples.flat(); | ||
| if (allItems.length > 0) { | ||
| const subGen = new SchemaGenerator(); | ||
| const subDraft = subGen.fromSamples(allItems, { | ||
| domain: `${domain}.${f.schemaName}`, | ||
| version, | ||
| maxDepth: 0, // sub-schemas: top-level only, nested objects stay as JSON | ||
| maxFields, | ||
| minPresence, | ||
| }); | ||
| types[f.schemaName] = { ...f.typeInfo, type: "array" }; | ||
| nestSchemas[f.schemaName] = { | ||
| schema: subDraft.schema, | ||
| mapping: subDraft.mapping, | ||
| }; | ||
| } | ||
| } | ||
| const nonNull = f.values.filter((v) => v != null); | ||
@@ -208,2 +262,3 @@ const uniqueCount = new Set(nonNull.map(String)).size; | ||
| types, | ||
| ...(Object.keys(nestSchemas).length > 0 ? { nestSchemas } : {}), | ||
| }; | ||
@@ -210,0 +265,0 @@ const mapping = { schemaId, paths }; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"} |
+1
-1
@@ -8,2 +8,2 @@ export { DcpSchema } from "./schema.js"; | ||
| export type { DecodeResult, TemplateMap } from "./decoder.js"; | ||
| export type { DcpSchemaDef, FieldTypeDef, FieldMappingDef, GenerateOptions, EncodedBatch, SchemaDraft, FieldReport, } from "./types.js"; | ||
| export type { DcpSchemaDef, NestSchemaDef, FieldTypeDef, FieldMappingDef, GenerateOptions, EncodedBatch, SchemaDraft, FieldReport, } from "./types.js"; |
+2
-0
@@ -8,2 +8,4 @@ import type { DcpSchemaDef, FieldTypeDef } from "./types.js"; | ||
| readonly types: Record<string, FieldTypeDef>; | ||
| /** Full definition including nestSchemas. */ | ||
| readonly def: DcpSchemaDef; | ||
| constructor(def: DcpSchemaDef); | ||
@@ -10,0 +12,0 @@ /** Bitmask with all field bits set. */ |
+3
-0
@@ -9,2 +9,4 @@ import { readFileSync, writeFileSync, mkdirSync } from "node:fs"; | ||
| types; | ||
| /** Full definition including nestSchemas. */ | ||
| def; | ||
| constructor(def) { | ||
@@ -16,2 +18,3 @@ this.id = def.id; | ||
| this.types = { ...def.types }; | ||
| this.def = def; | ||
| } | ||
@@ -18,0 +21,0 @@ /** Bitmask with all field bits set. */ |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"} |
+7
-0
@@ -17,3 +17,10 @@ /** Type definition for a single schema field. */ | ||
| types: Record<string, FieldTypeDef>; | ||
| /** Nested sub-schemas for array-of-objects fields. Key = field name. */ | ||
| nestSchemas?: Record<string, NestSchemaDef>; | ||
| } | ||
| /** Sub-schema + mapping pair for a nested array-of-objects field. */ | ||
| export interface NestSchemaDef { | ||
| schema: DcpSchemaDef; | ||
| mapping: FieldMappingDef; | ||
| } | ||
| /** Mapping: schema field name → dot.notation.path in source. */ | ||
@@ -20,0 +27,0 @@ export interface FieldMappingDef { |
+1
-1
| { | ||
| "name": "dcp-wrap", | ||
| "version": "0.2.0", | ||
| "version": "0.3.0", | ||
| "description": "Convert JSON to DCP positional-array format for AI agents — 40-70% token reduction", | ||
@@ -5,0 +5,0 @@ "type": "module", |
+83
-0
@@ -126,2 +126,85 @@ # dcp-wrap | ||
| ## Nested DCP (array-of-objects) | ||
| Arrays of objects are encoded using **`$R` references** — the sub-schema is stored in the schema definition (`nestSchemas`), and the output references it by ID without repeating the header. | ||
| ```json | ||
| [ | ||
| {"id": "u001", "name": "Alice", "teams": [{"id": "t01", "name": "Infra", "role": "lead"}, {"id": "t02", "name": "Security", "role": "member"}]}, | ||
| {"id": "u002", "name": "Bob", "teams": [{"id": "t03", "name": "Frontend", "role": "member"}]}, | ||
| {"id": "u003", "name": "Charlie", "teams": []} | ||
| ] | ||
| ``` | ||
| Becomes: | ||
| ``` | ||
| ["$S","user:v1","id","name","teams"] | ||
| ["u001","Alice",["$R","user.teams:v1",["t01","Infra","lead"],["t02","Security","member"]]] | ||
| ["u002","Bob",["$R","user.teams:v1",["t03","Frontend","member"]]] | ||
| ["u003","Charlie",["$R","user.teams:v1"]] | ||
| ``` | ||
| The sub-schema structure lives in the schema definition file: | ||
| ```json | ||
| { | ||
| "$dcp": "schema", | ||
| "id": "user:v1", | ||
| "fields": ["id", "name", "teams"], | ||
| "nestSchemas": { | ||
| "teams": { | ||
| "schema": { "$dcp": "schema", "id": "user.teams:v1", "fields": ["id", "name", "role"], ... }, | ||
| "mapping": { "schemaId": "user.teams:v1", "paths": { "id": "id", "name": "name", "role": "role" } } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
| The `$R` convention: | ||
| - `["$R", "schema-id", [row1], [row2], ...]` — array with rows | ||
| - `["$R", "schema-id"]` — empty array (no rows) | ||
| ### Design: static vs dynamic approach | ||
| Two approaches were evaluated for nested DCP encoding: | ||
| **Dynamic (inline `$S` preamble)** — sub-schema headers emitted at the top of each output: | ||
| ``` | ||
| ["$S","user.teams:v1","id","name","role"] ← preamble: sub-schema declaration | ||
| ["$S","user:v1","id","name","teams"] ← main header | ||
| ["u001","Alice",["$R","user.teams:v1",...]] ← $R references preamble | ||
| ``` | ||
| Pros: self-contained output, no schema file needed for decoding. Cons: preamble overhead at small N; schema declared per-output rather than per-tool. | ||
| **Static (`nestSchemas` in schema definition)** — sub-schemas stored in the cached schema, output carries only `$R` references: | ||
| ``` | ||
| ["$S","user:v1","id","name","teams"] | ||
| ["u001","Alice",["$R","user.teams:v1",...]] | ||
| ``` | ||
| Pros: no per-output overhead, schema cache is the single source of truth, round-trip serializable. Cons: consumer must have access to the schema definition to resolve `$R`. | ||
| **Chosen: static.** The gateway already caches schemas per tool. Storing `nestSchemas` there is the natural fit — infer once on first call, encode with `$R` on all subsequent calls. The dynamic approach remains valid for standalone/streaming use cases where the consumer has no schema cache. | ||
| ### Compression characteristics | ||
| | Records | JSON-only baseline | Flat DCP (no nesting) | Nested DCP (`$R`) | | ||
| |---------|-------------------|----------------------|-------------------| | ||
| | 3 | 0% | ~25% | ~23% | | ||
| | 10 | 0% | ~27% | ~28% | | ||
| | 30 | 0% | ~28% | ~32% | | ||
| | 100 | 0% | ~30% | ~33% | | ||
| At low record counts `$R` + schema-id overhead is slightly larger than repeating raw keys. At 10+ records the crossover occurs. The primary advantage is **consistency** (no JSON/DCP mixed format) and **LLM readability** (tested: Haiku 4.5 decodes nested `$R` structures with 10/10 accuracy on positional extraction tasks). | ||
| ### Known limitations | ||
| 1. **Sparse sub-fields**: When nested objects have heterogeneous keys (e.g. API responses with variable `metadata`), sub-schemas produce many nullable columns. Current mitigation: `maxDepth: 0` for sub-schemas keeps variable objects as opaque JSON. | ||
| 2. **`$R` requires schema context**: Unlike inline `$S`, the `$R` reference is only meaningful if the consumer has the `nestSchemas` definition. For the gateway use case this is always true (schema is cached). For standalone output, the dynamic preamble approach may be preferable. | ||
| 3. **Empty arrays**: `["$R", "schema-id"]` with no trailing rows. Correct behavior — zero rows, schema ID preserved for type information. | ||
| ## Working with messy data | ||
@@ -128,0 +211,0 @@ |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
187178
35.51%41
13.89%1853
19.63%256
47.98%