refactor(tools): drop 29 unused tool registrations (102→73) #2

Merged
Phil merged 10 commits from slim/tool-surface-2026-05-21 into main 2026-05-21 13:33:28 +00:00
Owner

Removes 29 unused tool registrations to reduce the MCP server's tool-schema footprint in the agent's context window (~7k tokens saved per session).

Removed:

  • tracking/ module (10): time-tracking + stopwatch APIs
  • org admin (3): create_org, edit_org, delete_org
  • org teams (6): list/create_org_team + add/remove team_member/team_repo
  • attachment cold (4): edit + delete × {issue, comment}
  • pull review cold (3): dismiss_pull_review, delete_pull_review, get_pull_review (single — list_pull_reviews covers it)

Preserved:

  • All issue / PR / repo / branch / file CRUD
  • Workflow runs, logs, dispatch, wait
  • Notifications + read state
  • Attachment hot path (list/get/download/create) — including PR #109 + auto-spill
  • Org read-only (get, list members, check membership, remove member)
  • create_repo + fork_repo (explicit keep)

Context: anthropics/claude-code#38044 — subagents inherit full MCP tool schemas without deferred loading. Less tool surface = more usable subagents.

Removes 29 unused tool registrations to reduce the MCP server's tool-schema footprint in the agent's context window (~7k tokens saved per session). **Removed:** - `tracking/` module (10): time-tracking + stopwatch APIs - org admin (3): `create_org`, `edit_org`, `delete_org` - org teams (6): `list/create_org_team` + `add/remove team_member/team_repo` - attachment cold (4): `edit` + `delete` × {issue, comment} - pull review cold (3): `dismiss_pull_review`, `delete_pull_review`, `get_pull_review` (single — `list_pull_reviews` covers it) **Preserved:** - All issue / PR / repo / branch / file CRUD - Workflow runs, logs, dispatch, wait - Notifications + read state - Attachment hot path (list/get/download/create) — including PR #109 + auto-spill - Org read-only (get, list members, check membership, remove member) - `create_repo` + `fork_repo` (explicit keep) Context: [anthropics/claude-code#38044](https://github.com/anthropics/claude-code/issues/38044) — subagents inherit full MCP tool schemas without deferred loading. Less tool surface = more usable subagents.
Phil added 10 commits 2026-05-21 13:33:23 +00:00
Three new MCP tools for debugging workflow-run failures without
leaving the agent loop:

- list_run_jobs: GET /repos/{o}/{r}/actions/runs/{id}/jobs
- get_run_logs:  GET /repos/{o}/{r}/actions/runs/{id}/logs
- get_job_logs:  GET /repos/{o}/{r}/actions/jobs/{id}/logs

The SDK's existing ListRepoActionJobs targets a different endpoint
(/actions/runners/jobs), so all three tools use pkg/forgejo's raw
HTTP helpers. Logs are capped at MaxInlineDownloadBytes (1 MiB);
ErrPayloadTooLarge maps to a clear hint to use get_job_logs.
Forgejo's REST v1 API does not expose action-run logs or artifacts; the
web UI fetches both from same-origin routes (no /api/v1 prefix) that
still accept "Authorization: token X" via Forgejo's auth middleware.

Reshape the toolset:
- Drop list_run_jobs entirely — Forgejo has no equivalent JSON endpoint;
  job lists are rendered into HTML, not exposed.
- get_run_logs + get_job_logs both hit
  GET /{owner}/{repo}/actions/runs/{run}/jobs/{job}/attempt/{attempt}/logs
  which returns text/plain. job_index defaults to 0 (single-job common
  case); attempt defaults to 1.

run_id in these tools is the URL-style run index (the N in
/actions/runs/N), matching the existing get_workflow_run convention,
NOT the run_number shown in the UI as "#962".
When an attachment exceeds MaxInlineDownloadBytes (1 MiB), the MCP
server now streams the bytes into DefaultSpillDir (~/.cache/forgejo-mcp/
attachments/<uuid>-<name>) and returns the on-disk path instead of
asking the caller to "fetch browser_download_url with token X" — which
the caller usually can't do because the token is intentionally not
visible to it (ADR-KV-018 token-discipline).

Bytes flow through the MCP server, never through Claude's context.
Agent receives only path + size + content-type and uses Read/Bash on
the resulting file.

pkg/forgejo gets a new DoRawToFile helper and a DefaultSpillDir helper
honouring XDG_CACHE_HOME.
Set ReturnRunInfo=true on the SDK call so Forgejo 14+ responds with
{id, run_number, jobs[]} instead of a bare 204. The tool now surfaces
the run id, run_number (= #N in the UI), and job names in its text
output, so callers can hand the id straight to get_workflow_run or
wait_for_run instead of racing list_workflow_runs by head_sha.

Older Forgejo (pre-return_run_info) still answers 204 — the SDK
errors on the empty JSON decode in that case; we catch that specific
error and fall back to the legacy success summary so the tool stays
backward-compatible.

Verified against forgejo.philflow.me v14.0.3:
  POST /api/v1/repos/Phil/flow.raven/actions/workflows/e2e-staging.yml/dispatches
  body {"ref":"dev","return_run_info":true}
  -> HTTP 201 {"id":1642,"run_number":1463,"jobs":["e2e"]}

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Forgejo v14.0.3 has no /api/v1/repos/{owner}/{repo}/actions/runs/{id}/jobs
endpoint (verified: 404), so discovering the jobs of a run required
brute-forcing get_run_logs(job_index=0,1,2…) until 404 — burning tool
calls and giving no metadata back.

list_run_jobs scans /api/v1/repos/{owner}/{repo}/actions/tasks (which
returns ALL recent repo tasks; per-run filter params are silently
ignored on v14) and matches client-side on the task URL suffix
/actions/runs/<run_number>. Default scan window: 500 tasks (10 pages
of 50) — covers ~24 h on raven-scale CI. max_scan_pages caller-tunable.

Accepts either run_number (preferred, UI-visible #N) or run_id
(database PK; resolved to a run_number first via GetRepoActionRun).

Output exposes task_id, name, status, event, workflow, started time,
duration, and the canonical run URL — enough to drive get_run_logs
and to triage failures without a follow-up tool call.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Block-and-wait companion to dispatch_workflow: polls get_workflow_run
on poll_interval_seconds (default 15 s) until the run reaches a
terminal status (success / failure / cancelled / skipped) or
timeout_seconds elapses (default 1800 s = 30 min, sized for full
e2e runs).

Respects ctx cancellation so the agent can abort the wait mid-stream.
The mark3labs/mcp-go stdio transport has no read-timeout, so the only
ceiling is the tool's own sleep budget — safe to wait the full 30 min
without the MCP framework cutting the response.

initial_delay_seconds (default 2) gives Forgejo's scheduler a beat
to pick the run up after dispatch_workflow so the first poll sees a
real status, not the transient "waiting".

Final output mirrors get_workflow_run's payload plus an explicit
Conclusion: <status> line for trivial caller parsing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Forgejo v14's /actions/runs endpoint accepts a `sort` query param but
silently ignores it — page 1 against forgejo.philflow.me returned runs
from 2026-04 first instead of newest. Sort runs client-side after the
SDK call (created_desc default; created_asc and "none" also accepted).

Also adds a created_after RFC3339 filter, applied client-side for the
same reason — useful for "show me runs since the latest deploy".

Each result line now exposes BOTH `id` (database PK, the input to
get_workflow_run / wait_for_run) and `run_number` (UI-visible #N,
the input to list_run_jobs and web URLs). Surface clarifications in
both tool descriptions: these are distinct numbers, not aliases.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The web log route returns a generic "Not found." for three distinct
failure modes — wrong run number, job index out of range, log expired
or unreachable. The previous error couldn't differentiate, costing
tool calls during triage.

On 404 the tool now:
  1. Probes GetRepoActionRun(runID) — if it hits, the caller passed a
     database id where a run_number was needed; we surface the actual
     run_number so they can retry.
  2. Enumerates /actions/tasks and matches on the URL suffix to count
     jobs in the run. If job_index >= count, returns "out of range,
     valid 0..N-1, names=[...]".
  3. Otherwise explains the Forgejo v14 bearer-token-vs-session-cookie
     limitation on web routes and points at the working artifact
     workaround (workflow uploads -> issue attachment -> triage agent
     pulls via download_issue_attachment).

Also documents the dead-end status of /actions/runs/{N}/jobs/.../logs
under bearer auth on v14, with the v16 + forgejo#12140 reference.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Forgejo v14.0.3 has no token-authenticatable artifact endpoint —
verified against forgejo.philflow.me across every REST + web path
variant. forgejo#12140 lands the proper HTTP API in v16; until the
production instance moves there, shipping a stub tool would be worse
than no tool at all (the agent would keep calling and failing).

Documents the current workflow-upload + issue-attachment workaround
that's actually working in production, and the implementation sketch
for when v16 arrives.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Removes registration of tools that are never used in Phils workflows
to reduce the MCP server's tool-schema footprint in the agent's context
window.

Tool surface: 102 -> 73 (-29 tools, ~7k tokens saved per session).

Removed:
- tracking module (10): time-tracking + stopwatch APIs
- org admin (3): create_org, edit_org, delete_org
- org teams (6): list/create_org_team + add/remove team_member/team_repo
- attachment cold (4): edit + delete x {issue, comment}
- pull review cold (3): dismiss_pull_review, delete_pull_review,
  get_pull_review (single — list_pull_reviews covers it)
- search_org_teams (1) — not in registry, was already inert

Behaviour preserved:
- All issue / PR / repo / branch / file CRUD
- Workflow runs, logs, dispatch, wait
- Notifications + read state
- Attachment hot path (list/get/download/create) — including Phils
  PR #109 attachment feature + auto-spill
- Org read-only (get, list members, check membership, remove member)
- create_repo + fork_repo explicitly kept (Phil-decision)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Phil merged commit 830447f7e8 into main 2026-05-21 13:33:28 +00:00
Phil deleted branch slim/tool-surface-2026-05-21 2026-05-21 13:33:28 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
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
Phil/forgejo-mcp!2
No description provided.