doc/plans/2026-06-05-agent-access-mcp-runtime-slots-adr.md
Date: 2026-06-05
Status: Accepted for MVP implementation contracts, pending SecurityEngineer and UXDesigner validation gates.
Source issues:
Paperclip needs governed MCP/tool access for agents. The product should not become a raw mcp.json editor or an adapter prompt convention. The control plane must own which tools an agent can discover, which calls can run, which credentials are available, which calls need review, and how every decision is audited.
Paperclip already has useful primitives:
The gap is the governed access layer between agents and external tool/application capabilities. Current plugin/MCP surfaces are useful, but they do not provide a single default-deny policy engine, durable invocation ledger, runtime-slot supervisor, redacted audit model, or approval-safe tool execution path.
Build the MVP as Agent Access, exposed in the product as Tools & Access. MCP is a transport and integration type, not the user-facing product concept.
The CTO accepts the default-deny gateway architecture from PAP-10341 with these MVP decisions:
Tool Application
A company-visible tool source. MVP types are mcp_http, mcp_stdio, paperclip_plugin, and paperclip_self. Future types such as a2a can be added behind the same concepts.
Connection
An admin-managed access instance for an application. It stores transport configuration and secret references, not raw secret values. MVP supports managed company connections only.
Tool Catalog Entry
A snapshot of a discoverable tool/resource/prompt from a connection, including schema hash, title/description, risk classification, read/write/destructive flags, last seen time, and review state.
Access Profile
A reusable bundle assigned to company defaults, agents, projects, routines, or issues. Profiles select which applications, connections, and tools may become visible/callable.
Policy
Server-evaluated rule that can allow, block, require approval, redact, rate-limit, or defer because runtime capacity is unavailable. Policies are evaluated from authoritative Paperclip state, not model-provided context.
Gateway Session
A short-lived per-run session minted by Paperclip. It exposes only allowed tools for that run and prevents upstream credentials from reaching the agent process.
Invocation
Durable ledger row for every tool attempt. It records idempotency identity, policy decision, approval state, execution status, argument/result hashes or safe summaries, and links to run/issue/agent/company.
Tool Call Audit Event
Durable redacted event for discovery, allow, deny, approval requested, approval accepted/rejected, execution started, result returned, timeout, runtime failure, and policy/rate-limit decisions.
Runtime Slot
Managed lifecycle unit for a local stdio MCP process or remote session handle. Runtime slots are visible, supervised, capped, and reusable. They are not hidden per-agent child processes.
Add company-scoped storage under a Tools & Access namespace. Names are provisional, but the contracts are not:
tool_applications: company, app identity, type, status, owner/admin metadata.tool_connections: company, application, managed connection kind, transport config, secret refs, enabled flag, health.tool_catalog_entries: company, connection, tool name, schema, risk tags, version/hash, review/quarantine state.tool_profiles: company, profile name, description, status.tool_profile_entries: company, profile selectors for app/connection/tool/risk.tool_profile_bindings: company, profile binding target: company, agent, project, routine, or issue.tool_policies: company, rule type, priority, selectors, condition JSON, effect, enabled flag.tool_invocations: company, run, issue, actor, connection, tool, args hash, idempotency key, approval state, execution status.tool_action_requests: company, invocation, issue interaction/approval links, canonical signed reviewed args, preview.tool_call_events: company, invocation/run/issue/agent links, decision, reason code, redacted summaries, result size, latency.tool_runtime_slots: company, connection, workspace scope, credential scope, trust scope, status, provider ref/process id, idle TTL, caps, last error.tool_rate_limit_counters: company-scoped counters by policy window.Do not overload principal_permission_grants as the tool-resource policy store. Use it only for administrator capabilities such as:
tools:admintools:manage_connectionstools:manage_profilestools:view_audittools:usetools:manage_runtimeAll foreign keys must enforce company boundaries. Raw secrets must not be copied into these tables. Secret values resolve only at gateway/runtime execution time.
At heartbeat invocation time, Paperclip resolves the authoritative agent, issue, project, routine, workspace, adapter, and run records. It then creates a gateway session tied to that run.
The adapter receives only Paperclip gateway configuration:
For tools/list, the gateway evaluates visibility policy and returns only allowed descriptors. Hidden tools are omitted.
For tools/call, the gateway:
403 or structured denial for unauthorized direct calls;Agent-supplied runContext may remain for compatibility, but it is never authoritative. It must be checked against the authenticated run, agent, project, and company before use.
Implement toolAccessPolicyService as a deterministic service that returns:
allowedvisibility: visible or hiddeneffects: allow, block, require_approval, redact_arguments, redact_result, rate_limited, defer_runtimematchedPolicyIdsreasonCoderedactionPlanrateLimitStateruntimeSlotRequirementsInputs are:
Precedence:
Policy decisions must be unit-tested with stable fixtures. Discovery and execution must use the same policy engine so a tool hidden from tools/list also rejects direct calls.
Every call attempt creates or resolves an invocation. The ledger is required for all tools, not only write tools, because denied reads and approval waits must be auditable.
For write/destructive tools, idempotency identity must include company, connection, tool, canonical args hash, issue/run context, and a policy-provided idempotency key when available. Retries must not duplicate external side effects.
Approval-required calls store canonical reviewed arguments. Approval execution must use exactly those stored arguments, not a fresh model-provided payload.
Store safe summaries, hashes, sizes, and pointers. Do not store raw secret values. Large outputs should become bounded summaries plus artifacts/references rather than unbounded transcript/audit bodies.
Audit is a first-class feature, separate from generic activity logging. Activity logs capture administrative mutations. Tool audit captures runtime access decisions and upstream outcomes.
Audit events must include enough to answer:
Audit reads require tools:view_audit or board/admin access. Agent-facing transcript links may show summarized decision/result state, but raw audit details remain subject to audit permissions.
The runtime-slot strategy is explicit:
(companyId, connectionId, workspaceScope, credentialScope, trustScope).Recommended initial defaults:
Phase 1 fixtures should be isolated from production behavior but contract-aligned:
Minimum smoke checks:
403;Use board/admin endpoints under /api/companies/:companyId/tools/...:
Use gateway endpoints under /api/tool-gateway/...:
Existing /api/plugins/tools discovery/execution must be wrapped, filtered, or migrated so plugin tools obey the same policy and audit model. Compatibility is acceptable during migration, but there must not be a second ungoverned agent tool path after the MVP enforcement work lands.
Primary navigation:
Required views:
UX language should prefer App, Connection, Tool, Profile, Policy, Runtime, Audit, and Example. Use MCP as a connection type detail.
UI must never be the enforcement boundary. Designs must make default deny, approval wait, denied direct call, missing secret, runtime failure, and changed-tool quarantine states obvious.
Write/destructive tool calls can be:
Issue-thread action cards are the MVP review path for ordinary external writes. They must show a safe preview, target app/tool, redacted arguments, policy reason, and execute/cancel controls. Acceptance executes only the stored reviewed arguments once.
Formal approvals are reserved for broader trust/policy changes, high-risk connection changes, and any action that changes future autonomy rather than a single invocation.
Unattended runs fail closed when approval is required and no valid issue-thread or approval path exists.
At ADR time, PAP-10381 had no completed threat-model document or comments. This ADR accepts the default architecture but leaves explicit security validation gates:
If PAP-10381 requests a stricter position, SecurityEngineer feedback supersedes this ADR for security controls and must produce a follow-up ADR revision before broad implementation proceeds.
At ADR time, PAP-10382 had no completed UX document or comments. This ADR locks product vocabulary and surface placement while leaving design details to UX:
If PAP-10382 designs show a lower-friction flow that preserves server-side enforcement, UX can change layout and interaction details without changing the architecture. UX cannot move enforcement into UI-only state.
Phase 1 can proceed with isolated fixtures and smoke harness work.
Phases 2-8 should use this ADR as the stable contract:
Phase 9 validates the end-to-end release with QA, SecurityEngineer, CloudOpsEngineer, EvalsEngineer, and DevRel.
mcp.json, or upstream MCP metadata as enforcement boundaries.This ADR was checked against:
doc/GOAL.md, doc/PRODUCT.md, doc/SPEC-implementation.md, doc/DEVELOPING.md, and doc/DATABASE.md.packages/mcp-server/README.md for the current Paperclip MCP server boundary.server/src/routes/plugins.ts for the current plugin tool access gap.No code, schema, or runtime behavior changed in this ADR.