Транспорт передаёт сообщения JSON-RPC между клиентом и вашим сервером. picomcp поддерживает оба транспорта, которые определяет MCP. Ваши инструменты при этом не меняются.
stdio#
await server.serve();Клиент запускает ваш сервер как дочерний процесс и обменивается с ним JSON, разделённым переводами строк, через stdin и stdout. Так с локальными серверами работают десктопные клиенты и агенты для программирования.
stdout принадлежит протоколу. При работе через stdio picomcp перенаправляет console.log, console.info и console.debug в stderr, так что случайная строка лога не сломает соединение. Клиенты обычно показывают stderr в своих логах.
Streamable HTTP#
const running = await server.serve({ http: 3000 });
console.error(`Listening on ${running.url}`); // http://127.0.0.1:3000/mcpserve({ http }) запускает сервер на Bun, Deno или Node — в той среде, где он выполняется. Параметры:
| Параметр | По умолчанию | Описание |
|---|---|---|
port | 3000 | Порт. 0 выбирает свободный. |
hostname | "127.0.0.1" | Укажите "0.0.0.0", чтобы принимать подключения с других машин. |
path | "/mcp" | Путь эндпоинта. На другие пути сервер отвечает 404. |
Возвращает { url, close() }.
fetch-обработчик#
server.fetch — это функция (Request) => Promise<Response> по веб-стандартам. Передайте её любой среде или фреймворку, которые работают с fetch:
Bun.serve({ port: 3000, fetch: server.fetch });Deno.serve({ port: 3000 }, server.fetch);export default { fetch: server.fetch }; // Cloudflare Workersserver.fetch не смотрит на путь: направляйте к нему запросы сами. Другие платформы — в разделе Развёртывание.
Как picomcp работает с HTTP#
picomcp использует Streamable HTTP в режиме JSON без состояния:
POSTс сообщением JSON-RPC или пакетом →200с JSON-ответом, либо202для уведомлений.GETиDELETE→405: так клиенты узнают, что поток от сервера к клиенту не предоставляется.OPTIONS→ CORS preflight для разрешённых источников.- Неподдерживаемый заголовок
MCP-Protocol-Version→400.
Сессий хранить не нужно, поэтому любой экземпляр может ответить на любой запрос. Благодаря этому picomcp без дополнительной работы подходит для serverless-платформ, балансировщиков нагрузки и автомасштабирования.
Источники и DNS rebinding#
Браузеры отправляют заголовок Origin. Вредоносная страница могла бы с его помощью добраться до сервера на вашей машине, поэтому picomcp его проверяет:
- Запросы без
Origin(CLI, серверы, десктопные приложения) разрешены всегда. - По умолчанию разрешены только источники
localhost,127.0.0.1и[::1], на любом порту. - Остальные источники получают
403.
Разрешите другие источники параметром origins:
pico({ name: "notes", origins: ["https://claude.ai", "https://app.example.com"] });
pico({ name: "public", origins: "*" }); // any origin: only for public, unauthenticated serversСвои транспорты#
server.handle(message) обрабатывает одно сообщение JSON-RPC или пакет и возвращает ответ. Для уведомлений он возвращает undefined. С его помощью picomcp подключается к WebSocket, очередям сообщений и чему угодно ещё:
socket.on("message", async (data) => {
const response = await server.handle(JSON.parse(data));
if (response) socket.send(JSON.stringify(response));
});