Connect an MCP server
Use an MCP Connection to make Tools from a remote Streamable HTTP MCP server available to an Agent. The connection and its server-side credential belong to the Tenant; an MCP Attachment selects it for one Agent.
Outcome
You will create and test a connection, preserve the Agent's existing attachments, and verify that one discovered Tool is invoked in a Turn.
Before you begin
You need a remote HTTPS MCP URL without embedded credentials, query parameters, or fragments; an Agent ID; and a backend SDK client. Plain loopback HTTP is a test-only mode: it is disabled outside NODE_ENV=test even if MCP_ALLOW_LOOPBACK_HTTP=true; production connections use HTTPS. Choose none, bearer, oauth_client_credentials, or oauth_authorization_code authentication. Authorization Code also requires {API origin}/v1/mcp/oauth/callback to be registered with the authorization server and a Supabase-authenticated Tenant admin session to approve the browser continuation.
Review MCP connections, Tools, Agents, and Security and credentials before configuring the connection.
Create the connection
This example uses a server that needs no authentication. Bearer and OAuth credentials are write-only fields supplied from backend environment variables. Direct-auth creation validates the remote server; a usable connection has status: "connected". There is no separate enabled flag—attachment to an Agent controls Tool availability.
authType | Additional create fields |
|---|---|
none | None |
bearer | bearerToken: process.env.MCP_BEARER_TOKEN! |
oauth_client_credentials | clientId: process.env.MCP_CLIENT_ID!, clientSecret: process.env.MCP_CLIENT_SECRET!, and optional scope |
oauth_authorization_code | Optional paired clientId and clientSecret, plus optional scope |
Complete authentication
none, bearer, and Client Credentials connections complete authentication during creation. Authorization Code creation returns a connection with status: "needs_auth". The ordinary API-key SDK client cannot initiate this continuation: API keys receive 403. On your trusted backend, construct a client with the current Supabase Tenant-admin access token, call connect(), and redirect that admin's browser to the returned URL:
import { BlazingAgents } from "@blazing-agents/sdk";
async function beginMcpOAuth(connectionId: string, tenantAdminAccessToken: string) {
const adminClient = new BlazingAgents({ apiKey: tenantAdminAccessToken });
const { authorizationUrl } = await adminClient.mcpConnections.connect(connectionId);
return Response.redirect(authorizationUrl, 303);
}Resolve tenantAdminAccessToken from the authenticated admin session on the backend and never return it to the browser. Only the redirect response leaves the backend.
OAuth requires a continuation
The returned URL carries a short-lived setup token, not the upstream credential. The platform callback completes the exchange and redirects to the dashboard; keep client secrets and tokens out of frontend code.
Test the connection
mcpConnections.test() performs live initialization and Tool discovery. A successful result safely reports server, toolNames, toolCount, and latencyMs; failures return an ok: false diagnostic without exposing credentials.
Attach it to the Agent
mcpConnectionIds is a complete replacement field. Read the current Agent and merge the new connection ID so existing MCP Attachments are retained.
Verify a discovered Tool
import assert from "node:assert/strict";
const connection = await client.mcpConnections.create({
name: `Customer tools ${crypto.randomUUID()}`,
url: "https://mcp.example.com/v1",
authType: "none",
});
const test = await client.mcpConnections.test(connection.id);
if (!test.ok) throw new Error(test.error.message);
assert.ok(test.toolNames.includes("lookup_customer"));
const agent = await client.agents.get(agentId);
const mcpConnectionIds = [
...new Set([...agent.mcpConnectionIds, connection.id]),
];
await client.agents.update(agentId, { mcpConnectionIds });
const turn = await client.chat({
agentId,
message: {
id: crypto.randomUUID(),
role: "user",
parts: [{ type: "text", text: "Use lookup_customer for customer 42." }],
},
});
let invoked = false;
for await (const chunk of turn.toUIMessageStream()) {
if (chunk.type === "tool-input-available") {
invoked ||= chunk.toolName.includes("lookup_customer");
}
}
assert.ok(invoked, "The Turn should invoke lookup_customer");Reconnect and diagnose failures
Use mcpConnections.reconnect(id, body) to replace the URL, authentication mode, or credential. A successful direct-auth reconnect returns connected; its prevalidation means a failed direct-auth reconnect retains the existing usable binding. Authorization Code reconnect is different: it replaces the credential state immediately, returns needs_auth, and requires another connect() continuation. Abandoning or failing that browser continuation does not restore the previous binding. Because Agent Versions store only the connection ID, reconnecting that same ID changes the live server or credential used by historical Pins.
Check status, lastAuthErrorCode, and the safe result from test() when authentication expires or discovery fails. Only connected connections can be attached. Audit Pins before reconnecting or deleting: a deleted MCP Connection disappears from pinned execution, and restoring a Version that names it fails current attachment validation. Deletion is rejected until every current Agent detaches it.
Production notes
- Tool discovery is live rather than stored as a permanent catalog. Re-test when the remote server changes.
- MCP Tools run through the in-process Agent loop. An MCP Connection does not grant access beyond the Tenant and does not bypass Tool approval or Agent configuration.
- Forwarding
userIdor selected metadata keys is disabled by default and configured on the MCP Attachment, not the connection.
Related capabilities
See MCP connections, Tools, Agents, and Security and credentials.
SDK and REST reference
The guide uses mcpConnections.create(), test(), connect(), reconnect(), and delete(), plus agents.get(), agents.update(), and chat().
The matching operations are create connection, test connection, connect OAuth, approve OAuth continuation, reconnect, delete connection, get Agent, update Agent, and create a Session Turn.