{"ref":"artifact:arc-mcp-hub","page":"/artifacts/arc-mcp-hub","json":"/artifacts/arc-mcp-hub.json","generated":"2026-10-26","drafted_with_ai":true,"entity":{"id":"arc-mcp-hub","name":"arc-mcp-hub","artifact_type":"mcp-server","ecosystem":"btp","serves_ecosystems":["abap"],"domain":"ai-and-agents","secondary_domains":["security-and-compliance"],"origin_ring":"independent","description":{"one_line":"A hub on SAP BTP that puts several [arc-1](artifact:arc-mcp-arc-1) instances, one per SAP system, behind one login and a route each, exchanging the caller's token through a [destination](artifact:btp-destination) so each system still sees the real user.","short":"Hub on SAP BTP putting several arc-1 instances behind one login","what_it_solves":"Running arc-1 against DEV, QA and PROD means three MCP servers configured separately in every client, each with its own login. The hub is one Cloud Foundry application in the same subaccount, which mounts `/dev/mcp`, `/qa/mcp` and `/prod/mcp` from a list of destinations, validates the caller once as an OAuth 2.1 resource server, exchanges that token through an `OAuth2JWTBearer` destination for one scoped to the backend, and bridges the Streamable HTTP session to it with the backend's tools unchanged. Which system a call lands on is decided by the endpoint the client connected to rather than by the model; an optional `/all` endpoint trades that for one connection where every tool carries a required `system` parameter. Nothing reasons in the middle and no shared service account is involved, since the backend propagates the user to SAP, so a developer who authenticates but lacks the role collection can connect to `/prod/mcp` and do nothing. Adding a system is a destination and one more entry in `HUB_BACKENDS`, and any XSUAA-protected Streamable HTTP MCP server qualifies as a backend.","when_not_to_use":"With one SAP system the README says to point the client at that arc-1 directly. Version 1 exchanges tokens within a single subaccount, so backends spread across subaccounts are out; it keeps its session map in memory, so more than one instance needs sticky sessions or a shared store. It routes deterministically and runs no model, which is a different thing from an assistant that reasons across systems. The `/all` endpoint drops the per-connection isolation, and the maintainer's answer to that is a PROD backend set read-only at the SAP end rather than a tool surface that hides the writes."},"links":{"repo":"https://github.com/arc-mcp/mcp-hub"},"identity":{"license":"MIT"},"source_available":true,"provides":[{"capability":"capability:tool-governance","what_it_does":"Decides which SAP system an agent's call can reach by which endpoint it connected to, exchanges the caller's token for one scoped to that backend, and binds a session to the principal that opened it, so the authorisation question is answered by SAP for the real user.","sources":[{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"**Connection-scoped systems.** A session on `/dev/mcp` can only ever see DEV's tools."},{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"exchanges it via a **BTP destination**"},{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"no shared service account and no LLM in the path."}]}],"requires":[{"ref":"artifact:btp-destination","requirement":"required","for":"one destination per backend, which both resolves the backend's URL and carries the `OAuth2JWTBearer` exchange that produces the per-user token","sources":[{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"`HUB_BACKENDS` | yes | JSON array of `{ name, destination, description? }`."},{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"exchanges it via a **BTP destination**"}]},{"ref":"artifact:btp-cloud-foundry-runtime","requirement":"required","for":"the runtime it is pushed to, in the same subaccount as the backends it fronts","sources":[{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"**Deploy** the hub into the **same BTP subaccount** as your ARC-1 instances"}]},{"ref":"artifact:arc-mcp-arc-1","requirement":"conditional","condition":"the backends are ARC-1 instances, which is the documented setup; the requirement the README states of a backend is XSUAA protection and Streamable HTTP, which another MCP server can meet","for":"the backends the hub fronts, one instance per SAP system, each doing its own principal propagation to SAP","sources":[{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"You want to front **other SAP MCP servers** too, not only ARC-1 — any XSUAA-protected,"}]}],"maintainers":["actor:arc-mcp"],"compat":{"runtimes":["node"],"deployment":["cf"]},"type_properties":{"runs":{"value":["central-server"],"sources":[{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"**Deploy** the hub into the **same BTP subaccount** as your ARC-1 instances"}]},"transports":{"value":["http"],"sources":[{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"You connect your MCP client to `https://<hub>/dev/mcp` (or `/qa/mcp`, `/prod/mcp`)."}]},"auth":{"value":["oauth","destination","principal-propagation"],"sources":[{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"The hub is an OAuth 2.1 resource server (one shared authorization server → one login)."},{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"exchanges it via a **BTP destination**"},{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"Per-user identity. Every call runs as the **logged-in user** via principal propagation"}]},"guardrails":[{"source":{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"**Connection-scoped systems.** A session on `/dev/mcp` can only ever see DEV's tools."}},{"source":{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"**PROD is read-only at the backend.**"}},{"source":{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"Each MCP session is **bound to the principal that created it**"}},{"source":{"url":"https://raw.githubusercontent.com/arc-mcp/mcp-hub/main/README.md","title":"arc-mcp/mcp-hub — README","checked":"2026-09-20","quote":"**The hub has no local authorization gate — by design.**"}}]},"provenance":{"discovered_via":[{"source":"source:github","channel":"arc-mcp"}],"first_seen":"2026-09-18"},"drafted_with_ai":true,"contributors":["actor:marianfoo"]},"effective_normative_relations":[],"readings":{"liveness":[{"label":"Maintenance","tier":"unknown","evidence":"no release data"},{"label":"Continuity","tier":"fair","evidence":"1 contributor, org-owned"},{"label":"Repository","tier":"poor","evidence":"archived on GitHub"}],"compatibility":[{"label":"Declared for","tier":"unknown","evidence":"no BTP release lines in the atlas"},{"label":"Survived majors","tier":"unknown","evidence":"no BTP release lines in the atlas"},{"label":"Maintainer's CI","tier":"good","evidence":"CI green, 2026-10-05"}],"practice":[{"label":"Tests","tier":"good","evidence":"8 test files"},{"label":"Docs","tier":"good","evidence":"docs/ with 7 pages, README 3 KB"},{"label":"Changelog","tier":"fair","evidence":"none in the repo"}],"reach":[{"value":null,"unit":"installs/week"},{"value":0,"unit":"watching"}]},"signals":{"crawled_at":"2026-10-24","npm":"not published under this name","stars":0,"forks":0,"open_issues":0,"archived":true,"pushed_at":"2026-10-05","license_spdx":null,"org_owned":true,"default_branch":"main","created_at":"2026-06-18T19:31:02Z","open_prs":0,"tree_truncated":false,"test_files":8,"workflows":1,"other_ci":false,"readme_bytes":3007,"docs_files":7,"changelog":false,"license_file":false,"dts_files":0,"first_commit":"2026-06-18","last_commit":"2026-10-05","commits":11,"contributors":1,"ci_status":"success","ci_run_at":"2026-10-05","ci_workflow":"CI","ci_event":"push","readme_path":"README.md","readme_sha":"8c9bcb7ee7a598a9b1b2f0eb53c8f84ef00809dd","repo_read":"2026-10-24"},"edges":{"maintainers":[{"ref":"actor:arc-mcp","name":"ARC MCP","json":"/actors/arc-mcp.json"}],"contributors":[{"ref":"actor:marianfoo","name":"Marian Zeis","json":"/actors/marianfoo.json"}],"explained_by":[],"alternative_to_this":[],"needed_by":[],"available_via":[],"parts":[],"add_ons":[],"answered_through_parts":[]}}