# Project-scoped MCP for Agent Mate Status: design and implementation plan; not deployed. Date: 2026-09-15 Authorization: user approved proceeding and requested this artifact before implementation. ## Outcome A user selects an existing project, enables an approved MCP connection, and Agent Mate can use its permitted tools through the existing AIOS runtime. Access belongs to that project and account. The chat explains connection readiness and tool activity. Closing the dashboard does not stop autonomous work. The four copied services have passed representative shadow checks. This demonstrates installation-level readiness, not project-scoped access or comprehensive tool correctness. ## Hard constraints - Do not modify aios-harness or create a replacement model/tool execution loop. - Adapt Agent Mate to the existing runtime and its tool registration/call path. - Dashboard HTTP and WebSocket management use the same authorization decisions. Neither transport confers authority itself. - Preserve legacy administrator MCP behavior and unrelated Connections behavior. - Develop and verify in shadow9455. No production deployment, commit or push is part of this authorization. - Do not expose the dashboard home, provider secrets or unrelated project data to workers or MCP subprocesses. ## Evidence from the existing code Paths below refer to /tmp/agent-mate-discovery. | Existing contract | Design consequence | | --- | --- | | crates/aios-cli/src/tui_backend.rs constructs McpRuntime::connect_configured(&home) once, then registers its definitions/call adapters | MCP availability is process-scoped. A per-session prompt instruction cannot enforce project permissions. | | crates/aios-agent-mate/src/runtime.rs launches the existing tui-backend with AIOS_HOME, creates/resumes a session and sends prompt.submit | Keep this execution path. Scope the integration before launch; do not put MCP calls in a competing agent loop. | | crates/aios-agent-mate/src/host.rs owns task lifetime independently of dashboard sockets | MCP access and activity records must be owned outside a browser connection too. | | aios-connections already defines McpTools, McpHttp, McpStdio and stable Project/Agent principals | Extend the existing Connections system rather than build a second ownership database. | | Policy::authorized checks current bindings, grants and credential authority | Reuse current resource authority on every operation, not just on initial discovery. | | Connection.credential is mandatory; registration/grants require that credential's assignment | Local keyless MCP needs an explicit supported auth mode. A dummy vault key would be incorrect. | | aios-mcp supports configured stdio and remote HTTP/SSE | A scoped MCP adapter can present a standard MCP interface to the unchanged client. Exact transport/lifecycle behavior still requires verification. | These are source-review findings, not proof that the proposed bridge is implemented or compatible. ## User workflow 1. In a project's Connections panel, show approved available MCP connections by label and discovered tool descriptions. Keep installation commands, environment values and credentials out of the chooser. 2. The project owner chooses a connection and permitted tools. Explain what each tool can do; do not classify arbitrary tools as read-only based on their name. 3. Persist the grant using the authenticated account and a server-resolved immutable project identity. Reject stale selectors. 4. Show separate states: configured, checking, ready, unavailable, permission revoked. A successful installation-level Test alone does not make a project ready. 5. Agent Mate can offer the same selection in interactive chat. Chat and the manual panel submit the same backend operation. 6. During a task, emit correlated started/completed/failed/cancelled tool activity. Show safe descriptions, timing and authorized output links, not raw credentials or unrestricted argument dumps. 7. Revocation immediately blocks subsequent admission. Explain any operation already admitted whose external side effects cannot be undone. ## Permission and configuration model An administrator-approved server registration supplies a stable server identity and configuration revision. Names are display labels, not authority. Binding a connection to a server does not expose its command, URL headers or environment to the browser. Reuse Connections ownership and resource bindings. Add an explicit MCP binding containing the server identity/revision and allowed tool names. Replacing a server command/endpoint must invalidate readiness and require explicit acceptance of the new revision; reusing a display name must not inherit trust. Connection authentication must explicitly distinguish no credential from an assigned credential. Existing serialized credentials and API-provider requirements remain compatible. Only a registered keyless MCP binding permits no credential; an omitted credential must never silently bypass credential checks on existing providers. Effective permission is the intersection of current account authority, active project binding, enabled connection, McpTools grant, approved server revision and allowed tool set. Agent-wide grants do not implicitly authorize every project. Start with exact tool-name permissions; document that argument-level resource authorization remains the adapter/server's responsibility. Missing identities, unknown tools, removed accounts, replaced projects, unreadable policy and disconnected connections fail closed. ## Execution architecture Proposed path: Project chat / Connections panel -> existing HTTP or WebSocket management adapter -> shared Connections authorization and persistence Independent Agent Mate host -> authenticated task/project binding -> existing AIOS runtime and MCP client -> project-scoped MCP bridge -> approved external MCP service The bridge is a protocol/permission adapter, not an agent engine. Prefer official rmcp for its MCP protocol implementation. It must be owned by an independent host/service lifecycle, not a dashboard socket or HTTP handler. Integrate service commands into the existing AIOS executable where appropriate; do not introduce another inference engine. The runtime may see only bridge definitions for its bound project. Simply filtering tools/list is insufficient: tools/call must reauthorize each request, because tool schemas can remain cached in the runtime. Before choosing the final launch mechanism, verify how runtime configuration, vault access, sessions and project paths resolve from AIOS_HOME. Do not solve isolation by copying the dashboard home, duplicating provider keys, changing global runtime configuration during concurrent work, or sharing one unrestricted worker among projects. Authenticate the host-to-bridge association using an OS-authenticated private channel plus a server-issued task binding. A shared Linux UID alone does not identify a project. Request-supplied account/project IDs are not evidence of authority. Any capability must be scoped, short-lived, non-loggable and unavailable to other project workers. The exact delivery mechanism is a required implementation gate. Upstream MCP processes must not inherit the dashboard environment/home. Use reviewed executable/endpoint definitions, minimal environment, output/time/concurrency bounds and scoped workspace/output storage. Browser tools are network-capable; command approval does not imply access to every host or project. Establish and test the allowed filesystem/network boundary before enabling real project access. ## Revocation, recovery and events Reauthorize discovery and every call against current persisted policy. Define call admission as the authorization linearization point. A revocation prevents later admission; signal cancellation for already running calls where supported, but never claim it reverses external effects. Do not replay a tool invocation after an uncertain disconnect. Persist request identity and terminal/unknown state outside the dashboard. Reconnecting the chat restores activity history; it does not resubmit operations. Revoked tools may remain visible in an existing runtime's cached schema, but invocation must fail safely; newly granted tools become available through a verified supported refresh or a new task/runtime, not a harness change. Activity records bind account, immutable project, task, runtime session, connection and request ID. Enforce the same ownership on activity replay and artifact access. Raw MCP output is untrusted content, never an authorization instruction. Output HTML needs isolated rendering; screenshot paths need authorized artifact publication rather than arbitrary file access. ## Implementation sequence and completion gates | Task | Work | Evidence required before completion | | --- | --- | --- | | MCP-P01 | Verify runtime/bridge launch and task identity contract | Existing runtime discovers and invokes a disposable bridge; two project bindings cannot impersonate each other; no harness diff | | MCP-P02 | Extend Connections for keyless MCP bindings and exact tool grants | Existing credential-backed behavior preserved; keyless allowed only for approved MCP; stale/replaced bindings rejected | | MCP-P03 | Implement independent bridge with current-policy admission | Allowed/denied/revoked calls verified; provider not contacted on denial; process/environment bounds demonstrated | | MCP-P04 | Bind bridge to Agent Mate task preparation | Actual unchanged runtime invokes scoped tool; no cross-project configuration leakage; dashboard close does not stop task | | MCP-P05 | Add project picker and interactive chat controls over existing transport | Same HTTP/WS authorization, readiness states, no mutation replay; owner/member browser checks | | MCP-P06 | Persist tool activity and publish authorized results | Reconnect recovery, duplicate/unknown outcome handling, artifact ownership and safe rendering verified | | MCP-P07 | Shadow acceptance and rollback checkpoint | Full flow below passed; concrete input/output evidence on blackboard; production unchanged | Tasks are sequential where contracts depend on earlier evidence. A source test or stub UI alone does not complete operational integration. Any incompatibility changes Agent Mate or this bridge design, never the harness. ## Acceptance scenarios - Account A grants project A extract_structure; the actual AIOS runtime invokes it on a local test page and returns its headings. - Project B has no grant: neither discovery nor a manually supplied call can use that connection. Assert no upstream call occurred. - Client submits another account/project/task identifier: rejected before upstream access. - Allow one tool on a multi-tool service: an unlisted tool remains denied even when explicitly called. - Revoke during a live session: next call denied without process restart; already admitted operation reported accurately. - Remove/recreate a project or replace the server registration: old grants do not silently attach to the replacement. - Keyless MCP works without a fabricated secret. Existing credential-backed Connections still reject missing/revoked keys. - Close/reopen dashboard during work: independent task continues; progress resumes without executing the tool twice. - Upstream timeout/crash and bridge restart: bounded failure or unknown outcome; no automatic side-effect replay. - Two projects execute concurrently: no credential, file, output or event cross-access. - HTTP and WebSocket requests produce equivalent ownership decisions, including expired/deleted accounts. - Browser screenshot results are accessible only to authorized project users; raw server paths cannot be fetched arbitrarily. Use synthetic pages, dummy credentials and disposable fixture projects first. Publish why each check matters, input, expected output, actual output and scope. Distinguish library fixtures, actual runtime integration and real dashboard browser checks. Never describe a planned check as passed. ## Rollout and remaining boundaries Keep project MCP unavailable until the execution and permission gates pass. Add readiness per connection rather than changing a global provider_execution flag to imply all Connections providers work. Preserve admin MCP tooling. Back up affected shadow configuration/data before activation; keep new grants explicit with no automatic grants to existing projects. Remote OAuth/BYOK lifecycle, arbitrary untrusted server installation, channel onboarding and media generation remain later integration work. The design must support them without claiming they already work. The current page-structure parser is regex-based and style-inliner output is not guaranteed offline self-contained; their prior tests are representative, not exhaustive. ## MCP-P01 progress — actual runtime proof On 15 September 2026, an executable rmcp3.4 fixture ran through the existing shadow AIOS binary, using session.create and prompt.submit. A deterministic loopback model responder requested the MCP tool; no real provider or project was contacted. | Input | Observed result | Admitted fixture operations | | --- | --- | --- | | Project A with matching enabled policy | Returned project-a and MCP_BOUNDARY_FIXTURE | 1 | | Tool arguments include project B override | Rejected unknown project field | 0 | | Disable policy after the runtime discovers tools | Project access denied | 0 | | Launch binding B with policy for A | Project access denied | 0 | This proves runtime/protocol compatibility and per-call denial behavior in a controlled fixture. It does not prove hostile-worker isolation, multi-account ownership, concurrent projects, or real Connections grant enforcement. Launch arguments and the fixture policy are supervisor-controlled test inputs, not a production identity mechanism. MCP-P01 remains in progress. The next implementation requirement is a trusted account/project/task binding and policy boundary outside the worker's writable filesystem. The current host is single-owner and authenticates Unix peers by UID; that alone cannot distinguish multiple projects. Do not enable live project MCP access until this boundary is implemented and verified. Harness source and live services were not changed by the proof. ## Durable task identity — implementation progress The Connections backend now stores an immutable account, host, task and verified project association. It survives registry reopening and checks current project ownership. Revocation prevents an old task from being reactivated. MCP permission lookup uses that stored project identity and current connection grants. Seven focused tests passed: persistence, wrong account/host/task, permanent revocation, replaced projects and removed policy accounts, unverified selectors, project reassignment, and current MCP grants/credential authority. The full Connections regression suite passed 32 tests. These tests use temporary SQLite databases and synthetic project directories. Not deployed. Authenticated transport wiring and OS worker isolation remain pending. The API requires trusted service context; an untrusted host or account string is not authentication. No live project MCP access was enabled. ## Authenticated submission wiring and worker storage checks Implemented in the development dashboard: before a scoped Agent Mate send reaches the host, the adapter resolves the logged-in account, checks its server-configured host and project mapping, and persists the task binding in the authority-owned Connections registry. It uses the same deterministic project selection as Agent Mate. Extra identity fields in the command are rejected. Session identity and host assignment are rechecked before dispatch. The opt-in task configuration is private, owned by the dashboard authority, and requires a different worker Linux UID. Absence of configuration preserves ordinary chat and creates no project MCP binding. This is not implicit permission to use MCP. The policy mapping is operator-controlled; it is not a browser-editable account or host selector. ### Verification completed - A real compiled dashboard accepted a disposable authenticated WebSocket send and created Alice's host/project binding before the synthetic Unix host received it. - Forged owner fields, another account's project and stale revisions did not reach host execution. - Same-UID worker configuration and non-private policy files were rejected. - Removing the fixture session closed its existing socket. - An installation without scoped configuration retained ordinary chat with zero MCP task bindings. - In the running shadow worker's mount namespace as UID994, eight read/write attempts against an authority-only sentinel failed, including direct paths and paths through the dashboard process's root. The authority UID995 could read it. Sentinel removed afterwards. - Existing MCP WebSocket management fixture passed. Four Agent Mate library regressions passed. Earlier Connections suite passed32 tests. The dashboard test uses a synthetic Unix host to observe dispatch order; the separate runtime proof uses the actual AIOS execution loop. These do not yet establish a complete real-provider, multi-project bridge flow. The worker storage check enters the actual mount/UID boundary but does not inherit the service cgroup/seccomp filters. ### Deployment state Tested build is staged, not activated. The shadow deployment guard found two dashboard-owned AIOS processes and prevented their interruption. No live project grants, task configuration, runtime restart, production changes or harness edits were made. Deployment can use the existing guarded activation script once the dashboard has no active child processes. No new approval is requested.