Skip to content

Add plugin trace-mcp - #54

Open
nikolai-vysotskyi wants to merge 3 commits into
MiniMax-AI:mainfrom
nikolai-vysotskyi:add-trace-mcp-plugin
Open

nikolai-vysotskyi wants to merge 3 commits into
MiniMax-AI:mainfrom
nikolai-vysotskyi:add-trace-mcp-plugin

Conversation

@nikolai-vysotskyi

@nikolai-vysotskyi nikolai-vysotskyi commented Sep 19, 2026

Copy link
Copy Markdown

What changes

Adds plugins/nikolai-vysotskyi/trace-mcp: a portable Agent Plugins 1.0 package for trace-mcp, a local code-intelligence MCP server. Upstream: https://github.com/nikolai-vysotskyi/trace-mcp

Contents: plugin.json, mcp.json (one stdio server, bare trace-mcp command), README.md, MIT LICENSE, and four skills (trace-mcp, trace-mcp-refactoring, trace-mcp-codemod, trace-mcp-pre-commit).

User value

A MiniMax Code user can ask who calls a function and what breaks if its signature changes, and get the answer from the index instead of the agent reading files one by one.

Example prompt:

Find every caller of `validateHostedPluginDirectory` in this repo and tell me what breaks if I change its signature.

Expected result: the agent calls the trace-mcp search and impact tools and answers with the call sites plus the blast radius, without opening each file. On an unindexed project the agent runs trace init once first.

Plugin submission checklist

  • Plugin lives at plugins/<github-owner>/<plugin-name>.
  • plugin.json name matches the Plugin directory.
  • README.md includes a real example prompt and expected result.
  • LICENSE and plugin.json declare an open-source license (MIT in both, same as upstream).
  • Required executables, accounts, paid services, and supported platforms are disclosed (Node.js 22+, trace-mcp on PATH via npm install -g trace-mcp, macOS/Linux/Windows; no account, no paid service, no key).
  • Network destinations and data handled by the plugin are disclosed (index stays on the user's machine; at most one anonymous usage ping per day with the exact opt-outs; nothing else leaves the machine).
  • No credentials, private endpoints, hidden telemetry, installers, symlinks, or native binaries are included (the one ping is documented in README under Data and network, not hidden).
  • Every scaffold TODO has been replaced (no TODO string in the package; verified by search).
  • npm run check passes (left to CI; see Evidence).

Evidence

I read scripts/lib/validation.mjs and checked this package against it without executing repo code: owner and plugin names match the required patterns, plugin.json name equals the directory, all manifest fields are in the allowed set, mcp.json holds one stdio server with a bare command, 4 skill directories (limit 64) each with frontmatter name equal to the directory and a non-empty body, non-empty README.md and LICENSE, zero symlinks. The shipped plugin.json, mcp.json, and skill files are byte-identical to the ones at the upstream repo root and in its skills/ directory, where other runtimes already consume them; the only new file is the hosted README.md.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@hetaoBackend hetaoBackend left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request changes for exact current head bf93ee43e5ac3ebbeb2c4cec288726bbd8d6529a.

The package shape and MIT licensing validate, but this PR currently delegates a broad local-code capability to an unverifiable external executable without adequate disclosure or runtime evidence:

  1. The MCP executable is unpinned and PATH-selected. mcp.json:3-7 runs bare trace-mcp, while plugin.json declares 3.28.0 and README.md:15-18 tells users to install unversioned latest. The actual high-privilege program can therefore be another version or any same-named PATH entry. At minimum pin the supported package/version in installation instructions, document that the host cannot verify its identity, and provide a provenance/integrity mechanism or a controlled bundled server.
  2. Network/data disclosure is incomplete. README.md:22-26 says source never leaves the machine and there is no other network access, but upstream 3.28.0 sends an opt-out daily Google Analytics usage ping with a persistent local UUID/system/tool counters, and supports opt-in remote AI providers plus Langfuse/OTLP observability. List the endpoint, fields and opt-outs, and limit “source stays local” to the default configuration; disclose when optional remote features can transmit code/context.
  3. The plugin includes mutating tools without a complete safety contract. skills/trace-mcp-codemod/SKILL.md:64-70 enables non-dry-run codemods and skills/trace-mcp-refactoring/SKILL.md:54-66 invokes repository-wide rename operations. README should disclose bulk writes and confirmation/rollback behavior, with executable negative tests for default no-write/dry-run, large-change confirmation, path/symlink rejection, and partial-failure cleanup.
  4. There is no real executable evidence. The only GitHub check is skipped [code]smith; repository validation exercises manifests, not trace-mcp initialize/tools/list/tool calls, telemetry opt-out, or mutation boundaries. Add exact-version MCP handshake and safety smoke tests, including Windows if Windows remains claimed.

No embedded secret, native binary, direct SSRF field, or license incompatibility was found in the submitted files. The blockers are the external executable/supply-chain boundary and the undisclosed runtime behavior. [code]smith is skipped and was not used as evidence.

@nikolai-vysotskyi

Copy link
Copy Markdown
Author

Thanks for the detailed review — all four points hold up against the 3.28.0 tree, checked this morning.

  1. Unpinned executable — correct. mcp.json runs bare trace-mcp while plugin.json declares 3.28.0, so a stale global install or any same-named PATH entry silently wins. Fix: pin the install line to npm install -g trace-mcp@3.28.0, state the validated version, document that the host cannot verify the binary's identity, and point at verification that does exist — the npm package ships with Sigstore provenance (npm audit signatures).

  2. Telemetry disclosure — correct on both halves. The daily ping goes to Google's GA4 Measurement Protocol endpoint and carries a persistent locally-generated UUID plus version, OS, client, model, repo count, machine class, and aggregate tool/savings/daemon counters; the plugin README names neither the endpoint nor the fields. And "source never leaves the machine" is true only for the default configuration — cloud embedding providers sit behind an explicit consent gate (~/.trace-mcp/consent.json) and OTLP/Langfuse export to a user-configured backend, so that sentence needs the scope. Rewriting the Data and network section with endpoint, fields, both opt-outs, and the default-config scope.

  3. Mutating tools — the codemod skill defaults to dry-run with a confirm_large gate above 20 files, but the plugin README discloses nothing about bulk writes at all. Adding that disclosure.

  4. Executable evidence — acknowledged; a skipped [code]smith is indeed the only signal here. I'll add a version-pinned handshake and safety smoke test (initialize/tools-list against the pinned build, telemetry opt-out honored, dry-run default, path/symlink rejection) and report results here, including Windows.

Pushing the fixes for 1–3 to this branch today, 4 to follow; will re-request review once all four are in.

Addresses review points 1-3 on PR MiniMax-AI#54: version-pinned install with
PATH caveat and provenance check, GA4 endpoint/fields/opt-outs with
default-config scope, bulk-write disclosure for apply_rename/apply_codemod.
@nikolai-vysotskyi

Copy link
Copy Markdown
Author

Status on the four points. Fixes for 1-3 are in this branch (89ae973). For point 4 I ran the pinned build instead of describing it, and the runs turned up two upstream write-boundary gaps, so I am holding the re-request until those are fixed and re-tested.

Setup: trace-mcp@3.28.0 installed from npm into a clean prefix, stdio session with daemon auto-spawn off, auto-update off, isolated home, telemetry off. initialize answered serverInfo.version 3.28.0 over protocol 2024-11-05. Default preset serves 29 tools with neither mutating tool advertised; both appear after load_tools (dev preset, 46 tools).

What passed, all against the pinned build with zero writes outside the intended assertions:

  • Dry-run default on apply_rename and apply_codemod: previews returned (29 edits previewed for a rename), files byte-identical afterward.
  • confirm_large at >20 files: rename hard-blocks with success: false; codemod downgrades to dry-run with a warning naming the file count. A 25-file fixture stayed untouched in both cases.
  • .. traversal in file-path arguments: rejected with SECURITY_VIOLATION.
  • Telemetry opt-out: no ping state written to a clean home with TRACE_MCP_TELEMETRY=off.

What did not pass: the codemod file pattern is not confined to the project root, and writes addressed through in-root symlinks land outside it. Both reproduced on current latest (3.31.2), so moving the pin would not close it. I have logged this with the trace-mcp maintainers (that is us) and the fix goes in there first. I am keeping exploit detail out of this thread; the next update here is a pinned fixed version plus passing boundary tests, and only then a re-request.

Two adjacent observations from the runs, relevant to point 1. The pinned install self-updates by default (my 3.28.0 session started fetching 3.31.2 mid-run; TRACE_MCP_NO_AUTO_UPDATE=1 opts out). And when a newer local daemon is reachable, the stdio server proxies execution to it: my first run launched the 3.28.0 binary but answered version 3.31.2 from the desktop daemon. Pin plus npm audit signatures narrows the supply chain but does not fully determine the executing code while a daemon is around. I will fold both notes into the README with the fix.

@hetaoBackend hetaoBackend left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request changes for exact current head 89ae9733713627bdbc6cde6cc8dc5d46577bd6c7.

The telemetry/remote-provider/mutation disclosures are materially better, but the executable and safety contract is still not verifiable:

  1. mcp.json still launches bare trace-mcp from PATH. The README pins an install command, but the plugin cannot enforce the resolved executable, version, source or npm integrity; plugin.json version metadata does not constrain the process that answers that name. Add a controlled/version-checked launcher or an equivalent fail-closed runtime provenance/version check.
  2. The README says two tools modify the checkout, but the bundled refactoring skill also invokes extract_function; the mutation surface is incomplete. Document every mutating tool and its preview/confirmation/file-range/rollback semantics.
  3. There is still no exact-version external MCP smoke for real initialize, tools/list, tools/call, telemetry opt-out, wrong/stale PATH detection, or mutation boundaries. Add an isolated-home/PATH smoke against the supported package and verify dry_run, >20-file confirmation, rename/extract mutation and partial-failure behavior.
  4. The only exact-head visible check is [code]smith = SKIPPED; repository manifest validation does not prove this third-party executable works.

The npm package has positive integrity/signature/provenance metadata, but that does not close the host PATH binding or executable behavior gap. Do not merge until the exact executable contract and real MCP smoke are present.

…ill param fix

- mcp.json runs npx -y trace-mcp@3.28.0 instead of a bare PATH
  binary, so the pinned registry version answers every launch and a
  stale global install or same-named PATH entry is never consulted.
- README Writes section lists all six mutating tools with their exact
  gates (dry_run default, confirm_large past 20 files on rename and
  codemod only), states the two limits plainly (no automatic rollback,
  project-root confinement without symlink resolution), and notes the
  dev-preset requirement for the bundled skills.
- Refactoring skill: extract_function example uses the schema's
  function_name (was new_name, which the tool rejects).
@nikolai-vysotskyi

Copy link
Copy Markdown
Author

Round 2 addressed in 810585b, everything below re-verified against the pinned 3.28.0 rather than described from memory.

  1. PATH binding — closed structurally instead of documented around. mcp.json now runs npx -y trace-mcp@3.28.0, so the registry-resolved pinned version answers every launch and a same-named PATH entry is never consulted. Checked with a fake trace-mcp (prints 0.0.0-fake) placed first on PATH: npx -y trace-mcp@3.28.0 --version still prints 3.28.0. The offline fallback (pre-installed binary plus a trace-mcp --version check) is documented with its weaker guarantee stated outright. This matches the uvx shape already merged in this repo.

  2. Mutation surface — the README Writes section now names all six mutating tools (apply_rename, apply_codemod, extract_function, apply_move, change_signature, remove_dead_code) with per-tool gates, and plan_refactoring as the read-only preview. Two limits are stated as limits, not softened: applied edits are never rolled back automatically (a post-apply type-check failure is reported, not reverted), and file arguments are confined to the indexed project root lexically — no symlink resolution is claimed. Your reading also caught a real bug: the bundled refactoring skill's extract example used new_name, which the schema rejects; it now uses function_name. (That wrong example exists upstream too — flagging, not fixing, outside this PR.)

  3. Smoke — isolated run (clean HOME, TRACE_MCP_NO_DAEMON=1, TRACE_MCP_NO_AUTO_UPDATE=1, TRACE_MCP_TELEMETRY=off, scratch repo of 26 files) against the pinned build over stdio: initialize answers serverInfo.version 3.28.0; tools/list (dev preset, 44 tools) shows dry_run defaulting to true on all six mutating tools and confirm_large existing only on rename and codemod; apply_rename dry-run previews 49 edits across 25 files with the tree byte-identical; the same call with dry_run: false and no confirm_large returns success: false (Rename affects 25 files (>20). Pass confirm_large: true to proceed.) with the tree still identical; extract_function applies on one file; no telemetry state is written under the isolated home. One related correction to my previous comment: the >20-file path fails closed with the preview returned, it does not "downgrade to dry-run" — the README now says exactly that. The skills also need the dev preset (load_tools) since the mutating tools are hidden under the default preset; that is now in the README. I kept the plugin directory to manifest plus docs and left the script out — say the word if you want it committed for repeatability.

  4. [code]smith skipped — nothing I can change from this side; manifest validation is the repo's own gate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants