FM-4 — sync FORGE_TOOLS_ALLOWLIST with real forge-mcp tool names #808

Closed
opened 2026-05-03 20:08:05 +00:00 by claude-desktop · 0 comments
Collaborator

As an operator, I want FORGE_TOOLS_ALLOWLIST in apps/server/src/domain/agent/mcp-config.ts to list the names that apps/forge-mcp/src/tools.ts actually registers, so that agents in containers can invoke mcp__forge__* tools instead of getting "tool not found" from the SDK allowlist filter and falling back to curl with $FORGEJO_ACCESS_TOKEN.

Context — why this is broken today

FM-3 (#687, 2026-05-01) cut over to forge-mcp (FM-2 hand-rolled bun stdio server, apps/forge-mcp/src/). forge-mcp registers tools by their short names (get_issue, list_issues, list_pull_requests, submit_review, request_reviewers, read_file, create_comment, …). forge-mcp/src/main.ts:53 does a strict byName.get(name) lookup with no aliasing. Meanwhile FORGE_TOOLS_ALLOWLIST (apps/server/src/domain/agent/mcp-config.ts:75-96) still carries legacy forgejo-mcp names copied from MF-5: get_issue_by_index, list_repo_issues, list_repo_pull_requests, get_pull_request_by_index, list_pull_reviews, create_review_requests, delete_review_requests, get_file_content, create_issue_comment, list_issue_comments. 11 of 17 names mismatch. The SDK's allowedTools filter rejects every call to a real forge-mcp verb. Result: agents have no working forge MCP path and curl-fall-back via $FORGEJO_ACCESS_TOKEN (which container-reconcile.ts:398 injects).

This story closes the allowlist drift only. Server-side rename (FM-5) and dualMount rip (FM-6) follow.

Acceptance criteria

Allowlist sync

  • Every entry in FORGE_TOOLS_ALLOWLIST (apps/server/src/domain/agent/mcp-config.ts) matches a name: field exported from apps/forge-mcp/src/tools.ts buildTools().
  • Mapping (legacy → forge-mcp short name) follows the table in specs/forge-mcp-cutover-followup.md §"Pass 1":
    • get_issue_by_indexget_issue
    • list_repo_issueslist_issues
    • list_issue_commentslist_comments
    • create_issue_commentcreate_comment
    • list_repo_pull_requestslist_pull_requests
    • get_pull_request_by_indexget_pull_request
    • list_pull_reviewslist_reviews
    • submit_pull_reviewsubmit_review
    • create_review_requestsrequest_reviewers
    • delete_review_requestsremove_review_request
    • get_file_contentread_file
    • update_issue, add_issue_labels, remove_issue_labels, create_issue, merge_pull_request, create_pull_request, list_repo_labels, list_workflow_runs, get_workflow_run, list_pull_request_files retained verbatim.

Tests

  • New unit assertion in mcp-config.test.ts: every name in FORGE_TOOLS_ALLOWLIST is present in the set returned by buildTools() from apps/forge-mcp/src/tools.ts. Cross-package import is fine — same monorepo. The test fails closed if forge-mcp drops or renames a verb.
  • Existing mcp-config.test.ts assertions covering buildMcpSetup keep passing.

Manual smoke

  • After landing, dispatch a real ticket. Task transcript shows at least one mcp__forge__* tool call (e.g. mcp__forge__get_issue, mcp__forge__create_pull_request). No mcp__forgejo__* tool calls — those will fail because the binary is gone, but they should not be attempted in this story (server-side instructions still emit them; that is FM-5's job to fix).

Out of scope

  • Renaming server-side mcp__forgejo__* references in parent-pr.ts, architect.ts, agent-runner.ts, worker.ts — see FM-5.
  • Removing dualMount, forgejoMcpCommand, FORGEJO_TOOLS_ALLOWLIST, FORGEJO_MCP_TOOLS env wiring — see FM-6.
  • Adding new tools to forge-mcp — every verb the agents use today already exists.

References

  • Spec: specs/forge-mcp-cutover-followup.md §Pass 1.
  • Tool registry: apps/forge-mcp/src/tools.ts:200-583 (name: fields).
  • Current allowlist: apps/server/src/domain/agent/mcp-config.ts:75-96.
  • forge-mcp dispatch (no aliasing): apps/forge-mcp/src/main.ts:53.
  • Parent spec: specs/forge-mcp-multi-forge.md.
  • Original FM-3 PR: #687.
As an operator, I want `FORGE_TOOLS_ALLOWLIST` in `apps/server/src/domain/agent/mcp-config.ts` to list the names that `apps/forge-mcp/src/tools.ts` actually registers, so that agents in containers can invoke `mcp__forge__*` tools instead of getting "tool not found" from the SDK allowlist filter and falling back to curl with `$FORGEJO_ACCESS_TOKEN`. ## Context — why this is broken today FM-3 (#687, 2026-05-01) cut over to `forge-mcp` (FM-2 hand-rolled bun stdio server, `apps/forge-mcp/src/`). `forge-mcp` registers tools by their **short names** (`get_issue`, `list_issues`, `list_pull_requests`, `submit_review`, `request_reviewers`, `read_file`, `create_comment`, …). `forge-mcp/src/main.ts:53` does a strict `byName.get(name)` lookup with no aliasing. Meanwhile `FORGE_TOOLS_ALLOWLIST` (`apps/server/src/domain/agent/mcp-config.ts:75-96`) still carries **legacy forgejo-mcp names** copied from MF-5: `get_issue_by_index`, `list_repo_issues`, `list_repo_pull_requests`, `get_pull_request_by_index`, `list_pull_reviews`, `create_review_requests`, `delete_review_requests`, `get_file_content`, `create_issue_comment`, `list_issue_comments`. 11 of 17 names mismatch. The SDK's `allowedTools` filter rejects every call to a real `forge-mcp` verb. Result: agents have no working forge MCP path and curl-fall-back via `$FORGEJO_ACCESS_TOKEN` (which `container-reconcile.ts:398` injects). This story closes the allowlist drift only. Server-side rename (FM-5) and dualMount rip (FM-6) follow. ## Acceptance criteria ### Allowlist sync - [ ] Every entry in `FORGE_TOOLS_ALLOWLIST` (`apps/server/src/domain/agent/mcp-config.ts`) matches a `name:` field exported from `apps/forge-mcp/src/tools.ts` `buildTools()`. - [ ] Mapping (legacy → forge-mcp short name) follows the table in `specs/forge-mcp-cutover-followup.md` §"Pass 1": - [ ] `get_issue_by_index` → `get_issue` - [ ] `list_repo_issues` → `list_issues` - [ ] `list_issue_comments` → `list_comments` - [ ] `create_issue_comment` → `create_comment` - [ ] `list_repo_pull_requests` → `list_pull_requests` - [ ] `get_pull_request_by_index` → `get_pull_request` - [ ] `list_pull_reviews` → `list_reviews` - [ ] `submit_pull_review` → `submit_review` - [ ] `create_review_requests` → `request_reviewers` - [ ] `delete_review_requests` → `remove_review_request` - [ ] `get_file_content` → `read_file` - [ ] `update_issue`, `add_issue_labels`, `remove_issue_labels`, `create_issue`, `merge_pull_request`, `create_pull_request`, `list_repo_labels`, `list_workflow_runs`, `get_workflow_run`, `list_pull_request_files` retained verbatim. ### Tests - [ ] New unit assertion in `mcp-config.test.ts`: every name in `FORGE_TOOLS_ALLOWLIST` is present in the set returned by `buildTools()` from `apps/forge-mcp/src/tools.ts`. Cross-package import is fine — same monorepo. The test fails closed if forge-mcp drops or renames a verb. - [ ] Existing `mcp-config.test.ts` assertions covering `buildMcpSetup` keep passing. ### Manual smoke - [ ] After landing, dispatch a real ticket. Task transcript shows at least one `mcp__forge__*` tool call (e.g. `mcp__forge__get_issue`, `mcp__forge__create_pull_request`). No `mcp__forgejo__*` tool calls — those will fail because the binary is gone, but they should not be attempted in this story (server-side instructions still emit them; that is FM-5's job to fix). ## Out of scope - Renaming server-side `mcp__forgejo__*` references in `parent-pr.ts`, `architect.ts`, `agent-runner.ts`, `worker.ts` — see **FM-5**. - Removing `dualMount`, `forgejoMcpCommand`, `FORGEJO_TOOLS_ALLOWLIST`, `FORGEJO_MCP_TOOLS` env wiring — see **FM-6**. - Adding new tools to `forge-mcp` — every verb the agents use today already exists. ## References - Spec: `specs/forge-mcp-cutover-followup.md` §Pass 1. - Tool registry: `apps/forge-mcp/src/tools.ts:200-583` (`name:` fields). - Current allowlist: `apps/server/src/domain/agent/mcp-config.ts:75-96`. - forge-mcp dispatch (no aliasing): `apps/forge-mcp/src/main.ts:53`. - Parent spec: `specs/forge-mcp-multi-forge.md`. - Original FM-3 PR: #687.
Sign in to join this conversation.
No project
No assignees
1 participant
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#808
No description provided.