router: multi-domain MCP gateway (per-domain + merged) #116
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_router#116
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Make the router's MCP gateway multi-domain. Today the router collapses every service to a single (first) domain; multi-domain services (e.g.
hero_procwithjobs/logs/secrets/system) only expose their first domain over MCP.Model (confirmed): services serve one
rpc.sock, domains are path segments —GET /api/domains.json,GET /api/{domain}/openrpc.json,POST /api/{domain}/rpc,GET /api/{domain}/events. The router's discovery/proxy already follow this; the gap is the MCP layer + spec cache + UI.Gaps (verified on
development)scanner.rs:476-480caches onlydomains.first()'s spec → other domains invisible.ServiceEntryhas a singleopenrpc_json+domains: Vec<String>(names only) — no per-domain specs.POST /mcp/{id}(routes.rs:1514);tools/listuses the oneentry.openrpc_json.tools/callisn't domain-aware; UI/explorer/markdown render one spec.Plan / tasks
ServiceEntry; scanner fetches every domain (not just the first).POST /mcp/{id}/{domain}(per-domain) + keepPOST /mcp/{id}as a merged MCP (domain-qualified tool names).tools/call: resolve(domain, method)and forward to/api/{domain}/rpcon the servicerpc.sock.hero_lib/examples/hero_lifecycle/hero_demo_server); build/verify fromdevelopment.Notes
development_router_multidomain_mcpoffdevelopment; PR →development.access.rsproc-secrets wire fix tracked separately.Covered by PR #118 (
router: multi-domain MCP gateway (per-domain + merged), merged intodevelopment@e7c9e49). All tasks delivered against the confirmed single-rpc.sock/ domains-as-path-segments model:acca99c—ServiceEntry.domain_specs: BTreeMap<String,String>+spec_for_domain()/domain_spec_pairs()(cache.rs:220,251,260); scanner fetches every domain's/api/{domain}/openrpc.json, not just the first (scanner.rs:455-480).51eef73—POST /mcp/{id}(merged, domain-qualified tool names viaDOMAIN_SEP = "__") andPOST /mcp/{id}/{domain}(per-domain, plain names) (routes.rs:1525,1533;mcp.rs:34,91,103).tools/call✅51eef73—proxy_to_service()resolves(domain, method)and forwards to/api/{domain}/rpcon the singlerpc.sock(mcp.rs:791,809).f48fb3e—/mcpoverview lists merged + per-domain endpoints (mcp.html:165-170); the OpenRPC explorer renders all domains via a selector hitting/api/{domain}/openrpc.json+/api/{domain}/rpc(service_openrpc.html:35,55-67).1aef9bf— per-domain + merged cases against the two-domain demo server (hero_router_test/src/functional/mcp.rs:63-113), live-verified (mergedalpha__alpha_ping/ per-domainalpha_ping;tools/calllands on the right domain).Closing as done. (Minor cosmetic follow-up, not blocking: a stale doc comment at
routes.rs:466still references the oldrpc_<domain>.sockmodel — the code itself uses the correct single-socket paths.)