Skip to content

[bug] Generated Pi adapter uses deprecated positional raw JSON instead of stdin #1834

Description

@madebymlai

Version

Platform

Linux (x64)

Install channel

GitHub release archive / install.sh

Binary variant

standard

What happened, and what did you expect?

The generated Pi extension (~/.pi/agent/extensions/cbmem.ts) invokes every tool by placing serialized JSON in a positional CLI argument:

spawn(BIN, ['cli', '--json', tool, JSON.stringify(args ?? {})], {
  stdio: ['ignore', 'pipe', 'pipe'],
  // ...
});

The CLI itself declares this argument form deprecated and writes a warning to stderr on every call:

warning: passing raw JSON to 'cli list_projects' is deprecated and will be removed in a future release; use flags (run 'cli list_projects --help'), --args-file <path>, or piped stdin.

The README also says inline JSON is retained only for backward compatibility and recommends flags, --args-file, or stdin.

I expected the generated adapter to use one of the supported non-deprecated transports. Since this is a programmatic bridge and already owns a child stdin pipe, stdin is the simplest option.

There are two related but distinct effects:

  1. v0.10.8 functional failure: the released generator does not include CLI --json. It tries to JSON.parse the default human-readable tree output, fails, and then surfaces the stderr deprecation warning as the tool error. Passing tool argument format:"json" makes some tools appear to work only because their stdout becomes parseable JSON. Tools without that format option (query_graph, get_architecture, search_code) remain unusable through the wrapper.
  2. Current main after fix(pi): emit parameters and execute in the generated pi adapter #1678: PR fix(pi): emit parameters and execute in the generated pi adapter #1678 correctly adds CLI --json, so the full MCP envelope is parseable and fixes the functional failure. However, the generated adapter still passes the request JSON positionally, so it still exercises the deprecated path and emits the warning on every invocation. It will break when the compatibility path is removed.

This issue is therefore narrower than #1806 / #1678: the tool schema/result-envelope work there is correct; this reports the remaining request transport.

Reproduction

No indexed or proprietary repository is required to reproduce the remaining main-branch problem.

Deprecated path used by the generated adapter:

CBM_LOG_LEVEL=error codebase-memory-mcp cli --json list_projects '{}'

Result: exit 0 and valid stdout, but stderr contains:

warning: passing raw JSON to 'cli list_projects' is deprecated and will be removed in a future release; use flags (run 'cli list_projects --help'), --args-file <path>, or piped stdin.

Documented stdin path:

printf '{}' | CBM_LOG_LEVEL=error codebase-memory-mcp cli --json list_projects

Result: exit 0, the same valid MCP envelope on stdout, and empty stderr.

I also verified stdin + --json with default tree output for search_graph, query_graph, and get_architecture. All return a valid MCP envelope; no tool-level format:"json" argument is needed.

Suggested fix

Generate the bridge with a writable stdin and remove the positional JSON argument:

const child = spawn(BIN, ['cli', '--json', tool], {
  stdio: ['pipe', 'pipe', 'pipe'],
  env: { ...process.env, CBM_LOG_LEVEL: 'error' },
});

child.stdin.on('error', () => {
  // The child may close stdin early after an abort or startup failure.
});
child.stdin.end(JSON.stringify(args ?? {}));

Sending {} and closing stdin also works for list_projects; as documented, that tool does not consume stdin and remains responsive.

Suggested regression assertions:

  • generated Pi adapter contains ['cli', '--json', tool]
  • generated Pi adapter uses stdio: ['pipe', 'pipe', 'pipe']
  • generated Pi adapter ends stdin with serialized args
  • generated Pi adapter does not append JSON.stringify(args ?? {}) to argv
  • smoke the generated adapter with a default tree-format tool and a tool without a format parameter (query_graph is suitable)
  • assert stderr does not contain the raw-JSON deprecation warning

Local workaround verified

I patched the generated extension to use --json plus stdin and to pass the MCP envelope's content through to Pi. A Jiti-loaded fixture registered all 15 tools and verified:

  • default-tree search_graph renders results
  • default-tree query_graph renders results
  • structured envelope details are preserved
  • MCP error envelopes throw a Pi tool error
  • no explicit tool-level format:"json" is required

Note: reinstall/update may overwrite the local extension until the generator ships the change.

Confirmations

Metadata

Metadata

Assignees

No one assigned

    Labels

    parsing/qualityGraph extraction bugs, false positives, missing edges

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions