mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-13 15:55:46 +01:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Native OpenCode agents use Paperclip tools through a local MCP bridge in the runner > - OpenCode 1.18 connects each MCP server one time per process. It does not retry > - One failed `initialize` or `tools/list` at startup marks the Paperclip server "failed" for the full session > - The agent then works with only built-in tools. In one chat it told the person "Switched the working design to blue", but no saved state supported this claim > - This pull request makes the runner confirm the Paperclip tools while the session loads, reconnect them, restart OpenCode if necessary, and fail the session by name if the tools stay unavailable > - The benefit is that an OpenCode turn never starts without its Paperclip tools, so the agent cannot silently claim actions that it could not do ## Linked Issues or Issue Description Refs #20886, #20921. **What happened** In chat eval `steering.steer-active` (private paid run 43086418488, on a commit with #20886 and without #20921), two of three OpenCode sessions started without Paperclip tools. One was the CEO chat (fresh session). One was the worker task after its saved session resumed in a new OpenCode process. The CEO agent ran `opencode mcp list` and saw `paperclip ✗ failed — Failed to get tools`. It then sent a request to the bridge without the bearer token and got HTTP 401. That 401 came from its own probe, not from OpenCode. The run still succeeded with the reply "Switched the working design to blue …", because a plain chat reply counts as the result. **Expected behavior** Every native OpenCode session starts with the Paperclip MCP tools. If the tools cannot be loaded, the session fails with a named reason, and the turn does not start without tools. **Steps to reproduce** 1. Start OpenCode 1.18.34 with a remote MCP server whose first `tools/list` request fails (for example, the server resets the socket one time). 2. `GET /mcp` returns `{"paperclip":{"status":"failed","error":"Failed to get tools"}}`. OpenCode keeps this status for the life of the process. 3. `POST /mcp/paperclip/connect` returns `true`, and then `GET /mcp` returns `connected` (about 8 ms). We measured this with the real 1.18.34 binary. This is the same class as #20886: `Connection: close` made the one-shot startup connect fail more often (about 9 of 25 sessions), and #20921 removed the trigger. Any other transient failure at startup still produced a toolless session. This change removes the class. ## What Changed - `opencode-server-driver.ts`: while a session opens (fresh, resumed or recovered), the driver reads OpenCode's `GET /mcp`. If the `paperclip` server is not `connected`, it calls `POST /mcp/paperclip/connect` up to two times. If the server is still not connected, it throws `paperclip_tools_unavailable`. The existing startup retry restarts OpenCode for this error (three attempts in total). After that, the session fails visibly. - The check runs in parallel with session creation or resume. The added work on a healthy start is one local HTTP request. - `fake-opencode-server.mjs`: the fixture now serves `GET /mcp` and `POST /mcp/paperclip/connect`. It connects to the real bridge with the configured token, and it can simulate failed connects. - New `paperclip-tools-startup.test.ts`: reconnect after one failed connect, restart after a process stays failed, reconnect on a saved session that resumes in a new process, and a named failure when the tools never load. All four tests fail on master (master opens a toolless session). ## Verification - `pnpm exec vitest run src/drivers/opencode/paperclip-tools-startup.test.ts` (in `packages/paperclip-runner`): 4 passed. Red on master: 4 failed. - All OpenCode driver, proxy, live runnerd OpenCode and native-runtime server suites that use the fixture: 29 files, 567 tests passed. - `node --test scripts/contracts/contract-fingerprints.test.mjs`: 11 passed. `tsc --noEmit -p packages/paperclip-runner`: clean. - Real OpenCode 1.18.34 probe (failure, then `connect`, then `connected`) as in the steps above. - Paid chat eval run 43117909094 on this change (steering.steer-active and three other OpenCode chat cases). Result is in a comment on this PR. ## Risks - Low. A healthy start adds one local `GET /mcp` request, in parallel with session creation. - If OpenCode cannot load the Paperclip tools after reconnects and restarts, the session now fails with `paperclip_tools_unavailable`. Before, it ran without tools. This is intended. - No persisted run, session or pack state changes. A session saved by the previous release resumes through the same open path and gets the same check. ## Model Used - Anthropic Claude Opus 5.5 (`claude-opus-5-5`), agentic coding with tool use (shell, file edits, GitHub CLI). ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>