Files
cobble/src/harness/mcp/connect-mcp-server.ts
T
tbenandClaude Opus 5.5 6a2665dae9 Add the harness, envs, per-bot models and chat attachments
- Harness: providers, model catalog synced hourly, automatic free picks,
  cooldowns, tool loop with context trimming, MCP computer tools
- Bots queue runs replies and tasks through the harness; jobs wait
  (attempt refunded) while every model is resting
- Envs: Settings > Environment, scoped general/workspace/computer,
  written to computers and redacted from tool output
- Models: Settings > Models, per-harness provider select defaulting to
  OpenRouter, and a models modal on each bot's chat (the coordinator's
  edits the defaults)
- Chat: thinking row while a reply runs, file attachments (upload,
  paste, drop) that replies read as images, audio and document text
- Fix media uploads failing after a user's first file, and private
  files being served from the public media path

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 03:38:38 +01:00

59 lines
1.8 KiB
TypeScript

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { AppData } from "@/src/data/app-data";
import { SiteData } from "@/src/data/site-data";
type Params = {
/**
* The server's MCP endpoint, e.g. `http://cobble-computer:8080/mcp`.
*/
url: string;
headers?: Record<string, string>;
signal?: AbortSignal;
};
/**
* Connects to an MCP server over Streamable HTTP, falling back to the
* older SSE transport. Close the client when the run is done.
*/
export default async function connectMcpServer({
url,
headers,
signal,
}: Params): Promise<Client> {
const endpoint = new URL(url);
const request_init = headers ? { headers } : undefined;
const options = { signal, timeout: AppData.McpConnectTimeoutMs };
try {
const client = newClient();
await client.connect(
new StreamableHTTPClientTransport(endpoint, { requestInit: request_init }),
options,
);
return client;
} catch (error: unknown) {
if (signal?.aborted) throw error;
try {
const client = newClient();
await client.connect(
new SSEClientTransport(endpoint, { requestInit: request_init }),
options,
);
return client;
} catch {
throw new Error(
`Couldn't connect to the MCP server at ${endpoint.origin}: ${
error instanceof Error ? error.message : String(error)
}`,
);
}
}
}
function newClient() {
return new Client({ name: SiteData["SiteSlug"], version: "1.0.0" });
}