mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-16 15:15:35 +02:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Apps give those agents governed access to external tools. > - Remote MCP setup needs secure endpoint validation and durable credentials. > - PostHog needs both browser sign-in and personal API key setup paths. > - This pull request adds the shared remote MCP foundation and the PostHog definition. > - The benefit is a secure and reusable base for later app connection work. ## Linked Issues or Issue Description Refs #11965 This is stack 1 of 11. It replaces the first reviewable part of #11965. ## What Changed - Add guarded remote MCP setup and credential handling. - Add PostHog OAuth and API key connection methods. - Add focused server, shared contract, and UI coverage. - Keep the migration replay-safe and idempotent. - Give the late-close security regression the same 10-second CI headroom as the adjacent real-timer handshake test. - Synchronize fake-timer handshake tests at the exact ensure-session boundary so real filesystem setup cannot race the fake deadline. - Drive PTY overflow coverage only after listener registration so scheduling cannot reorder the test fixture. ## Verification - pnpm exec vitest run packages/adapter-utils/src/acpx-engine/execute.test.ts server/src/__tests__/plugin-worker-manager.test.ts (220 passed; affected cases also passed five focused stress repetitions) - `pnpm exec vitest run packages/adapter-utils/src/acpx-engine/execute.test.ts -t "never leaks a sandbox-provided value from a late close rejection into logs or the result"` (1 passed) - `pnpm exec vitest run packages/adapter-utils/src/acpx-engine/execute.test.ts -t "never promotes a late ensureSession resolution|closes a late-resolving real handle exactly once"` (2 passed) - `pnpm -r typecheck` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/tool-access-service.test.ts` - `pnpm --filter @paperclipai/db check:migrations` - `pnpm build` ## Risks - Remote endpoint validation can reject configurations that previously passed without checks. - OAuth configuration errors can block setup until the operator corrects the provider settings. - The migration uses guarded statements so repeated execution is safe. - The test-only synchronization changes do not affect runtime behavior; they remove filesystem/fake-clock and listener-registration races observed under parallel CI load. > I checked `ROADMAP.md`. This stack continues the existing app connection work from #11965 and does not duplicate another planned item. ## Model Used OpenAI Codex, GPT-5. The runtime model ID and context window were not exposed. The model used reasoning, tool use, 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 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>
31 lines
1.6 KiB
TypeScript
31 lines
1.6 KiB
TypeScript
import { checkOAuthEndpointUrl, oauthEndpointUrlRejectionMessage } from "@paperclipai/shared";
|
|
|
|
export type AuthorizationTarget =
|
|
| { ok: true; url: string; host: string }
|
|
| { ok: false; message: string };
|
|
|
|
/**
|
|
* Vet an authorization URL before it becomes a top-level navigation (PAP-17099).
|
|
*
|
|
* The server already refuses to hand out an unsafe endpoint, but this is the
|
|
* boundary where a bad value would actually execute — `window.location.assign`
|
|
* on a `javascript:` URL runs script in the board's origin — so the board checks
|
|
* the same rules with the same shared validator rather than trusting the
|
|
* response body it just received.
|
|
*/
|
|
export function resolveAuthorizationTarget(value: string | null | undefined): AuthorizationTarget {
|
|
const servedOverHttp = typeof window !== "undefined" && window.location.protocol === "http:";
|
|
const check = checkOAuthEndpointUrl(value ?? null, {
|
|
// A board served over plaintext HTTP is a local-development board, where a
|
|
// loopback authorization server is exactly what someone is testing against.
|
|
// A board served over HTTPS requires HTTPS.
|
|
allowInsecureLoopback: servedOverHttp,
|
|
// Paperclip's own origin: a first-party authorization endpoint (the smoke-lab
|
|
// fixture) is served however the board is, and going to the page you are
|
|
// already on adds no exposure.
|
|
allowInsecureOrigins: typeof window !== "undefined" ? [window.location.origin] : [],
|
|
});
|
|
if (check.ok) return { ok: true, url: check.url, host: check.host };
|
|
return { ok: false, message: oauthEndpointUrlRejectionMessage("authorization", check.reason) };
|
|
}
|