Skip to content

feat(cli): project MCP tools into the routed CLI via routes.mcpCommands (#102 stage 4) - #275

Merged
ScriptedAlchemy merged 3 commits into
mainfrom
feat/102-s4
Sep 2, 2026
Merged

feat(cli): project MCP tools into the routed CLI via routes.mcpCommands (#102 stage 4)#275
ScriptedAlchemy merged 3 commits into
mainfrom
feat/102-s4

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Second of two #102 stage-4 PRs (the acceptance pass landed as #274). Implements the issue's "MCPorter-based CLI projection" line in-house, per the recorded #107 gate G7 (no hard MCPorter dependency): the projection runs over the compiled route graph and invokes routes locally — zero new dependencies, no second command model. MCPorter remains usable independently against the generated MCP server as a live-server client.

What this adds

  • routes.mcpCommands: true | { include?, exclude? } — selects tools from generated MCP servers into the same collision-checked command graph and generated executable as src/cli/** routes, including standalone (no src/cli/** at all). Patterns match <server>:<tool> with literal text plus *; any pattern matching nothing (or include: []) fails compilation with new diagnostic AB4822 listing the available identities. Malformed config is AB4804; routes.cli: 'conventional' + mcpCommands is AB4804.
  • Projected command shape<bin> <server> <tool>, one optional --input '<JSON object>' (omitted → {}; invalid JSON/arrays/null/scalars → usage exit 2 before any route execution). The route's own zod inputSchema stays the single validation authority.
  • Fail-closed mutation gate — a tool is read-only only when its static MCP annotations.readOnlyHint === true; every other tool (missing or malformed annotations included) synthesizes a required --yes and exits 2 without executing the route when absent (proven by a side-effect-counting fixture tool).
  • Route-contract parity — projected commands render with invocation: { kind: 'tool', props: { input, operationId } } and request context { kind: 'tool', operationId, surface: <tool>, artifactEpoch }, identical to the generated MCP server; a parity test asserts CLI --json output equals the in-memory MCP structuredContent for identical input. All rendered output modes (Markdown/TTY progress/--json/--ndjson) come along for free from the shared shell.
  • Collision merge — projected paths/groups/aliases collide with custom CLI claims under the existing AB4813, with routes.mcpCommands.exclude recovery.
  • Provenancemcp: { server, tool, confirm } on compiled commands, surfaced through the test-manifest, dev route manifest, and Workbench's strict manifest decoder (schema extended; no UI changes).

Review notes

Local gates (merged with latest main)

  • typecheck clean; rslint 0 errors / 0 warnings (939 files)
  • unit 2454/0, route-unit 18/0, projection 57/0 (includes new cli-dispatch-mcp suite), packed CLI journey 1/0
  • changeset: agent-bundle minor

Compile selected generated MCP tools into the shared CLI graph with fail-closed mutation confirmation and route-contract parity.
# Conflicts:
#	packages/agent-bundle/tests/projection/mcp-in-memory.test.ts
@changeset-bot

changeset-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1e64e2c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agent-bundle Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@ScriptedAlchemy
ScriptedAlchemy merged commit f06a91c into main Sep 2, 2026
4 checks passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T04:34:12.570491Z 1e64e2c PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1e64e2c71e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +294 to +298
' if (command.mcp !== undefined) {',
' return openRenderedSession({',
" invocation: { kind: 'tool', props: { input: parsed, operationId: command.routeId } },",
' props: { input: parsed },',
` request: { artifactEpoch: ${JSON.stringify(generatedRouteArtifactEpoch(options.plugin))}, kind: 'tool', operationId: command.routeId, surface: command.mcp.tool },`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Mount MCP context providers in projected CLI runs

In the generated packed-CLI path, selecting this MCP branch still sends the tool through generatedRenderedRouteWorkerSource, whose runAgentRequest setup neither imports nor executes model.providers and does not install the framework processLifetime provider, unlike generatedRouteFlightWorkerSource. Consequently, a valid MCP tool that reads (await agent()).providers.projectAuth succeeds through its generated MCP server but sees a missing provider or fails when invoked through the new projected CLI; pass the compiled providers into this worker and mount them using the tool invocation before rendering.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in 5317ce619: generated rendered-route workers now receive the compiled provider registry, execute providers in deterministic key order with the existing fail-closed contract, mount processLifetime, and are fed providers by both routed CLI and rendered-script build paths. Merged via #319.

ScriptedAlchemy added a commit that referenced this pull request Sep 2, 2026
…tool scopes (#223) (#276)

* feat(runtime): observe transport identity in generated MCP request scopes (#223)

Generated MCP tool, resource, and prompt request scopes now observe the
negotiated client identity as a native host and derive workspace from the
server process cwd, alongside the existing native session and authInfo
actor, forwarding all four axes into the Flight worker. Typed
unavailability is preserved where a transport genuinely lacks an axis
(bare stdio supplies no sessionId or authInfo). The in-memory projection
level mirrors the worker boundary so mcp-in-memory stays faithful, with
the harness context seam still winning. Proof assertions flip from
honest absence to the positive contract at the generated-server
integration, mcp-in-memory, and packed journey levels; also repairs the
packed listTools assertion left stale when #273 added the context
fixture route.

* test(packed): reconcile packed listTools with the mutation-probe harness tool (#275)
@ScriptedAlchemy
ScriptedAlchemy deleted the feat/102-s4 branch September 2, 2026 04:53
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