mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-06 21:05:21 +02:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connections let people give agents access to external tools. > - A personal connection needs the current user's authorization. > - A new MCP URL must be probed before Paperclip can discover its sign-in method. > - Requiring a personal grant before that probe prevents sign-in from starting. > - This pull request permits the initial probe for a creator-owned draft with no credentials. > - People can complete personal setup while later requests retain authorization checks. ## Linked Issues or Issue Description **What happened?** Connecting an unknown MCP URL with "Just me" failed with HTTP 502 and "This connection needs the current user's authorization". Paperclip checked for a personal grant before contacting the provider. The health wrapper also changed the expected authorization error into a server error. **Expected behavior** Discover OAuth and start browser sign-in. Create a personal grant after consent. For a public endpoint, discover its tools and create the empty personal grant after a successful probe. Keep missing authorization on later health checks as HTTP 422. **Steps to reproduce** 1. Add an unknown remote MCP URL with no saved credentials. 2. Select "Just me". 3. Check the link. Before this fix, the request fails before sign-in or tool discovery. **Paperclip version or commit** The three original regressions fail against `6cfe4acff` with the service fix removed and pass with it restored. **Deployment mode** The defect was reported in production and reproduced in local server tests with isolated PostgreSQL. Related work: Refs #11831. Refs #11144. Searches found no duplicate fix. ## What Changed - Allow an initial credential-free probe only for the creating user's personal draft with unknown authentication and no supplied credentials. - Leave OAuth grant creation to the callback. Create an empty personal grant only after a public probe succeeds. - Preserve the personal grant for URLs that already contain a credential. - Make empty personal grant creation conflict-safe without overwriting a concurrent grant or duplicating its creation audit. - Commit the empty grant and audit atomically. Retain the established public draft identity after a later catalog failure, so a failed retry cannot remove a successful retry's grant. - Run the following catalog/default-profile step in its own transaction, so failures discard partial catalog, profile, binding, and audit changes without deleting the established identity. - Verify archived personal connections retain their owner: another user is rejected before probing, while the original owner can resume setup. - Preserve `user_authorization_required` and HTTP 422 in health failures. - Cover the connect and OAuth callback routes, real loopback HTTP, credential-bearing URLs, and later health checks. - Document personal setup and the test fixtures. ## Verification - Red/green: the original three tests failed with the exact reported error before the fix and passed after it. - The credential-bearing personal URL regression also failed before its guard was added. - Focused suite: `pnpm --filter @paperclipai/server exec vitest run src/__tests__/generic-mcp-connection.test.ts src/__tests__/tool-access-service.test.ts` passed all 385 tests across the two suites. An earlier run had a socket hang-up in an existing agent-permissions test; the unchanged suite passed on rerun. - The concurrent rollback regression failed before its fix because the successful retry's grant was deleted. It now verifies the grant and draft survive and a later normal health check succeeds. - Database fault injection during profile-entry insertion reproduced partial catalog writes before the transaction fix. The regression now verifies unchanged catalog rows, no partial profile/bindings, a retained grant, and successful retry. - CI's first serialized-server shard 3 attempt failed an existing peer-agent mutation test (the real run-context guard ran despite the test's mock). The test passed in isolation and all 108 tests in that suite passed unchanged locally. The single failed-shard rerun passed without code changes. - Final-commit CI: all 32 applicable checks passed on `639f037987352cab6084c4ebfa5dbf7b0aed6046`, including all 385 affected tests, the full test matrix, browser suite, build, typecheck, release checks, and security checks. The two Storybook-only checks were not applicable and skipped. Greptile is 5/5 with all review threads resolved. [Successful CI run](https://github.com/paperclipai/paperclip/actions/runs/35027478353). - `pnpm -r typecheck` passed. - `pnpm smoke:mcp-fixtures -- --require-paperclip` passed. - `pnpm build` passed. - Full local `pnpm test:run` was attempted: its general-server group finished with 12,372 passed, 4 failed, and 70 skipped tests. The run started before review edits; its two MCP failures used the old cached service (including an insert without the new conflict clause). All 385 focused tests pass on the final code. The other failures were existing workspace-cleanup and runtime-port tests; their unchanged suites passed on rerun (66 passed, and 25 passed/3 skipped). The local command stopped before later groups. The final-commit CI matrix is the full-suite merge gate; this local run is not claimed as green. ## Risks - The initial probe must not become a general authorization bypass. It is restricted to the creating user's draft. Normal health checks retain authorization enforcement. - Public endpoints get a personal grant with no secrets only after they answer successfully. Credential-bearing URLs keep their existing grant. - The concurrent-probe regression seeds the catalog and default profile to isolate grant creation. Existing first-time catalog/profile creation races are outside this change; this does not claim to make the entire setup flow concurrency-safe. - No database migration or UI change is required. OAuth tests use a simulated provider; the public endpoint test uses real loopback HTTP. ## Model Used OpenAI Codex, GPT-6-based assistant for regression tests and PR preparation; a GPT-5-based Codex assistant assisted with the initial implementation. Exact runtime model IDs and context-window sizes are not exposed in this session. Both used reasoning, repository tools, and code execution. ## 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 - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>