UNPKG

@brave/brave-search-mcp-server

Version:

MCP server for Brave Search. Uses the Brave Search API to return results from the web, including ranked links, images, and videos, as well as AI summaries of pages, rich results, and more.

73 lines (72 loc) 2.52 kB
import { randomUUID } from 'node:crypto'; import express from 'express'; import config from '../config.js'; import createMcpServer from '../server.js'; import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; import { ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'; const yieldGenericServerError = (res) => { res.status(500).json({ id: null, jsonrpc: '2.0', error: { code: -32603, message: 'Internal server error' }, }); }; const transports = new Map(); const isListToolsRequest = (value) => ListToolsRequestSchema.safeParse(value).success; const getTransport = async (request) => { // Check for an existing session const sessionId = request.headers['mcp-session-id']; if (sessionId && transports.has(sessionId)) { return transports.get(sessionId); } // We have a special case where we'll permit ListToolsRequest w/o a session ID if (!sessionId && isListToolsRequest(request.body)) { const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, }); const mcpServer = createMcpServer(); await mcpServer.connect(transport); return transport; } // Otherwise, start a new transport/session const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (sessionId) => { transports.set(sessionId, transport); }, }); const mcpServer = createMcpServer(); await mcpServer.connect(transport); return transport; }; const createApp = () => { const app = express(); app.use(express.json()); app.all('/mcp', async (req, res) => { try { const transport = await getTransport(req); await transport.handleRequest(req, res, req.body); } catch (error) { console.error(error); if (!res.headersSent) { yieldGenericServerError(res); } } }); app.all('/ping', (req, res) => { res.status(200).json({ message: 'pong' }); }); return app; }; const start = () => { if (!config.ready) { console.error('Invalid configuration'); process.exit(1); } const app = createApp(); app.listen(config.port, config.host, () => { console.log(`Server is running on http://${config.host}:${config.port}/mcp`); }); }; export default { start, createApp };