Portcall
{"type":"text"}
Portcall
Una pasarela de plugins pequeña que sirve servidores MCP locales a través de HTTP.
El nombre es un juego de palabras náutico: port call — port (puerto / puerto de red) + call (escala de un barco / petición).
Qué es
Portcall escucha en un puerto HTTP y monta uno o más servidores MCP en rutas separadas:
/vault/mcp → mcpvault (Obsidian vault)
/healthz → liveness + mount listCada montaje es un endpoint MCP independiente. Los clientes los registran por separado: no hay agregación de herramientas, por lo que no hay colisiones de nombres ni esquema de espacios de nombres que mantener.
Exponer el puerto más allá de localhost está deliberadamente fuera de alcance. Pon un túnel, un proxy inverso o nada delante; Portcall se vincula a 127.0.0.1 por defecto y no le importa lo que haya río arriba.
Related MCP server: mcp-unify
Por qué no un puente stdio
La forma obvia de poner un servidor MCP stdio en HTTP es un puente genérico como supergateway. Eso funciona, pero tiene un problema estructural: cada petición o sesión lanza un proceso hijo, y es fácil equivocarse al recolectar esos hijos.
En supergateway concretamente, el hijo solo se reclama desde transport.onclose o transport.onerror. Nada llama a transport.close() en una petición sin estado completada normalmente, por lo que onclose nunca se dispara y cada petición exitosa pierde un proceso — solo las peticiones fallidas se limpian. Su modo con estado no pierde (un temporizador de sesión cierra el transporte), pero mantiene un flujo SSE GET de larga duración, que algunos proxies manejan mal.
Envolver el comando en npx lo empeora: npx bifurca el servidor real, por lo que matar al hijo mata al envoltorio y deja huérfano al nieto.
La respuesta de Portcall es no lanzar nada cuando no es necesario.
Adaptadores
Adaptador | Para | Cómo |
| Servidores que exportan una fábrica como biblioteca | Llama a la fábrica en el mismo proceso. No existe ningún proceso hijo, por lo que no hay nada que recolectar. |
| Servidores de terceros que solo hablan stdio | Aún no implementado. Cuando llegue, debe reclamar al hijo en la finalización normal, no solo en caso de error, y manejar los asesinatos de grupos de procesos para comandos envoltorio. |
inProcess es el caso interesante y cubre los servidores que merece la pena autoalojar. @bitbonsai/mcpvault, por ejemplo, exporta createServer(vaultPath, options) que devuelve un Server del SDK v2 de MCP; su entrada bin es esencialmente serveStdio(() => createServer(...)). Portcall llama a la misma función directamente y se salta stdio por completo.
El SDK crea una instancia de servidor nueva por petición y la elimina con la petición, por lo que no hay estado de sesión que expire ni manejadores que se acumulen.
Versiones del protocolo
Portcall está construido sobre @modelcontextprotocol/server v2, que atiende dos eras de protocolo desde un único manejador:
Moderno (
2026-07-28) — sobre por petición. Las peticiones llevan las cabecerasMCP-Protocol-Version,Mcp-Methody (para llamadas a herramientas)Mcp-Name, además de un bloqueparams._meta. No hay protocolo de inicioinitializeni sesión de larga duración; el descubrimiento esserver/discover.Legado (era 2025) — se sirve sin estado por defecto.
GETyDELETE(operaciones de sesión de 2025) responden405. EstablecePORTCALL_MODERN_ONLY=truepara rechazar el tráfico heredado por completo.
Debido a que la era moderna es por petición, no hay un flujo SSE permanente que mantener abierto. Eso evita una clase de problema de proxy: algunos proxies inversos retienen las cabeceras de respuesta hasta que llega el primer byte del cuerpo, lo que detiene indefinidamente un flujo SSE recién abierto pero silencioso. Para los flujos que sí ocurren, PORTCALL_KEEPALIVE_MS controla el intervalo de comentarios SSE; redúcelo si un proxy delante está almacenando en búfer.
Configuración
Todos los valores específicos del host provienen del entorno.
Variable | Por defecto | Significado |
| (obligatorio) | Ruta absoluta al almacén de Obsidian que se va a servir |
|
| Puerto TCP |
|
| Interfaz de enlace |
| (sin definir) | Token estático de portador. Sin definir significa sin autenticación |
| (sin definir) | Monta también el plugin nombrado en |
| (sin definir) | Sirve cada montaje bajo |
|
| Intervalo de keepalive SSE; |
|
| Rechaza las peticiones de la era 2025 en lugar de servirlas |
PORTCALL_TOKEN protege cada montaje con Authorization: Bearer <token>. Ten en cuenta que algunos clientes MCP — entre ellos la interfaz de conector personalizado de Claude — no ofrecen forma de establecer una cabecera de petición, por lo que para esos el token debe aplicarse río arriba (u omitirse, con el acceso controlado en la capa de red).
PORTCALL_PATH_PREFIX es el recurso para exactamente esos clientes: mueve cada montaje bajo un segmento que elijas, de modo que /vault/mcp se convierte en /<prefijo>/vault/mcp y la propia URL lleva el secreto. De ello se derivan dos cosas, y el servidor las aplica ambas:
Las respuestas
404dicen solonot_found. Nunca enumeran lo que está montado.El listado de montajes sale del
/healthzpúblico y pasa a/<prefix>/healthz. El/healthzsimple sigue respondiendo, por lo que las sondas de actividad siguen funcionando, pero no revela rutas.
Trata un prefijo de ruta como más débil que una cabecera. Las URL llegan a los registros de acceso del proxy, a los informes de errores y a cualquier cosa que registre un destino, y una filtrada otorga el mismo acceso que un token filtrado. Sube el listón: no es autenticación.
Qué plugins están montados, y dónde, se declara en plugins.config.ts.
Ejecución
Requiere Node 24 (ver .nvmrc).
npm install
npm run build
cp .env.example .env # then set PORTCALL_VAULT_PATH
npm startTanto npm start como npm run dev cargan .env si existe y arrancan sin él si no existe, por lo que un demonio puede inyectar el entorno directamente. Las variables ya establecidas en el entorno no se sobrescriben.
npm run dev ejecuta el punto de entrada a través de tsx con watch. Un demonio debería ejecutar la salida compilada, no tsx.
Comprueba que está activo:
curl -s localhost:7100/healthzPruebas
npm test # builds, then runs unit and integration tests
npm run typecheckSin dependencias de prueba: el ejecutor es node:test, y tsx (ya necesario para npm run dev) carga el TypeScript.
Las pruebas de integración son de caja negra. Lanzan el servidor compilado contra un almacén desechable en un puerto efímero y lo manejan a través de HTTP real, por lo que ejercitan el mismo artefacto que ejecuta un demonio: enrutamiento, el alias /mcp, autenticación de portador y ambas eras de protocolo. Las pruebas unitarias cubren la resolución de montajes y la comprobación del portador, donde una regresión silenciosa parecería un cliente muerto en lugar de un error.
Estructura
src/
server.ts HTTP entry point, wiring, health, shutdown
routes.ts mount resolution and URL normalisation
auth.ts bearer token check
config.ts environment parsing
log.ts structured logging
types.ts the Plugin interface
adapters/
inProcess.ts library-factory adapter
plugins/
vault.ts mcpvault
plugins.config.ts which plugins mount at which paths
test/
integration.test.ts black-box tests against the built server
routes.test.ts mount resolution
auth.test.ts bearer token check
helpers.ts server harness and MCP request buildersLicencia
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA universal MCP server that acts as a unified gateway for dynamically connecting and managing multiple MCP servers via a single HTTP endpoint.106MIT
- AlicenseNot gradedqualityCmaintenanceUnifies multiple MCP servers behind a single endpoint with lazy loading, auto-cleanup, Python plugins, and role-based filtering.2MIT

FlowMCP Serverofficial
AlicenseNot gradedqualityDmaintenanceProvides LocalServer and RemoteServer implementations for running MCP servers locally via stdio or remotely via HTTP/SSE, with simple and advanced deployment options.1MIT- AlicenseNot gradedqualityCmaintenanceThis server bridges a stdio MCP server to HTTP, allowing MCP clients that communicate over HTTP to use the server's tools. It includes a per-tool allow/deny filter for security.MIT
Related MCP Connectors
A basic MCP server to operate on the Postman API.
A MCP server built for developers enabling Git based project management with project and personal…
An MCP server that let you interact with Cycloid.io Internal Development Portal and Platform
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/pizza6899-crypto/portcall'
If you have feedback or need assistance with the MCP directory API, please join our Discord server