MCP servers
Register workspace MCP servers and test listed HTTP/SSE tools.
MCP server records under /api/v1/mcp-servers. A workspace, personal, or Copilot bearer key
with current membership can perform the read-only GET routes. Personal and Copilot reads use
the stable workspace-safe.v1 projection; they never expose connection coordinates or stored
headers. A workspace-scoped key is required for POST, PATCH, DELETE, and tool tests. Missing
token → 401 { "error": "Valid bearer API key is required" }; a valid key without the required
workspace authority → 403.
No cursor pagination. No Idempotency-Key. Session copies: /api/mcp-servers/*. Distinct from the platform MCP surface that exposes Confluye itself.
Endpoints
| Method | Path | Envelope |
|---|---|---|
| GET | /api/v1/mcp-servers | { servers[] } |
| POST | /api/v1/mcp-servers | 201 { server } |
| GET | /api/v1/mcp-servers/{id} | { server } |
| PATCH | /api/v1/mcp-servers/{id} | { server } |
| DELETE | /api/v1/mcp-servers/{id} | { deleted: true } |
| POST | /api/v1/mcp-servers/{id}/tools/{toolName}/test | Test result (see below) |
Missing id → 404 { "error": "MCP server not found." }.
Server object
Reads from a key with the workspace.secret.read capability return id, workspaceId, name,
transport (http | sse | stdio), endpoint, headers, enabled, tools (string[]),
createdAt, optional lastSeenAt. A Viewer or other key without that capability receives the safe
projection below, regardless of whether its scope is workspace, personal, or Copilot.
Keys without that capability return the safe-content contract instead:
{
"redaction": { "applied": true, "projection": "safe-content", "contractVersion": "workspace-safe.v1" },
"id": "mcp_…",
"workspaceId": "ws_…",
"name": "Docs",
"transport": "http",
"enabled": true,
"tools": ["search"],
"createdAt": "2026-08-24T00:00:00.000Z"
}
The safe projection intentionally omits endpoint and headers. Clients that need connection
configuration must migrate to a workspace key with the appropriate secret capability; clients that
only enumerate servers should consume redaction.contractVersion and the safe fields above.
Create (upsert by name)
Official Google Workspace MCP connections accept an optional googleMcp object in create/update on session, tRPC, versioned API and platform capability surfaces. Its fields are service (gmail, drive, docs, sheets, slides, calendar), access (read, write) and optional credentialId. The endpoint must match that service's official endpoint, and custom headers are not accepted. The credential must belong to the acting user's accessible scope in the same workspace and use an administrator-registered agent client. Omit the credential to prepare a connection for interactive consent; use a null credential ID when disconnecting.
Full connection reads and create/update responses include googleMcp and its current googleMcpVersion, including enabled-only and tools-only updates. Safe directory reads show only the service and access level, never its credential ID. Preparing or changing the binding makes tools unavailable until discovery succeeds, preserving the user's saved selections for eligible tools. Manually replacing the bound credential value also withdraws readiness, even when its ID stays the same; normal token-renewal compare-and-set preserves readiness and the revision. Renewable agent grants require a signed native Google token pair; unsigned imported pairs, substituted refresh tokens and older proofs require fresh Connect Google service consent before discovery or dispatch. Access-only imports remain subject to issuer and scope verification. These pending Google responses return enabled: false, empty tools and disabled descriptors; the stored enabled preference still allows Test connection to discover the new binding. Endpoint-only and headers-only updates must still satisfy the Google binding's endpoint and header rules. The registered client's connection access is checked for attached and imported credentials and before dispatch. All-users access is the default; explicit verification-only access requires approved scopes or an exact verification audience. Google approval and client classification remain separate. Human consent remains session-only and is invalidated by a later connection change or disconnect, including cancellation before the first grant is installed. API clients can return the existing authorization handoff to Settings; an accessible Google binding does not require repeat consent. A personal binding requests consent for another member or an unattended caller; a shared workspace credential remains available to authorized workspace callers. Generic connections, alternate URL forms and redirects cannot bypass Google's binding checks. They cannot reuse the browser state cookie or start consent as another user. See Google Workspace MCP.
Required trimmed name and endpoint. Else 400 { "error": "MCP server name and endpoint are required." }.
| Field | Notes |
|---|---|
headers | Object or JSON string object |
transport | Default http. Other values must be http, sse, or stdio |
tools | Array of strings; trimmed; empty entries dropped; duplicates collapsed in order |
enabled | Default true. When enabled, lastSeenAt is set |
POST upserts @@unique([workspaceId, name]): same name returns 201 with the same id and updated endpoint/headers/transport/tools/enabled. This is the mutation idempotency story (not Idempotency-Key).
Parse/validation errors → 400 { "error": "<message>" } ("Headers must be a JSON object.", "MCP tools must be an array of strings.", "MCP transport must be http, sse, or stdio.").
POST and a PATCH that changes endpoint apply the outbound network policy before anything is stored. An endpoint on a private, loopback, link-local, cloud metadata (169.254.169.254), or internal host, or a name that resolves to one, returns 400 with a fixed message that does not repeat the host. An operator can allow a legitimate private installation with FLUXUS_HTTP_EGRESS_ALLOWLIST.
Discovery and tool requests refuse redirects to another scheme, host or port with egress_blocked
before sending the next request. Same-origin redirects remain supported. Store the provider's final
endpoint URL when its old address redirects to another origin, then test the connection again.
An MCP server registered as a product connection sends a signed run
context with every request, must keep an https:// endpoint on the origin it was registered with, and is
refused (not called unsigned) when its endpoint moves to another origin. A registered product connection prevents
server deletion: DELETE returns 409 mcp_product_connection_attached. Remove the product connection through its
own lifecycle first; unwithdrawn mailbox credentials move into bounded, subject-free revocation storage before
their mailbox rows are removed. Then delete the MCP server. If an Admin marked the connection trusted,
changing its endpoint, headers or transport removes that trust and records it in the audit log; changing
only tools or enabled does not. PATCH can change endpoint and headers; transport can only be changed
through the POST upsert, because PATCH does not accept it. Other servers are called exactly as described here.
Codex CLI and Claude Code nodes use product connections through a temporary run-scoped MCP door. The door signs requests with the saved run context and requires workflow trust. A CLI node using product tools may include the run's saved-browser session and permitted workspace instruction skills; it cannot combine them with another MCP server. An untrusted connection or mixed MCP attachments block validation, publication or run admission. See the product connections reference for workflow trust and the MCP feature page for the CLI attachment rules.
Update and delete
PATCH: enabled, endpoint, headers, tools. Not name or transport. Enabled servers refresh lastSeenAt.
DELETE is hard-delete.
Tool test
POST .../tools/{toolName}/test — toolName is URL-decoded. Body { arguments } (object, JSON object string, or omitted → {}).
| Condition | HTTP |
|---|---|
| Server missing | 404 |
enabled: false | 400 { "error": "MCP server is disabled." } |
Non-empty tools list and name not listed | 400 "MCP tool \"{name}\" is not listed on server \"{serverName}\"." |
Empty tools | Any tool name is allowed |
Bad arguments | 400 "MCP tool arguments must be a JSON object." |
| Live call success | 200 { ok: true, serverId, serverName, toolName, arguments, content, metadata, latencyMs, checkedAt } |
Live call failure (including stdio) | 200 { ok: false, ..., error, latencyMs, checkedAt } — not 5xx |
Runner POSTs JSON-RPC tools/call to endpoint for http and sse only. Timeout: WORKFLOW_MCP_TIMEOUT_MS or 10s. Max body: WORKFLOW_MCP_MAX_RESPONSE_BYTES or 1 MiB. Protocol header MCP-Protocol-Version: 2025-06-18. stdio → error "MCP stdio transport is not supported by the workflow runner." inside ok: false. Test payloads do not echo stored Authorization headers.
Known gaps
- PATCH cannot rename or change transport.
stdiocan be stored but cannot be executed here.- Empty
toolsdoes not discover remote tools; it only skips the allow-list. - Duplicate create is upsert, not
409.
