Server composition: mount multiple urfave trees into one MCP surface #4

Closed
opened 2026-05-23 20:53:53 +00:00 by coilysiren · 0 comments
Owner

Originally filed by @coilysiren on 2026-05-13T14:23:30Z - https://github.com/coilysiren/cli-mcp/issues/39

FastMCP supports composing multiple servers via mount() (live binding, child changes propagate) and import_server() (snapshot copy), with automatic namespacing: my_toolns_my_tool, data://infodata://ns/info.

Today cli-mcp projects a single *cli.Command root. There's no first-class way to merge two CLI trees (e.g. two sibling repos' .coily/coily.yaml-derived urfave trees) into one MCP server without manually building a wrapper root.

Proposal: climcp.Mount(server *mcp.Server, prefix string, child *cli.Command, opts Options) error. Adds the child's leaves to the existing server with prefix. prepended to every tool name. prefix == "" for flat merge, with collision detection.

Use case that motivates this: coily could in theory expose a single MCP server that aggregates verbs from every .coily/coily.yaml in the current workspace's repo siblings. Each repo's verbs get namespaced by repo name. One MCP endpoint, every workspace verb reachable.

Open questions:

  • Live binding (child changes propagate) vs snapshot? In Go, the urfave tree is usually built once at startup, so snapshot is probably enough.
  • Conflict policy when prefix collides: error, overwrite, or rename-with-suffix?
  • Resource/prompt namespacing isn't relevant for cli-mcp today (no resources/prompts), so this is tools-only for v1.
_Originally filed by @coilysiren on 2026-05-13T14:23:30Z - [https://github.com/coilysiren/cli-mcp/issues/39](https://github.com/coilysiren/cli-mcp/issues/39)_ [FastMCP][fastmcp] supports composing multiple servers via `mount()` (live binding, child changes propagate) and `import_server()` (snapshot copy), with automatic namespacing: `my_tool` → `ns_my_tool`, `data://info` → `data://ns/info`. Today cli-mcp projects a single `*cli.Command` root. There's no first-class way to merge two CLI trees (e.g. two sibling repos' `.coily/coily.yaml`-derived urfave trees) into one MCP server without manually building a wrapper root. Proposal: `climcp.Mount(server *mcp.Server, prefix string, child *cli.Command, opts Options) error`. Adds the child's leaves to the existing server with `prefix.` prepended to every tool name. `prefix == ""` for flat merge, with collision detection. Use case that motivates this: `coily` could in theory expose a single MCP server that aggregates verbs from every `.coily/coily.yaml` in the current workspace's repo siblings. Each repo's verbs get namespaced by repo name. One MCP endpoint, every workspace verb reachable. Open questions: - Live binding (child changes propagate) vs snapshot? In Go, the urfave tree is usually built once at startup, so snapshot is probably enough. - Conflict policy when prefix collides: error, overwrite, or rename-with-suffix? - Resource/prompt namespacing isn't relevant for cli-mcp today (no resources/prompts), so this is tools-only for v1. [fastmcp]: https://github.com/jlowin/fastmcp
coilysiren 2026-05-30 05:44:18 +00:00
  • closed this issue
  • added the
    icebox
    label
Commenting is not possible because the repository is archived.
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilysiren/cli-mcp#4
No description provided.