Snodo.Proxy (snodo_proxy v0.4.1)

Copy Markdown View Source

A supervised proxy that merges catalogs from MCP backends.

Start a proxy with backend specifications, then pass runtime/2 to a Snodo transport. Backend tools and prompts use the configured name prefix. Resource URIs use mcp-proxy://<backend-id>/ so a read always reaches one backend. The proxy keeps one atomic catalog snapshot for discovery and routing.

{:ok, proxy} =
  Snodo.Proxy.start_link(
    backends: [
      [id: "search", target: {:http, "http://127.0.0.1:4001/mcp"}],
      [id: "files", target: {:stdio, "file-server", []}]
    ]
  )

runtime = Snodo.Proxy.runtime(proxy)
{:ok, listener} = Snodo.Transport.StreamableHTTP.Server.start_link(runtime: runtime)

A backend may also use any custom Snodo.Client transport target, or {:direct, runtime} for an in-process server. Backends that disconnect are retried every second. A rejected or conflicting catalog update retains the last accepted catalog and appears in health/1.

Summary

Functions

Adds and connects a backend, rejecting duplicate IDs or catalog collisions.

Returns an OTP child specification for a proxy.

Returns each configured backend's connection and catalog status.

Refreshes one backend's catalog immediately.

Removes a backend and its published catalog entries.

Builds a server runtime backed by the proxy's current catalog.

Starts the proxy supervisor and its configured backends.

Functions

add_backend(proxy, backend)

@spec add_backend(pid(), keyword() | map()) :: :ok | {:error, term()}

Adds and connects a backend, rejecting duplicate IDs or catalog collisions.

child_spec(opts)

@spec child_spec(keyword()) :: Supervisor.child_spec()

Returns an OTP child specification for a proxy.

health(proxy)

@spec health(pid()) :: map()

Returns each configured backend's connection and catalog status.

refresh_backend(proxy, id)

@spec refresh_backend(pid(), String.t()) :: :ok | {:error, term()}

Refreshes one backend's catalog immediately.

remove_backend(proxy, id)

@spec remove_backend(pid(), String.t()) :: :ok | {:error, :not_found}

Removes a backend and its published catalog entries.

runtime(proxy, opts \\ [])

@spec runtime(pid(), keyword()) :: Snodo.Server.Runtime.t()

Builds a server runtime backed by the proxy's current catalog.

:name defaults to "snodo-proxy", :version to the package version, and :authorization accepts a Snodo.Authorization policy. The proxy applies that policy to the merged catalog at discovery and invocation time.

start_link(opts \\ [])

@spec start_link(keyword()) :: Supervisor.on_start()

Starts the proxy supervisor and its configured backends.