feat: compose authenticated stdio MCP with explicit runtime tool mapping
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e747-8f27-7242-8df8-8bc44f88c929
This commit is contained in:
parent
1ece969f59
commit
3c5cbfbafe
14 changed files with 465 additions and 81 deletions
|
|
@ -25,6 +25,7 @@ def build_parser(settings: RuntimeSettings | None = None) -> argparse.ArgumentPa
|
|||
mcp.add_argument("--port", type=int, default=resolved.mcp_port)
|
||||
mcp.add_argument("--transport", default=resolved.mcp_transport)
|
||||
mcp.add_argument("--api-base", default=resolved.api_base)
|
||||
mcp.add_argument("--token-file", type=Path, help="projected Hub credential for single-principal stdio only")
|
||||
|
||||
migrate = commands.add_parser("migrate", help="Run packaged Alembic migrations")
|
||||
migrate.add_argument("revision", nargs="?", default="head")
|
||||
|
|
@ -87,7 +88,7 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|||
_run_api(args.host, args.port)
|
||||
return 0
|
||||
if args.command == "mcp":
|
||||
_run_mcp(args.host, args.port, args.transport, args.api_base)
|
||||
_run_mcp(args.host, args.port, args.transport, args.api_base, args.token_file)
|
||||
return 0
|
||||
if args.command == "migrate":
|
||||
if not args.database_url:
|
||||
|
|
@ -109,11 +110,22 @@ def _run_api(host: str, port: int) -> None:
|
|||
uvicorn.run("hub_core.runtime.app:app", host=host, port=port)
|
||||
|
||||
|
||||
def _run_mcp(host: str, port: int, transport: str, api_base: str) -> None:
|
||||
def _run_mcp(host: str, port: int, transport: str, api_base: str,
|
||||
token_file: Path | None = None) -> None:
|
||||
from hub_core.mcp.credentials import StdioTokenFile
|
||||
enforced = RuntimeSettings.from_env().enforce_access
|
||||
if token_file is not None and transport != "stdio":
|
||||
raise SystemExit("--token-file is restricted to single-principal stdio")
|
||||
if enforced and (transport != "stdio" or token_file is None):
|
||||
raise SystemExit("enforced MCP requires stdio and --token-file; network MCP needs an authenticated host composition")
|
||||
provider = StdioTokenFile(token_file) if token_file is not None else None
|
||||
server = HubCoreMCPServer(name="hub-core", api_base=api_base,
|
||||
require_credentials=RuntimeSettings.from_env().enforce_access,
|
||||
trailing_slash=False)
|
||||
server.mcp.run(transport=transport, host=host, port=port)
|
||||
token_provider=provider, require_credentials=enforced or provider is not None,
|
||||
backend_profile="runtime")
|
||||
if transport == "stdio":
|
||||
server.mcp.run(transport="stdio")
|
||||
else:
|
||||
server.mcp.run(transport=transport, host=host, port=port)
|
||||
|
||||
|
||||
def _run_migrations(database_url: str, revision: str) -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue