Skip to content

fix(mcp): close the agent E2E product gaps (P7-SHIP-02) - #1031

Open
acamarata wants to merge 4 commits into
mainfrom
fix/ship02-mcp-gaps
Open

acamarata wants to merge 4 commits into
mainfrom
fix/ship02-mcp-gaps

Conversation

@acamarata

Copy link
Copy Markdown
Collaborator

Closes the five cli product gaps the P7-SHIP-02 MCP-only agent harness (#1029) stops at. Do not merge from here; the manager merges.

Changes

  1. nself mcp without a project. The server starts anywhere. With no project it lists nself_init and the read-only tools; once a project exists it lists every tool.
  2. First build is plan-bindable. A render that generates secrets gets a plan id its inputs reproduce: the content id of a second, read-only render with a fixed public seed. It is used only when both renders have the same plan; otherwise E451 still applies (fail closed). The plan declares secrets-persist; the apply draws fresh secrets and writes exactly its own render; input drift is still E450. The machine gate always returns a plan confirmation for a plan that declares secrets-persist, so the agent sees build (plan, then confirm).
  3. Live tool list. mcpgen.Surface checks the project root and the installed plugin set after every successful call. When they changed, it rebuilds the machine registry and calls SetTools, which sends notifications/tools/list_changed. The ci tools then appear after add ci in the same session.
  4. deploy promote <source> <target>. Use was promote [source target] (one arg); it is now two optional args, so ["qa","prod"] validates.
  5. nself mcp --timeout (default 5m, minimum 1s) bounds each tool call; a longer call answers E423.

nself mcp now rejects positional args (cobra.NoArgs). The generated registry, inventory, OpenAPI, TS SDK types, MCP tool golden and wiki pages are regenerated. The hand docs describe the new behaviour.

Tests

  • internal/reconcile: the binding id is the same for every seed; a plan id binds a first build; the written secrets are not the binding render's; drift gives E450; sameShape.
  • internal/invoke: a write plan with secrets-persist returns a kind plan confirmation; parsePlan reads the secrets fact.
  • internal/mcpgen: the no-project filter.
  • cmd/commands: an stdio session with no project, then init, then a plugin added during the session, with tools/list_changed each time and none when nothing changed; the --timeout E423 bound and flag validation; deploy promote qa prod argv; the fresh-project build --plan-id round trip with E450 on drift.

Local evidence (CI host mm4): go test passed for reconcile, invoke, mcpgen, errs and repoqa, and for the scoped cmd/commands MCP/build/surface/registry/contract tests in both compat modes. make contract-check and make wiki-check passed. TestMCPIntegration_InitBuildVerify (V15) fails on mm4 with E128 from a stray ~/.nself/plugins/cron in that host's real HOME. It fails the same way on unmodified origin/main there, so this change did not cause it.

@acamarata
acamarata force-pushed the fix/ship02-mcp-gaps branch 2 times, most recently from 5e3bb26 to 6aa6083 Compare October 29, 2026 22:16
The MCP-only agent harness (P7-SHIP-02) stops at five cli gaps. This
closes them.

1. nself mcp starts outside a project. It then lists nself_init and the
   read-only tools; once a project exists it lists every tool.
2. A first build can be bound by a plan id. A render that generates
   secrets gets an id its inputs reproduce: the content id of a second,
   read-only render with a fixed public seed, used only when both renders
   have the same plan. The plan declares the secrets-persist step, the
   apply writes fresh secrets, drift is still E450, and E451 remains for a
   render whose random values change the plan itself. The machine gate
   always returns a plan confirmation for a plan with secrets-persist, so
   an agent sees "build (plan, confirm)".
3. The tool list is live. After a successful call, mcpgen.Surface checks
   the project root and the installed plugin set; when they changed it
   rebuilds the machine registry and replaces the tools, which sends
   notifications/tools/list_changed (so the ci tools appear after add ci).
4. deploy promote declares two optional args, source and target, so the
   generated tool accepts ["qa", "prod"].
5. nself mcp --timeout (default 5m) bounds each tool call (E423 after it).

mcp now rejects positional args (cobra.NoArgs). Generated registry,
inventory, OpenAPI, TS SDK types, MCP tool golden and wiki pages are
regenerated; the hand docs (MCP-Server, Guide-Agents-MCP, Safe-On-Live,
cmd-build, cmd-mcp) describe the new behaviour.
Main grew cmd/commands to its ratchet ceiling, so the no-project notice
moves into mcpgen.Surface (printed through Warn) and the constructor
comment is shortened. Behaviour is unchanged.
The server writes notifications from its own goroutine, so on a loaded
Linux runner list_changed arrived after the 20 ping round trips the test
allowed. With no request outstanding the next line can only be a
notification, so the test reads the stream until it arrives, bounded by
a 30 s deadline.
@acamarata
acamarata force-pushed the fix/ship02-mcp-gaps branch from 6aa6083 to 81e7773 Compare October 29, 2026 22:55

This branch has not been deployed

No deployments
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.

1 participant