Initial curated ITWorx_MCP_Hub source from 368fba691ea8d23403b4d56b53b5ec670d7c5020
This commit is contained in:
commit
cb5be898ea
663 files changed
+82674
No files matched your search
@@ -0,0 +1,80 @@
|
||||
"""Minimal JSON-lines stdio bridge; tokens are read only for the call and never emitted."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
from collections.abc import Callable, Iterable, Iterator, Mapping
|
||||
from typing import Any, Protocol
|
||||
|
||||
|
||||
class BridgeTransport(Protocol):
|
||||
def send(
|
||||
self, request: Mapping[str, Any], *, token: str, endpoint: str
|
||||
) -> Mapping[str, Any] | None: ...
|
||||
|
||||
|
||||
class StdioBridge:
|
||||
"""Translate bounded JSON-lines messages to remote MCP without shell or token output."""
|
||||
|
||||
ALLOWED_METHODS = frozenset(
|
||||
{
|
||||
"initialize",
|
||||
"notifications/initialized",
|
||||
"ping",
|
||||
"tools/list",
|
||||
"tools/call",
|
||||
"resources/list",
|
||||
"resources/templates/list",
|
||||
"resources/read",
|
||||
"prompts/list",
|
||||
"prompts/get",
|
||||
}
|
||||
)
|
||||
|
||||
def __init__(self, *, endpoint: str, token_env: str | None = None) -> None:
|
||||
if not endpoint.startswith("https://"):
|
||||
raise ValueError("stdio bridge endpoints must use HTTPS")
|
||||
self.endpoint = endpoint
|
||||
self.token_env = token_env or "ITWORX_MCP_ACCESS_TOKEN"
|
||||
|
||||
def forward(
|
||||
self,
|
||||
lines: Iterable[str],
|
||||
transport: BridgeTransport,
|
||||
*,
|
||||
environ: Mapping[str, str] | None = None,
|
||||
token_provider: Callable[[], str] | None = None,
|
||||
) -> Iterator[str]:
|
||||
values = environ if environ is not None else os.environ
|
||||
static_token = values.get(self.token_env)
|
||||
if not static_token and token_provider is None:
|
||||
yield _error("authentication_required")
|
||||
return
|
||||
for raw in lines:
|
||||
if len(raw.encode("utf-8")) > 4 * 1024 * 1024:
|
||||
yield _error("request_too_large")
|
||||
continue
|
||||
try:
|
||||
request = json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
yield _error("invalid_json")
|
||||
continue
|
||||
if not isinstance(request, dict) or request.get("method") not in self.ALLOWED_METHODS:
|
||||
yield _error("unsupported_method")
|
||||
continue
|
||||
try:
|
||||
token = token_provider() if token_provider is not None else static_token
|
||||
if not token:
|
||||
yield _error("authentication_required")
|
||||
continue
|
||||
result = transport.send(request, token=token, endpoint=self.endpoint)
|
||||
if result is not None:
|
||||
yield json.dumps(dict(result), separators=(",", ":"))
|
||||
except Exception:
|
||||
yield _error("upstream_unavailable")
|
||||
del static_token
|
||||
|
||||
|
||||
def _error(code: str) -> str:
|
||||
return json.dumps({"error": {"code": code}}, separators=(",", ":"))
|
||||
Reference in new issue
Block a user