feat(agents): McpRegistryPort + DefaultMcpRegistry adapter #527

Merged
charles merged 1 commit from boss/516 into main 2026-04-28 13:51:36 +00:00
Collaborator

Summary

Extracts the MCP-server / allowedTools assembly out of agent-runner.ts and foreman.ts into a hexagonal port + adapter pair (M25 / #516), so every dispatch path consults a single source of truth for forge selection (MF-1/2/5), the dual-mount flag (MF-5), and per-forge token injection (MF-4).

  • New port domain/ports/mcp-registry-port.ts exposing serversFor(agent, binding) + allowedTools(agent, binding) over a minimal structural AgentInstance (subset of ResolvedAgent and WorkerConfig).
  • New adapter infrastructure/agents/default-mcp-registry.ts carrying the Forgejo dual-mount, the FORGE_TYPE/token wiring, and the mcp__penpot__* allowlist gate; a dualMount: false config flip is the single switch for the MF-5 cutover.
  • agent-runner.ts and foreman.ts now build their MCP servers + tool allowlist through the adapter; mcp-config.ts constants stay in place until every callsite migrates.

Closes #516

Test plan

  • bun x turbo run test — 2458 pass / 0 fail (incl. 13 new default-mcp-registry.test.ts cases for forge selection, MF-5 dual-mount, penpot gating, base allowlist, legacy fallback)
  • bun x turbo run typecheck — clean across all 4 workspaces
  • bun x @biomejs/biome@^2 check . / format . — clean (the 2 remaining infos are pre-existing in workdir.test.ts)

🤖 Generated with Claude Code

## Summary Extracts the MCP-server / `allowedTools` assembly out of `agent-runner.ts` and `foreman.ts` into a hexagonal port + adapter pair (M25 / #516), so every dispatch path consults a single source of truth for forge selection (MF-1/2/5), the dual-mount flag (MF-5), and per-forge token injection (MF-4). - New port `domain/ports/mcp-registry-port.ts` exposing `serversFor(agent, binding)` + `allowedTools(agent, binding)` over a minimal structural `AgentInstance` (subset of `ResolvedAgent` and `WorkerConfig`). - New adapter `infrastructure/agents/default-mcp-registry.ts` carrying the Forgejo dual-mount, the `FORGE_TYPE`/token wiring, and the `mcp__penpot__*` allowlist gate; a `dualMount: false` config flip is the single switch for the MF-5 cutover. - `agent-runner.ts` and `foreman.ts` now build their MCP servers + tool allowlist through the adapter; `mcp-config.ts` constants stay in place until every callsite migrates. Closes #516 ## Test plan - [x] `bun x turbo run test` — 2458 pass / 0 fail (incl. 13 new `default-mcp-registry.test.ts` cases for forge selection, MF-5 dual-mount, penpot gating, base allowlist, legacy fallback) - [x] `bun x turbo run typecheck` — clean across all 4 workspaces - [x] `bun x @biomejs/biome@^2 check .` / `format .` — clean (the 2 remaining infos are pre-existing in `workdir.test.ts`) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(agents): McpRegistryPort + DefaultMcpRegistry adapter
All checks were successful
qa / qa (pull_request) Successful in 12m32s
qa / dockerfile (pull_request) Successful in 15s
899073aead
Extracts the MCP-server / allowedTools assembly out of agent-runner.ts and
foreman.ts into a hexagonal port + adapter pair so dispatch paths consult a
single source of truth for forge selection, the MF-5 dual-mount flag, and
per-forge token injection.

Closes #516

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
reviewer approved these changes 2026-04-28 11:18:28 +00:00
reviewer left a comment

Port interface, adapter, and both migration sites are correct — forge selection, dual-mount flag, and per-forge token isolation all verified; 13 unit tests cover the required AC scenarios plus edge cases (GitLab, penpot gating, back-compat fallback, reconfigure()), CI green (run #2474).

Nit not worth blocking: the AC text says McpServerSpec should come from domain/agent/types.ts, but it's redeclared in the port file; the self-contained approach is sound (keeps the port from importing infrastructure types), though worth noting if a shared type location gets formalised in a later M25 issue.

Port interface, adapter, and both migration sites are correct — forge selection, dual-mount flag, and per-forge token isolation all verified; 13 unit tests cover the required AC scenarios plus edge cases (GitLab, penpot gating, back-compat fallback, `reconfigure()`), CI green (run #2474). Nit not worth blocking: the AC text says `McpServerSpec` should come from `domain/agent/types.ts`, but it's redeclared in the port file; the self-contained approach is sound (keeps the port from importing infrastructure types), though worth noting if a shared type location gets formalised in a later M25 issue.
Author
Collaborator

Rebase aborted — design superseded on main.

origin/main already carries McpRegistryPort + DefaultMcpRegistry (commit ef7b74e) with a different shape:

  • main aliases AgentInstance = ResolvedAgent (wide); this PR uses a narrow structural interface (name/type/forgejo_token/tokens/penpot_mcp).
  • main's adapter reads agent.token; this PR reads agent.forgejo_token.
  • main's config flag is mf5DualMount; this PR's is dualMount.
  • main keeps agent-runner.ts/foreman.ts on buildMcpSetup; this PR migrates them, passing WorkerConfig which doesn't structurally satisfy main's AgentInstance = ResolvedAgent.

Add/add conflicts on mcp-registry-port.ts, default-mcp-registry.ts, and the test file aren't resolvable without re-engineering either the port surface or the call-sites — both are design decisions, not rebase work.

Recommend closing this PR. The remaining value (migrating agent-runner.ts + foreman.ts callsites onto main's port) should land as a fresh issue against the now-merged port shape.

Rebase aborted — design superseded on `main`. `origin/main` already carries `McpRegistryPort` + `DefaultMcpRegistry` (commit `ef7b74e`) with a different shape: - main aliases `AgentInstance = ResolvedAgent` (wide); this PR uses a narrow structural interface (`name`/`type`/`forgejo_token`/`tokens`/`penpot_mcp`). - main's adapter reads `agent.token`; this PR reads `agent.forgejo_token`. - main's config flag is `mf5DualMount`; this PR's is `dualMount`. - main keeps `agent-runner.ts`/`foreman.ts` on `buildMcpSetup`; this PR migrates them, passing `WorkerConfig` which doesn't structurally satisfy main's `AgentInstance = ResolvedAgent`. Add/add conflicts on `mcp-registry-port.ts`, `default-mcp-registry.ts`, and the test file aren't resolvable without re-engineering either the port surface or the call-sites — both are design decisions, not rebase work. Recommend closing this PR. The remaining value (migrating `agent-runner.ts` + `foreman.ts` callsites onto main's port) should land as a fresh issue against the now-merged port shape.
code-lead force-pushed boss/516 from 899073aead
All checks were successful
qa / qa (pull_request) Successful in 12m32s
qa / dockerfile (pull_request) Successful in 15s
to 7b9e522948
All checks were successful
qa / qa (pull_request) Successful in 13m7s
qa / dockerfile (pull_request) Successful in 14s
2026-04-28 11:26:15 +00:00
Compare
code-lead force-pushed boss/516 from 7b9e522948
All checks were successful
qa / qa (pull_request) Successful in 13m7s
qa / dockerfile (pull_request) Successful in 14s
to 2714a8c07b
Some checks are pending
qa / qa (pull_request) Waiting to run
qa / dockerfile (pull_request) Waiting to run
2026-04-28 13:39:18 +00:00
Compare
code-lead force-pushed boss/516 from 2714a8c07b
Some checks are pending
qa / qa (pull_request) Waiting to run
qa / dockerfile (pull_request) Waiting to run
to 2db7a19a9f
Some checks failed
qa / dockerfile (pull_request) Has been cancelled
qa / qa (pull_request) Has been cancelled
2026-04-28 13:44:15 +00:00
Compare
charles deleted branch boss/516 2026-04-28 13:51:38 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks!527
No description provided.