> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polycore.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP

> How external AI agents call the governed Polycore catalog without receiving production credentials.

Polycore exposes connected runner capabilities through a Streamable HTTP MCP
endpoint. This lets coding agents and other MCP clients use the same catalog,
policy gate, environment routing, and audit model as Slack and dashboards.

The MCP client receives tool schemas, not downstream credentials.

<Info>
  MCP access is provisioned during assisted onboarding. Polycore creates the
  organization-scoped caller identity and token, then helps configure and test
  each client.
</Info>

## Architecture

```mermaid theme={"system"}
flowchart LR
  Agent["MCP client"]
  MCP["Polycore MCP endpoint"]
  CP["Control plane"]
  Runner["Customer-hosted runner"]
  Data[("Database or API")]

  Agent -- "Caller token" --> MCP
  MCP --> CP
  CP -- "Signed governed dispatch" --> Runner
  Runner --> Data
```

The caller token authenticates requests to Polycore. It is not a database
password, API key, or cloud service-account credential.

## Catalog discovery

The MCP tool list is built from runners that are currently connected for the
caller's organization.

Tool metadata includes:

* Capability name and description.
* Input JSON Schema.
* Project namespace when needed to avoid collisions.
* `polycore_list_pending_approvals`, a read-only control-plane tool for
  observing pending approval state.

Runner capability names are converted to MCP-safe tool names. For example, a
runner capability such as `firestore.count` is exposed with a sanitized tool
name while preserving its catalog identity in dispatch and audit.

<Note>
  The tool list reflects the live connected catalog. If a runner disconnects or
  a deployment changes its capabilities, MCP should not continue presenting a
  stale executable surface as available.
</Note>

## Assisted setup

<Steps>
  <Step title="Choose the agent and scope">
    We identify the MCP client, the Polycore organization and projects it should
    reach, and the operator identity that will own the token.
  </Step>

  <Step title="Provision a caller token">
    Polycore creates a distinct token and audit subject for the client. Separate
    agents receive separate identities so their activity can be distinguished.
  </Step>

  <Step title="Configure the MCP client">
    The client receives the Polycore MCP URL and bearer token through its normal
    secret configuration. No runner credential is placed in the client.
  </Step>

  <Step title="Verify discovery">
    We confirm that the client sees only the expected project namespaces and
    capability schemas from connected runners.
  </Step>

  <Step title="Test reads and writes">
    A read completes end to end. A write enters pending approval, and the client
    cannot release it through the MCP tool surface.
  </Step>
</Steps>

## Read flow

For a `read` capability:

1. The MCP client calls the generated tool with schema-valid arguments.
2. The control plane binds the MCP caller, organization, project, and
   environment.
3. The invocation is signed and dispatched to the selected runner.
4. The structured result returns to the client.
5. The invocation is recorded under the MCP caller identity.

This works for built-in datastore queries and customer-authored read actions.

## Write flow

For a `write` capability, the call returns an approval-required result rather
than an executed mutation.

```mermaid theme={"system"}
sequenceDiagram
  participant A as MCP agent
  participant P as Polycore control plane
  participant H as Human approval surface
  participant R as Runner

  A->>P: Call write tool
  P-->>A: Pending approval id
  P->>H: Present operation and arguments
  H-->>P: Approve or deny
  alt Approved
    P->>R: Signed write dispatch
    R-->>P: Result
  else Denied
    P->>P: Close without dispatch
  end
  A->>P: Observe pending approval state
  P-->>A: Executed, denied, failed, or still pending
```

The agent can observe a pending request so it can report the final state. It
does not receive approve or deny tools.

<Warning>
  Do not add an agent-callable approval tool as a convenience. If the same agent
  can both request and approve a write, client-side tool policy can collapse the
  human gate.
</Warning>

## Authentication and attribution

Use a distinct MCP token for each meaningful caller, such as a deployment bot,
coding agent, or team integration.

<Columns cols={2}>
  <Card title="Why distinct tokens matter" icon="fingerprint">
    Audit records identify which external caller made a request. One shared
    token would flatten those identities into a single subject.
  </Card>

  <Card title="What a token does not contain" icon="key-round">
    It does not contain runner enrollment secrets or credentials for Postgres,
    Firestore, internal APIs, or your cloud provider.
  </Card>
</Columns>

Store the token in the MCP client's secret mechanism. Do not commit it to a
repository or paste it into agent context.

## Environment routing

When a project has multiple environments, the MCP catalog represents
non-default targets with environment-qualified tool names. The selected tool
determines which enrolled runner receives the call; environment is not a free
form capability argument. The client never supplies a raw database URL or
service-account identity.

<Tabs>
  <Tab title="Explicit target">
    The agent selects the advertised environment-qualified tool, such as a
    `staging__...` capability, when a request names that target.
  </Tab>

  <Tab title="Default target">
    The unqualified tool name maps to the project's default environment. We
    verify that default during onboarding.
  </Tab>

  <Tab title="Unavailable target">
    If the selected runner is offline, the invocation fails. Polycore does not
    fall back to another environment.
  </Tab>
</Tabs>

## Security boundaries

<AccordionGroup>
  <Accordion title="What can a compromised MCP token do?" icon="shield-alert">
    It can request the catalog exposed to that caller until revoked. It cannot
    retrieve raw runner credentials. Reads remain the main immediate data-access
    surface, and writes still enter the configured approval path.
  </Accordion>

  <Accordion title="Does the agent connect to the runner?" icon="unlink">
    No. The agent connects to the Polycore control plane. The runner maintains
    its own outbound connection and accepts signed dispatches from the control
    plane.
  </Accordion>

  <Accordion title="Where do tool results go?" icon="arrow-up-right">
    Results return through the control plane to the MCP client and are part of
    the request and audit path. Design capabilities to avoid returning
    unnecessary sensitive fields.
  </Accordion>

  <Accordion title="Can the client discover disconnected capabilities?" icon="refresh-cw-off">
    The MCP tool surface is derived from the live runner catalog. Availability
    changes when runners connect, disconnect, or deploy a revised catalog.
  </Accordion>
</AccordionGroup>

## Production validation

<Check>
  Each MCP client uses a distinct caller identity and stores its token outside
  prompts and source control.
</Check>

<Check>
  Tool discovery is limited to the intended organization and connected project
  catalog.
</Check>

<Check>
  Reads route to the intended environment and return bounded structured data.
</Check>

<Check>
  Writes return pending approval and the MCP surface has no approve or deny
  tool.
</Check>

<Check>
  Revoked or invalid tokens fail authentication without reaching a runner.
</Check>

<Check>
  The audit path distinguishes the MCP caller from Slack and web callers.
</Check>
