Files
PaperClipAI/doc/connection-intents.md
T
DottaandPaperclip b3343dbd64 feat(connections): add self-serve intent runtime (#12345)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents need a governed way to request app connections during issue
work.
> - The catalog now describes the available providers and setup methods.
> - A request must become a durable, company-scoped intent before an
operator acts on it.
> - This pull request adds that intent runtime across server, agent,
CLI, and shared contracts.
> - The benefit is a safe bridge from agent need to operator-approved
setup.

## Linked Issues or Issue Description

Refs #11965

This is stack 7 of 11. It depends on stack 6 and replaces another
reviewable part of #11965.

## What Changed

- Add connection intent types, validation, service logic, and routes.
- Add agent runtime tools and CLI support for connection requests.
- Add issue-thread interaction support for connection intents.
- Add runtime, route, adapter, and contract tests.
- Hold the final resolved-continuation row lock through asynchronous
adapter preparation until an actual process spawn, so parking or
reassignment cannot cross that boundary.
- Report Hermes Gateway's first remote run request through the shared
dispatch hook so the resolved-intent lock is released at the true
dispatch boundary.
- Revalidate the addressed user's live non-viewer membership and
connection-management authority for every intent mutation, including
OAuth completion.

## Verification

- `pnpm --filter @paperclipai/server typecheck`
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/tool-access-service.test.ts`
- Result: 176 tests passed.
- `pnpm build`
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-stale-queue-invalidation.test.ts` (32 passed;
includes non-process dispatch lock-release coverage)
- `pnpm exec vitest run --project @paperclipai/server
server/src/__tests__/connection-intents-service.test.ts -t
"addressed-user mutation"` (1 passed)
- `pnpm exec vitest run --project @paperclipai/server
server/src/__tests__/tool-access-service.test.ts -t "binds OAuth
callback completion to the initiating board session"` (1 passed)
- `pnpm --filter @paperclipai/hermes-paperclip-adapter test --
src/gateway/server/execute.test.ts` (23 passed; includes dispatch-hook
ordering and exactly-once coverage)
- `pnpm --filter @paperclipai/hermes-paperclip-adapter typecheck`

## Risks

- A malformed intent could create an unusable operator request.
- Validators and company checks reject invalid or cross-company
requests.
- The final continuation gate holds the issue row lock through adapter
preparation until process or remote dispatch; later operator changes use
the normal active-run interruption path.
- The change does not add a database migration.

> 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 linked the public source pull request with `Refs #`
- [x] I have not referenced internal or instance-local Paperclip issues
or links
- [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>
2026-08-29 12:08:34 -05:00

3.6 KiB

Connection intents

Connection intents let an agent ask the responsible user for a known service connection without leaving the task thread. The user can reuse an eligible connection or run the normal provider setup in a dialog. A successful resolution grants and installs the connection for the requesting agent, then wakes the task assignee in a fresh run.

Shared setup flow

ui/src/features/connections/ConnectionSetupFlow.tsx is the only connection setup implementation. It owns provider selection, method and identity choices, provider fields, validation, OAuth, access, catalog setup, installs, retry states, and completion. It has two presentation hosts:

  • ui/src/pages/apps/AppsConnect.tsx supplies full-page routing and breadcrumbs.
  • ui/src/features/connections/ConnectionIntentInteractionBody.tsx supplies the task dialog, intent resolution, query invalidation, and focus return.

Provider-specific setup must stay in the shared feature and AppDefinition metadata. Do not add provider forms or connection mutations to either host.

Agent tools

Every active heartbeat with a responsible user receives two run-bound tools:

  • connections_search({ query }) searches first-party connectable definitions and returns ready, needs_user_action, available, or unavailable from the requesting agent's perspective.
  • connection_request({ service }) returns immediately when the service is already usable. Otherwise it creates or reuses a connection_intent and instructs the agent to end the run pending continuation.

Claude and Codex receive the tools through a native managed MCP server. Local/process adapters receive PAPERCLIP_RUNTIME_TOOLS_* environment variables and CLI guidance. Cloud, HTTP, gateway, and external adapters receive the typed runtime descriptor in their invocation context; compatible adapters may also project it into their remote environment.

The equivalent CLI helpers are:

paperclipai connections search notion
paperclipai connections request notion

The manually configured Paperclip MCP server also advertises connections_search and connection_request. Both helper surfaces require the narrow runtime token and fail outside an active heartbeat.

Security and lifecycle

  • Company, agent, run, task, and responsible user come only from the signed runtime token and stored heartbeat context.
  • Tokens are scoped to connection intents, expire after one hour, and are rejected when the heartbeat is no longer running.
  • The thread payload contains only service identity, requesting-agent identity, and a safe phase. It never contains credentials or authorization URLs.
  • OAuth state is linked to the interaction. The same-origin callback finalizes the existing connection pipeline, posts only interaction ID/outcome to its opener, and redirects back to the task if there is no opener.
  • Personal OAuth defaults to the addressed user and creates an explicit delegation to the requesting agent. Reuse and installs are additive.
  • Task-hosted setup locks install reach to the requesting agent; the store host retains its normal broader access choices.
  • The intent resolves only after the connection, grant/delegation, profile access, and install succeed. Failures remain pending with needs_retry.
  • Closing the task, a newer run requesting the same service, or a newer human task comment expires the intent and deletes linked OAuth state.
  • Success and decline wake the assignee once using an interaction-and-status idempotency key and force a fresh continuation session.

Legacy request_confirmation.payload.connectionAuthorization interactions remain readable and resolvable. New agent requests use connection_intent exclusively.