61 lines
1.5 KiB
TypeScript
61 lines
1.5 KiB
TypeScript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
import { FetchSSEServerTransport } from "./fetch-transport.server";
|
|
import { registerMcpTools } from "./mcp-tools.server";
|
|
|
|
type McpToolRegistrar = (server: McpServer) => void;
|
|
|
|
export const server = new McpServer(
|
|
{
|
|
name: "app-mcp",
|
|
version: "1.0.0",
|
|
},
|
|
{
|
|
capabilities: {
|
|
tools: {},
|
|
},
|
|
}
|
|
);
|
|
|
|
// Register MCP tools
|
|
registerMcpTools(server);
|
|
|
|
// Tool registrar storage for app-specific tools
|
|
const toolRegistrars: McpToolRegistrar[] = [];
|
|
|
|
/**
|
|
* Register a tool registrar that will add custom MCP tools.
|
|
* This allows apps to extend the MCP server with their own tools.
|
|
*/
|
|
export function addToolRegistrar(registrar: McpToolRegistrar) {
|
|
toolRegistrars.push(registrar);
|
|
registrar(server);
|
|
}
|
|
|
|
const transports = new Map<string, FetchSSEServerTransport>();
|
|
const MAX_TRANSPORTS = 64;
|
|
|
|
export async function connect(sessionId?: string | null) {
|
|
const transport = new FetchSSEServerTransport("/mcp", sessionId);
|
|
transport.onclose = () => {
|
|
transports.delete(transport.sessionId);
|
|
};
|
|
await server.connect(transport);
|
|
pruneTransports();
|
|
transports.set(transport.sessionId, transport);
|
|
return transport;
|
|
}
|
|
|
|
export async function getTransport(sessionId: string) {
|
|
return transports.get(sessionId);
|
|
}
|
|
|
|
function pruneTransports() {
|
|
while (transports.size >= MAX_TRANSPORTS) {
|
|
const oldestSessionId = transports.keys().next().value;
|
|
if (!oldestSessionId) {
|
|
return;
|
|
}
|
|
transports.delete(oldestSessionId);
|
|
}
|
|
}
|