=== NEW SERVERS ADDED (7) === - servers/closebot — 119 tools, 14 modules, 4,656 lines TS (Stage 7) - servers/google-console — Google Search Console MCP (Stage 7) - servers/meta-ads — Meta/Facebook Ads MCP (Stage 8) - servers/twilio — Twilio communications MCP (Stage 8) - servers/competitor-research — Competitive intel MCP (Stage 6) - servers/n8n-apps — n8n workflow MCP apps (Stage 6) - servers/reonomy — Commercial real estate MCP (Stage 1) === FACTORY INFRASTRUCTURE ADDED === - infra/factory-tools — mcp-jest, mcp-validator, mcp-add, MCP Inspector - 60 test configs, 702 auto-generated test cases - All 30 servers score 100/100 protocol compliance - infra/command-center — Pipeline state, operator playbook, dashboard config - infra/factory-reviews — Automated eval reports === DOCS ADDED === - docs/MCP-FACTORY.md — Factory overview - docs/reports/ — 5 pipeline evaluation reports - docs/research/ — Browser MCP research === RULES ESTABLISHED === - CONTRIBUTING.md — All MCP work MUST go in this repo - README.md — Full inventory of 37 servers + infra docs - .gitignore — Updated for Python venvs TOTAL: 37 MCP servers + full factory pipeline in one repo. This is now the single source of truth for all MCP work.
96 lines
2.4 KiB
TypeScript
96 lines
2.4 KiB
TypeScript
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
import {
|
|
getDefaultEnvironment,
|
|
StdioClientTransport,
|
|
} from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
import { findActualExecutable } from "spawn-rx";
|
|
|
|
export type TransportOptions = {
|
|
transportType: "sse" | "stdio" | "http";
|
|
command?: string;
|
|
args?: string[];
|
|
url?: string;
|
|
headers?: Record<string, string>;
|
|
};
|
|
|
|
function createStdioTransport(options: TransportOptions): Transport {
|
|
let args: string[] = [];
|
|
|
|
if (options.args !== undefined) {
|
|
args = options.args;
|
|
}
|
|
|
|
const processEnv: Record<string, string> = {};
|
|
|
|
for (const [key, value] of Object.entries(process.env)) {
|
|
if (value !== undefined) {
|
|
processEnv[key] = value;
|
|
}
|
|
}
|
|
|
|
const defaultEnv = getDefaultEnvironment();
|
|
|
|
const env: Record<string, string> = {
|
|
...defaultEnv,
|
|
...processEnv,
|
|
};
|
|
|
|
const { cmd: actualCommand, args: actualArgs } = findActualExecutable(
|
|
options.command ?? "",
|
|
args,
|
|
);
|
|
|
|
return new StdioClientTransport({
|
|
command: actualCommand,
|
|
args: actualArgs,
|
|
env,
|
|
stderr: "pipe",
|
|
});
|
|
}
|
|
|
|
export function createTransport(options: TransportOptions): Transport {
|
|
const { transportType } = options;
|
|
|
|
try {
|
|
if (transportType === "stdio") {
|
|
return createStdioTransport(options);
|
|
}
|
|
|
|
// If not STDIO, then it must be either SSE or HTTP.
|
|
if (!options.url) {
|
|
throw new Error("URL must be provided for SSE or HTTP transport types.");
|
|
}
|
|
const url = new URL(options.url);
|
|
|
|
if (transportType === "sse") {
|
|
const transportOptions = options.headers
|
|
? {
|
|
requestInit: {
|
|
headers: options.headers,
|
|
},
|
|
}
|
|
: undefined;
|
|
return new SSEClientTransport(url, transportOptions);
|
|
}
|
|
|
|
if (transportType === "http") {
|
|
const transportOptions = options.headers
|
|
? {
|
|
requestInit: {
|
|
headers: options.headers,
|
|
},
|
|
}
|
|
: undefined;
|
|
return new StreamableHTTPClientTransport(url, transportOptions);
|
|
}
|
|
|
|
throw new Error(`Unsupported transport type: ${transportType}`);
|
|
} catch (error) {
|
|
throw new Error(
|
|
`Failed to create transport: ${error instanceof Error ? error.message : String(error)}`,
|
|
);
|
|
}
|
|
}
|