Portcall
Portcall
ローカル MCP サーバーを HTTP 経由で提供する小さなプラグインゲートウェイです。
この名前は海事のダジャレです: port call — port(港 / ネットワークポート) + call(停泊 / リクエスト)。
概要
Portcall はひとつの HTTP ポートで待ち受け、ひとつ以上の MCP サーバーを個別のパスにマウントします:
/vault/mcp → mcpvault (Obsidian vault)
/healthz → liveness + mount list各マウントは独立した MCP エンドポイントです。クライアントはそれらを個別に登録します。ツールの集約はないため、名前の衝突も、維持すべき名前空間スキームもありません。
localhost の外へのポート公開は意図的に範囲外です。前面にトンネルやリバースプロキシ、あるいは何も置かなくて構いません。Portcall はデフォルトで 127.0.0.1 にバインドし、上流が何かを気にしません。
Related MCP server: mcp-unify
なぜ stdio ブリッジではないのか
stdio MCP サーバーを HTTP に載せる凡庸な方法は、supergateway のような汎用ブリッジです。それは機能しますが、構造上の問題があります: リクエストまたはセッションごとに子プロセスが生成され、その子プロセスの回収は失敗しやすいのです。
特に upergateway では、子プロセスは transport.onclose または transport.onerror からのみ回収されます。正常に完了したステートレスリクエストでは transport.close() を呼ぶものが何もないため、onclose は発火せず、成功したリクエストはすべてプロセスをリークします。クリーンアップされるのは、失敗したリクエストだけです。ステートフルモードではリークしません(セッションタイマーがトランスポートを閉じます)が、その代わりに長時間維持される GET SSE ストリームを保持するため、一部のプロキシでは不都合が生じます。
コマンドを npx でラップするとさらに悪化します。npx は実際のサーバーをフォークするため、子プロセスを kill するとラッパーが死に、孫プロセスが孤児になります。
Portcall の答えは、必要ないときには何も起動しないことです。
アダプタ
アダプタ | 対象 | 仕組み |
| ファクトリをライブラリとしてエクスポートするサーバー | ファクトリをインプロセスで呼び出します。子プロセスが存在しないため、回収するものがありません。 |
| stdio のみを話すサードパーティサーバー | まだ実装されていません。実装された時点で、正常完了時にも子プロセスを回収し、ラッパーコマンド向けのプロセスグループ kill も処理する必要があります。 |
inProcess が注目すべきケースで、セルフホストに値するサーバーをカバーします。たとえば @bitbonsai/mcpvault は createServer(vaultPath, options) をエクスポートして、MCP SDK v2 の Server を返します。その bin エントリは実質 serveStdio(() => createServer(...)) です。Portcall は同じ関数を直接呼び出し、stdio を完全にスキップします。
SDK はリクエストごとに新しいサーバーインスタンスを構築し、リクエストとともに破棄します。そのため、タイムアウト必要のあるセッション状態も、蓄積するハンドルもありません。
プロトコルバージョン
Portcall は @modelcontextprotocol/server v2 で構成され、単一のニラから2つのプロトコル時代を提供します。
Modern (
2026-07-28) — リクエストごとのエンベロープ。リクエストにはMCP-Protocol-Version、Mcp-Method、ツール呼び出しの場合はMcp-Nameヘッダーに加えてparams._metaブロックが含まれます。initializeハンドシェイクも長命セッションもありません。発見はserver/discoverです。Legacy (2025 時代) — デフォルトではステートレスに提供されます。
GETとDELETE(2025 年のセッション操作)は405を返します。PORTCALL_MODERN_ONLY=trueを設定すると、レガシートラフィックを全部拒否します。
モダン時代はリクエストごとであるため、開いたままにする SSE ストリームがありません。これにより、特定のプロキシ問題を回避できます: 一部のリバー每秒プロキシは最初のボディバイトが到着するまで応答ヘッダーを保留し、開いたばかりで無音の SSE ストリームを無期限に停止させます。実際に発生するストリームについては、PORTCALL_KEEPALIVE_MS が SSE コメントフレーム間隔を制御します。前駅のプロキシがバッファリングする場合は値を下げてください。
設定
ホスト固有の値はすべて環境変数から取得します。
変数 | 既定値 | 意味 |
| (必須) | 提供する Obsidian ヴォールトの絶対パス |
|
| TCP ポート |
|
| バインドするインタフェース |
| (未設定) | 静的ベアラートークン。未設定なら認証なし |
| (未設定) | 指定したプラグインを |
| (未設定) | 全てのマウントを |
|
| SSE キープアライブ間隔。 |
|
| 2025 時代のリクエストを提供する代わりに拒否する |
PORTCALL_TOKEN は、各マウントを Authorization: Bearer <token> でゲートします。MCP クライアントの中には、Claude のカスタムコネクタ UI など、リクエストヘッダーを設定する手段がないものもいるため、その場合は代わりに上流でトークンを強制するか(ネットワーク層でアクセス制御する場合はトークンを入れず)、対応する必要があります。
PORTCALL_PATH_PREFIX はまさにそのようなクライアントのフォールバックです。すべてのマウントを任意のセグメント配下へ移し、/vault/mcp を /<prefix>/vault/mcp にし、URL 自体がシークレットを担います。そこから 2 つのことが導かれ、サーバーは両方とも強制します:
404レスポンスはnot_foundとだけ返します。マウントされもを列挙することはありません。マウント一覧は公開の
/healthzから/<prefix>/healthzに移動します。裸の/healthzは応答し続けるため、liveness プローブは動きますが、何のパスも明かしません。
パスプレフィックスはヘッダーよりも弱いととり扱ってください。URL は、プロキシのアクセスログやクラッシュレポート、宛先を記録するものに残ります。 URL は漏れたトークンと同じくらいアクセス権を与えます。これはハードルを上げるだけで、認証ではありません。
どのプラグインをどこにマウントするかは、plugins.config.ts で宣言されます。
実行
Node 24 が必要です(.nvmrc を参照)。
npm install
npm run build
cp .env.example .env # then set PORTCALL_VAULT_PATH
npm startnpm start と npm run dev は、.env があればそれを読み込み、なくても起動します。つまり、デーモンは代わりに環境変数を直接注入できます。すでに環境に設定された変数は上書きされません。
npm run dev は watch 付きの tsx でエントリポイントを実行します。デーモンはビルド済みの出力を実行すべきであり、tsx は使いません。
起動を確認:
curl -s localhost:7100/healthzテスト
npm test # builds, then runs unit and integration tests
npm run typecheckテスト依存関係はありません。ランナーは node:test で、tsx(npm run dev で既に必要)が TypeScript を読み込みます。
統合テストはブラックボックスです。使い捨てヴォールトに対してビルドしたサーバーをエフェメラルポートで起動し、実 HTTP で駆動するため、デーモンが実行するのと同じ成果物を検証します。ルーティング、/mcp エイリアス、ベアラー認証、両方のプロトコル時代を含みます。ユニットテストは、マウント解決とベアラー認証チェックをカバーします。ここでの静かなリグレッションは、エラーではなくクライアントが死んでいるように見えます。
レイアウト
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 buildersライセンス
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