Files
PaperClipAI/maps/feature-map/connection-setup.md
T
Devin FoleyandPaperclip 0b62c736a0 feat(connections): add generic Daytona API and Toolbox access (#16483)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Apps connections give agents controlled access to external services.
> - Daytona provides sandbox, file, command, Git, and account APIs.
> - Operators need to assign this access without exposing a server
credential.
> - A small task-specific tool list cannot serve general Daytona work.
> - This pull request adds the published HTTP actions through the
existing connection gateway.
> - Operators keep control of identity, agent access, and each action.

## Linked Issues or Issue Description

**Problem or motivation**

Paperclip has a Daytona sandbox provider for its own execution
infrastructure. It lacks a normal Apps connection for agents to manage
an operator's Daytona account. Reusing the server's provider credential
would bypass normal connection ownership and action permissions.

**Proposed solution**

Add a Daytona connection with personal or shared vault credentials.
Generate its action catalog from the official platform and Toolbox API
specifications. Use the existing run-bound gateway, grants, action
policies, approvals, revocation, and audit paths. Sandbox IDs come from
Daytona; tools need no Paperclip task or lease ID.

**Alternatives considered**

A four-action diagnostic subset cannot support general provider work.
Launching the provider CLI would expose host filesystem behavior. Native
OAuth is not included because a supported third-party registration path
was not verified. The native method uses an organization API key.
Existing Composio setup is a separate possible OAuth route and is not
qualified by this change.

**Roadmap alignment**

This extends the existing Apps and Connections provider coverage in
`ROADMAP.md`. It uses that system's credential and permission model.
GitHub searches found no existing Daytona Apps connector PR or issue.

## What Changed

- Add the Daytona catalog entry, provider source override, official
theme logos, permission review, and setup documentation.
- Generate 274 HTTP actions: 169 platform and 105 Toolbox operations.
Record two WebSocket upgrades separately; do not advertise them as HTTP
tools. Record source URLs and hashes.
- Add provider-focused execution for sandboxes, snapshots, volumes,
files, Git, commands, computer use, and account resources. Provider
authority still limits which endpoints accept an organization key.
- Validate action arguments. Resolve Toolbox targets through the fixed
platform API. Check sandbox identity and organization before using an
approved Daytona proxy. Keep normal guarded network requests and vault
resolution.
- Transfer file bytes without reading or writing host files. Share one
caller deadline across prerequisite reads, dispatch, and response
reading. Bound requests and responses. Do not automatically retry writes
with unknown outcomes. Redact the selected credential from results and
errors.
- Classify credential access, access changes, interactive input, command
execution, file permissions, and deletion (including TTL and
auto-delete) as destructive actions. Keep new and changed actions under
catalog review.
- Upgrade saved catalogs and retire the earlier diagnostic names. Hide
retired actions from the UI and agent discovery even when provider
refresh fails. Preserve existing action choices and historical records.
Reject stale same-name contracts during agent discovery and dispatch
before a board refresh.
- Add database-backed gateway and catalog-upgrade regressions, schema
generator tests, a browser setup check, and both capability map updates.

## Verification

- Passed on the review-fix head: 57 focused Vitest cases (18 Daytona
database/client cases, five HTTP boundary cases, and 34 shared catalog
cases), four generator tests, `pnpm -r typecheck`, and `pnpm build`. The
five HTTP cases use a real local server through the pinned production
transport. The normal browser setup check and 17 generator/artwork cases
passed on the initial PR head; those UI and artwork paths are unchanged.
- Passed on this branch: brand asset validation, token gates, map
structure checks, and `git diff --check`. All latest-head GitHub checks
pass on `ea979ccb3a64dc9508807823540f935c4316ea35`. Apex is 5/5, with
all five findings addressed and zero unresolved threads. The branch has
no merge conflicts.
- The initial catalog-generation command could not find the external
research corpus. The supported `--definitions-only` mode regenerated the
definitions successfully. Unrelated generated drift was excluded.
- An earlier full local Vitest attempt on the preview branch failed when
bundled PostgreSQL could not start on macOS. After replay onto current
master, all three unchanged event-sequencing cases pass with bundled
PostgreSQL; the earlier startup cause remains uncertain.
- The first full-suite command on this branch used my external test
database override. Chat fixtures require a current migrated schema and
failed because `agents.lifecycle_state` was absent in that disposable
database. A focused comparison reproduces failure with the override and
passes with normal setup. That attempt was stopped, and the full suite
restarted without the override. Focused Daytona cases use their own
migrated PostgreSQL 16 databases.
- The clean local full-suite attempt recorded embedded PostgreSQL
startup failures in two unchanged native-runtime cases and two failures
in unchanged Git fixtures. It was stopped after these failures were
isolated; no full local suite pass is claimed. The 15 matching
native-runtime cases pass separately. The Git cases fail with the local
`init.defaultBranch=main` setting and pass with `GIT_CONFIG_COUNT=1
GIT_CONFIG_KEY_0=init.defaultBranch GIT_CONFIG_VALUE_0=master` limited
to the test command. No global Git setting was changed. Full Linux CI is
green.
- Fixtures use real database persistence and run-bound gateway sessions
with provider responses replaced by fixtures. They cover personal/shared
vault ownership, reads and writes, file bytes, Off policies, revocation,
organization mismatch, untrusted proxy rejection, output bounds, saved
catalog upgrades, failed refresh, and permission preservation.
- The first Apex review found five valid issues: multipart transport
compatibility, destructive classification, caller deadlines, audit
filters, and stale saved contracts. All five were fixed with regressions
before the second review. A typecheck then found the nullable saved
schema hash; admission now accepts that stored type and rejects null as
stale.
- The browser check covers setup controls without submitting a provider
key. No real Daytona account, provider write, native OAuth flow, or
agent model run is qualified. Live provider read/write proof remains
pending a test account.

## Risks

- Daytona keys have broad Toolbox authority, including keys with no
selected resource scopes. Only assign this connection to trusted agents
and review its action permissions.
- Remote writes or commands can continue after a timeout. Calls do not
automatically retry an uncertain outcome.
- The bridge targets Daytona Cloud. Proxy hosts are restricted; an
unrecognized future regional host fails closed.
- Files and responses have an 8 MiB bound. Each action has one caller
deadline, capped at 30 seconds across all provider requests and response
reading. Interactive WebSocket sessions are not exposed as HTTP actions.
- The generated JSON snapshot exceeds 1,000 lines because it holds the
provider input contracts. Generator logic and execution code remain in
separate small modules. Updates require explicit regeneration and
catalog review.
- No database migration or lockfile change is required.

## Model Used

OpenAI Codex, GPT-6. The runtime identifies the model family but does
not expose the exact backend model ID or context window. Used reasoning,
repository inspection, code editing, shell tools, database verification,
and browser tests.

## 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>
2026-10-15 14:05:26 -07:00

9.4 KiB

navigation
navigation
section sectionOrder order
Apps, channels, and extensions 50 10

Connection setup

People connect an app or account, choose who may use it, and recover incomplete setup from either Apps or a task that needs access. A saved draft, a completed provider login, a usable connection, and a resumed task are separate checkpoints. Chat channels additionally require an endpoint and linked sender identity.

Agent access: companion.

Sub-features

  • catalog: find a provider, inspect its available methods, and open setup; unavailable methods explain their prerequisite rather than silently switching.
  • identity-and-access: select personal/shared identity and eligible agents; an empty explicit selection and company-wide access must not be confused.
  • credentials: provider sign-in, key, or generic MCP URL follows its supported setup method; credentials are not retained in browser draft storage.
  • handoff: provider popup/full-page callback returns to the correct setup host with the original task intent and identity choice intact.
  • draft-recovery: cancel, Back, Save & exit, reload, Finish setup, and reconnect preserve the exact draft rather than creating duplicate connections.
  • task-request: only the addressed person resolves the requested connection; usable access releases the pending task request through normal continuation.
  • channel-setup: provider endpoint, represented agent, linked sender, and communication instructions are configured before an external message is used.
  • failure: denied login, unreachable/private URL, expired credentials, and permission errors leave an actionable state rather than a false success.

How to get to it (user POV)

apps-catalog

Open Apps (/apps), choose an app, and connect from its landing page. Select an available method and access, then complete setup. Existing connections open their details; unfinished ones offer a way to finish setup.

Use Connect with a link or /apps/byo for a generic MCP server. Paste its URL, select access, and follow the probe's sign-in/key guidance. Provider-specific catalog setup and a generic endpoint may use different flows.

task-request

Open the task's pending connection request and its setup action as the named user. Setup can open in a task dialog and may use an OAuth popup. Follow the request's original link if setup falls back to a standalone page.

resume-connection

From Apps or connection details, use Finish setup, reconnect, or the offered authentication recovery action. Reload or return from the provider before checking whether the same saved connection became usable.

chat-channel

With chat connectors enabled, select a supported chat/email provider in Apps or open /apps/chat/connect. Complete that provider's endpoint setup, then open its settings (/apps/chat/:endpointId/settings). Follow identity linking as the intended sender before messaging the agent externally.

Driving it with Playwright and the Paperclip CLI

Preconditions: follow the baseline. Choose a disposable provider account/resource and record its auth method, deployment mode, account ownership, and access selection. For live setup, use the provider's documented prerequisites in the connector playbook. Automated fixtures do not establish OAuth registration, public callbacks, or production provider access.

apps-catalog

Automated: Browse, unconnected app, and AppsConnect cover catalog entry, access selection, provider-specific method choices, and setup failures with mocked APIs. Connection intents drives store and task setup against one fake provider through a useful continuation:

pnpm exec vitest run ui/src/pages/apps/Browse.test.tsx ui/src/pages/apps/AppsConnect.test.tsx
pnpm exec playwright test -c tests/e2e/playwright.config.ts tests/e2e/connection-intents.spec.ts

Manual: connect from an unconnected provider landing. Select the intended identity and agent access, complete authentication, reload, and inspect the saved connection. Run a permitted read-only action with an eligible agent and verify its useful result. Try an ineligible agent and confirm denial. Repeat with a user who cannot install company-wide; the UI must not imply broad access.

Daytona follows this same key/access wizard. Its native method exposes the published platform and Toolbox HTTP actions using provider sandbox IDs, without a Paperclip task or lease requirement. Daytona browser setup checks the catalog, password field, access controls, and optional organization pin. It does not submit a key or qualify a real provider account. See Daytona for API-key authority and OAuth limits.

Automated: AppsConnect's generic MCP cases cover probe-driven auth, private or unreachable endpoints, preregistered clients, secret-backed headers, and unsafe authorization URLs. These are component/API mocks, not remote provider proof.

Manual: connect a known test MCP URL through the link flow, verify its saved endpoint and a read-only action, then repeat with a bad URL and wrong credential. The error should explain the next action and preserve non-secret setup context. Test no-auth and authenticated endpoints separately; never infer one from the other.

task-request

Automated: interaction card checks addressed-user controls. AppsConnect tests cover page/dialog parity, task-bound OAuth, popup handoff, and verifying a saved connection before closing. Withdrawn requests render a terminal acknowledgement with no setup action; the interaction-body test and narrow Storybook journey cover this recovery state. The connection-intents browser suite above exercises fixture-backed continuation.

Manual: ask an agent to use an unavailable app, open its request as the named user, and complete setup in the dialog. Verify the card settles, the exact task resumes, and the agent returns a useful provider result. Repeat the page-host fallback and denied OAuth path. As another user, confirm that merely seeing the task does not grant the right to resolve the request.

resume-connection

Automated: AppsConnect tests cover exact-draft resume, declined OAuth, reconnect lookup failure/retry, response-lost creation, archived connection revival, and saved account reuse. App detail covers the connection host. These tests do not complete a real provider login.

Manual: leave setup through its footer, reload Apps, choose Finish setup, and confirm the same connection is resumed. Decline provider login and recover from that checkpoint. Reconnect an expired disposable account and verify a permitted action afterwards. Count connections before/after to catch accidental duplicates.

chat-channel

Automated: setup routing, saved setup state, email setup, and identity confirmation cover shared UI logic with fixtures. Provider-specific live setup is not implied.

Channel integration also covers bounded Telegram subscription recovery at startup and after committed configuration changes, saved retry deadlines, rollback, and parking pending repair while an endpoint or connection is inactive. The provider responses are fixtures. Settled maintenance leaves no discovery timer or database scans.

Manual: complete setup for one named provider, reload endpoint settings, link the intended sender, and send a disposable message. Verify one task and a useful reply in the originating conversation. Inspect an unlinked sender's denial and the endpoint's pause behavior. Repeat independently for each provider at issue; Slack setup does not qualify Discord, Telegram, GitHub, email, or iMessage.

Gotchas

  • Private endpoint rejection depends on deployment: owned loopback MCP servers are supported in local-trusted/private instances. Public authenticated deployments apply the private-network restriction.

  • A successful OAuth callback is not proof of saved connection access or task continuation. Verify all three checkpoints.

  • Personal identity, shared account access, and per-agent access are distinct. Connecting an account does not waive an Off action or Ask first review.

  • A tool app connection is not a chat endpoint. The same provider can offer both.

  • Old Apps/Connections URLs can redirect to Apps. Use the current navigation and record the actual destination rather than documenting an obsolete screen.

  • Full provider matrix, AI-account selection, gateway/profile administration, and account revocation lifecycles remain outside this seed recipe.

  • For governed actions after setup, use questions and approvals.

Documentation scope: App catalog and connection setup

Provider-specific authentication/revocation, credential-only accounts, and aggregator administrative variants still need their own detailed matrices.