@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
JavaScript
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 };