---
title: MCP
description: Connect an agent client to bounded tools over explicitly mapped internet-reachable vaults.
slug: mcp
path: /mcp
section: APIs
availability: supported
nav_order: 6
canonical_url: https://developers.phasoric.com/mcp
markdown_url: https://developers.phasoric.com/mcp.md
mirror_url: https://phasoric.com/developers/mcp
---
# Model Context Protocol (MCP)

Phasoric exposes a stateless MCP Streamable HTTP endpoint implemented with the official TypeScript SDK. It negotiates the current `2025-11-25` protocol revision and supported earlier revisions at:

```text
POST /api/mcp
```

[Machine-readable tool reference](/api/content/developers/references/mcp.json)

The hosted endpoint is an authenticated AI-tool gateway over explicitly mapped internet-reachable content. It discovers Phasoric Hosted, Dropbox, Google Drive, and GitHub mappings owned by the authenticated account. Local-only browser state remains available only through the in-page WebMCP adapter described below.

External-provider mappings join two server-authoritative records on every call: the synchronized workspace mapping and the authenticated account's active provider connection with the required read capability. A provider connection by itself is not vault authority, and a mapping identifier by itself is not a credential. Device-encrypted `BASALT-ENC-1` bodies remain inaccessible because their decryption key never leaves the device.

## WebMCP / Site Tools

Phasoric exposes one versioned agent-tool contract through two transports:

- Hosted MCP (`/api/mcp`) operates on explicitly mapped Phasoric Hosted or remote-provider vaults and accepts only the opaque mapping handles returned by `list_vaults`.
- WebMCP registers the same tool names, descriptions, safety annotations, and operations with `document.modelContext` after the local workspace is ready. Operation-specific inputs stay identical; only the transport's vault selector differs (`mappingId` for hosted MCP and `vaultId` for WebMCP).

WebMCP vault IDs are opaque routing handles. `local:<vault>` executes against the active browser workspace; `hosted:<mapping>` forwards the call to hosted MCP. Agents should always call `list_vaults` and pass the returned `vaultId` rather than constructing one. If `vaultId` is omitted, WebMCP uses the currently selected local vault.

Forwarded hosted calls use the user's HttpOnly Phasoric session cookie. Page JavaScript never receives a bearer token. The server accepts session-authenticated MCP only when the request carries the WebMCP transport header, comes from a trusted Phasoric origin, and is same-origin or same-site. Hosted plan, rate, account, and monthly operation checks still apply.

The shared contract lives in `shared/agent-tools.js`; do not add a tool to only one transport. Every contract change must keep hosted and WebMCP tool-name parity and provide an implementation in both adapters.

## Standard Streamable HTTP lifecycle

Codex and other conforming clients begin with an `initialize` JSON-RPC request. Initialization, `notifications/initialized`, `ping`, `tools/list`, and `tools/call` use the standard Streamable HTTP path. Requests use these transport headers:

```http
Authorization: Bearer bda_…
Content-Type: application/json
Accept: application/json, text/event-stream
MCP-Protocol-Version: 2025-11-25
```

The initialize request does not require `MCP-Protocol-Version`; subsequent standard requests send the revision negotiated by the initialize result. The endpoint returns JSON responses for client requests and does not expose a standalone GET event stream in stateless mode.

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": {},
    "clientInfo": { "name": "phasoric-client", "version": "1.0.0" }
  }
}
```

The initialize result includes server-wide instructions telling agents to discover mappings first, respect bounded reads, and preview writes for human approval.

### Legacy compatibility

Existing Phasoric integrations remain supported. A JSON GET request performs legacy discovery, and POST requests without the Streamable HTTP `Accept` header may use JSON-RPC `server/discover`, `tools/list`, or `tools/call`. The compatibility bridge also accepts `Mcp-Method` and `Mcp-Name` headers. An `initialize` body always takes precedence and enters the standard Streamable HTTP path.

## Authentication

Phasoric supports two independent connection methods.

### Account connection with OAuth (recommended)

Interactive remote clients should connect to the resource URL `https://phasoric.com/api/mcp` and perform OAuth discovery. Phasoric publishes Protected Resource Metadata and Authorization Server Metadata, accepts standards-based HTTPS Client ID Metadata Documents (CIMD), and retains Dynamic Client Registration (DCR) compatibility for public clients.

The authorization-code flow requires PKCE `S256`, exact redirect matching, OAuth state, and the exact resource indicator `https://phasoric.com/api/mcp`. The consent page explains the requested permissions before issuing a five-minute, single-use authorization code. Access tokens last one hour. When `offline_access` is granted, refresh tokens last up to 30 days, rotate after every successful use, and replay revokes the grant and token family.

Available scopes are:

| Scope | Meaning |
|---|---|
| <code>mcp:read</code> | List authorized mappings and use search, note, graph, schema, canvas, provenance, and other read-only MCP tools. |
| <code>mcp:write</code> | Request `create_or_append_note` or `apply_note_transaction`; mapping policy, preview, revision, idempotency, and approval rules still apply. |
| <code>offline_access</code> | Receive a rotating refresh token so the client can remain connected. |

OAuth tokens are audience-bound to the hosted MCP resource. They cannot authenticate `/api/dev`, capture, account, billing, or administration APIs. Each MCP request still resolves the account's current status, plan entitlement, rate limit, monthly allowance, mapping permissions, and write governance.

Review or revoke clients in **Settings → AI Connections & API → Connected applications**. Revocation immediately invalidates the grant and its access and refresh credentials; it does not change a manually managed developer token.

### Manual bearer token (compatibility)

CLI, desktop, and development clients that cannot complete OAuth may generate a hosted access token from **Settings → AI Connections & API**. Phasoric stores only its hash and supports rotation or revocation:

```http
Authorization: Bearer bda_…
Content-Type: application/json
```

Most vault tools also require a `mappingId` argument. Treat it as an opaque handle returned by `list_vaults`; do not construct it or assume it is always a raw UUID.

The same manually managed token may be used for both hosted MCP and the Developer REST API on Developer & Agent or Team plans. Each endpoint checks the account's current plan independently on every request. A Premium or Professional token therefore does not grant Developer REST API access. OAuth MCP tokens are never shared with the Developer REST API.

MCP operations use a dedicated monthly counter and request-per-minute boundary; they do not consume Developer REST API allowance. Authentication, inactive-account, entitlement, rate-limit, and monthly-limit rejections do not consume the monthly MCP allowance. Once an authenticated request reaches a recognized protocol or tool operation, it reserves one operation before execution, including a tool call that later fails argument validation. This prevents concurrent mutation requests from executing beyond the monthly allowance.

## Initialization and discovery

Standard clients should use `initialize`. The legacy `server/discover` method remains available to older Phasoric clients:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "server/discover"
}
```

Response:

```json
{
  "jsonrpc": "2.0",
  "result": {
    "server": {
      "name": "phasoric-hosted-mcp",
      "version": "1.0.0",
      "protocolVersion": "2025-11-25"
    },
    "protocolVersions": ["2025-11-25", "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"],
    "capabilities": {
      "tools": {
        "listChanged": false
      }
    }
  },
  "id": 1
}
```

## List tools

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list",
  "params": {}
}
```

The V1 implementation currently exposes these tools:

| Tool | Purpose | `mappingId` |
|---|---|---|
| `get_intelligence_capabilities` | Reports hosted scope availability, bounded semantic reads and proposal-only capabilities | Required |
| `get_decisions` | Returns human-confirmed Strata decisions with status, temporal validity and source references | Required |
| `get_decision_evidence` | Returns authorized source blocks supporting a confirmed decision | Required |
| `find_related` | Returns typed explicit, semantic, evidence, decision, temporal and derived relationships | Required |
| `get_relationship_explanation` | Explains a typed relationship with source evidence and freshness | Required |
| `get_changes` | Returns deterministic hosted knowledge change events with before/after revisions | Required |
| `get_contradictions` | Returns recorded decision tensions without flattening history | Required |
| `get_open_questions` | Returns persisted, scope-authorized open questions and evidence references | Required |
| `get_commitments` | Returns persisted commitments and unresolved follow-up with provenance | Required |
| `query_quarry` | Materializes a versioned saved Quarry inside the authorized Context Scope | Required |
| `get_watch_findings` | Returns authorized persisted Pulse Watch findings and review state | Required |
| `get_living_synthesis` | Returns authorized persisted living brief sections with evidence and review state | Required |
| `propose_knowledge_change` | Previews scope-authorized note changes through the guarded transaction service | Required |
| `propose_action` | Creates a Forge proposal containing a guarded note-change preview | Required |
| `list_vaults` | Discover authorized Phasoric Hosted and remote-provider mappings | Not required |
| `open_app_view` | Return a deep link to a supported Phasoric workspace view | Not required |
| `search_notes` | Search paths and bounded content in one available vault | Required |
| `get_note_content` | Read one available note and provider revision | Required |
| `create_or_append_note` | Preview/apply one authorized note write | Required |
| `query_graph_relations` | Query incoming/outgoing WikiLink relations | Required |
| `translate_canvas` | Convert bounded spatial nodes to a Markdown outline | Not required |
| `get_vault_schema` | Inspect bounded YAML frontmatter keys | Required |
| `apply_note_transaction` | Preview/apply guarded authorized note changes | Required |
| `get_knowledge_events` | Read provenance events for one mapping | Required |

## Call a tool

```json
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "search_notes",
    "arguments": {
      "mappingId": "<value returned by list_vaults>",
```

Successful tool results use MCP-style content records. Tool failures may return JSON-RPC errors or an MCP `isError` result depending on whether the failure is protocol-level or tool-level.

## Mutation safety

`create_or_append_note` and `apply_note_transaction` use the Phasoric knowledge-transaction guardrail. Phasoric Hosted mappings retain their database transaction and recoverable-trash behavior. A Dropbox, Google Drive, or GitHub mapping becomes writable only when its owner enables **Allow hosted MCP note changes** for that exact mapping, the mapping is not pull-only, the active connection has provider file-write capability, and device-held vault encryption is disabled. Google Drive deletes move the note to Drive trash, and GitHub changes create commits on the mapped branch.

- Writes default to dry run.
- Applied writes require explicit `dryRun: false`.
- Existing-note changes should provide the current expected revision/hash.
- Applied writes require an idempotency key.
- Phasoric Hosted batch transactions are bounded and atomic.
- Remote-provider previews may contain multiple actions, but an applied remote request is limited to one note per idempotency key because provider writes cannot be committed atomically with Phasoric's audit database.

An MCP client should preview the mutation, show the intended effect when appropriate, then explicitly apply the confirmed transaction.

## Bounded inspection

MCP operations are intentionally bounded. Current implementation limits include:

- search result limits;
- bounded provider listings, folder traversal, total provider requests, operation wall time, body reads, and content-search downloads;
- at most 500 canvas nodes for `translate_canvas`;
- a bounded frontmatter scan for `get_vault_schema` (up to 2,000 Phasoric Hosted notes, or up to 20 live note reads inside an external-provider mapping);
- bounded content used for graph/frontmatter analysis;
- at most 100 actions in a note transaction.

Do not treat a truncated schema/graph response as proof that no additional information exists.

## Governance boundaries

MCP does not create a second authority model. A tool call cannot legitimately:

- read a local-only vault through the hosted gateway;
- infer access to an arbitrary provider folder from a connected Dropbox, Google Drive, or GitHub account;
- decrypt a remote note protected by a device-held vault key;
- manufacture workspace/vault authority from a guessed identifier;
- bypass current Context Scope/audience restrictions where a scoped Product Runtime workflow applies;
- confirm a Strata decision merely because an agent generated it;
- bypass Forge for consequential governed actions;
- promote unreviewed model output to trusted shared memory.

## Client configuration

For a manual desktop/CLI connection, generate a token in **Settings → AI Connections & API**, then expose it to the local Codex host as `PHASORIC_MCP_TOKEN`. Do not put the token itself in `config.toml` or a checked-in file.

### Codex CLI and ChatGPT desktop

Add the Streamable HTTP server with the current Codex CLI:

```powershell
codex mcp add phasoric --url https://phasoric.com/api/mcp --bearer-token-env-var PHASORIC_MCP_TOKEN
codex mcp get phasoric
```

The equivalent project-scoped `.codex/config.toml` entry is:

```toml
[mcp_servers.phasoric]
url = "https://phasoric.com/api/mcp"
bearer_token_env_var = "PHASORIC_MCP_TOKEN"
default_tools_approval_mode = "prompt"
```

In the ChatGPT desktop app, open **Settings → MCP servers → Add server**, choose **Streamable HTTP**, enter `https://phasoric.com/api/mcp`, save, and restart. The desktop app, Codex CLI, and IDE extension share MCP configuration on the same Codex host. Use `/mcp` to inspect the connected server.

The token environment variable must be available to the process launching Codex or the desktop app. Restart the application after adding or rotating it.

### ChatGPT on the web

In a ChatGPT workspace where custom MCP connections are enabled, add `https://phasoric.com/api/mcp` as the remote MCP server. ChatGPT discovers Phasoric's OAuth metadata, opens the Phasoric sign-in and consent screen, and returns after authorization. Workspace administrator policy and the ChatGPT product's current connector availability still apply. No developer token needs to be pasted into ChatGPT.

After connecting, ask the client to call `list_vaults`. Explicitly mapped Phasoric Hosted, Dropbox, Google Drive, and GitHub vaults may appear. Local-only vaults are intentionally unavailable through this hosted endpoint.

`list_vaults` returns `readOnly` and `writeAccess` for each remote mapping. To authorize Dropbox, Google Drive, or GitHub CRUD, open **Settings → Cloud Sync**, select the exact provider mapping, and enable **Allow hosted MCP note changes**. Leave approval mode on `prompt`: the agent should preview first, then apply only the change you approve.
