feat: add MCP server core, stdio and streamable HTTP transports and serve command

Low-level SDK server built from the catalog plus gitea_api_request, with TOOLSETS/READ_ONLY/DISABLED_TOOLS filters, schema validation without value echo, one audit event per call, static bearer verifier, identity resolver hook, /health, DNS-rebinding protection, rate limiting and fail-closed startup checks.
This commit is contained in:
Latte committed 2026-10-14 16:13:11 +02:00
1 parent 581ca67bf8
commit c9e2c481e7
11 files changed
+2846 -14

No files matched your search

+27 -1
View File
@@ -122,8 +122,23 @@ class AuditLogger:
correlation_id: str | None = None,
result_status: str = "pending",
error: str | None = None,
*,
domain: str | None = None,
method: str | None = None,
path: str | None = None,
identity_login: str | None = None,
identity_mode: str | None = None,
sudo: str | None = None,
outcome: str | None = None,
duration_ms: float | None = None,
) -> str:
"""Log an MCP tool invocation."""
"""Log an MCP tool invocation.
The keyword-only fields describe a server tool call (tool domain, HTTP
method, path template, identity, sudo target, outcome and duration). They
are only written when given. Callers must pass argument names, never
argument values, in ``params``.
"""
payload: dict[str, Any] = {
"correlation_id": correlation_id or str(uuid.uuid4()),
"tool_name": tool_name,
@@ -132,6 +147,17 @@ class AuditLogger:
"params": params or {},
"result_status": result_status,
}
optional: dict[str, Any] = {
"domain": domain,
"method": method,
"path": path,
"identity_login": identity_login,
"identity_mode": identity_mode,
"sudo": sudo,
"outcome": outcome,
"duration_ms": duration_ms,
}
payload.update({key: value for key, value in optional.items() if value is not None})
if error:
payload["error"] = error
return self._append_entry("tool_invocation", payload)