Skip to content

Features: add mcp proxy#9

Open
yapishu wants to merge 4 commits into
mainfrom
reid/mcp-proxy
Open

Features: add mcp proxy#9
yapishu wants to merge 4 commits into
mainfrom
reid/mcp-proxy

Conversation

@yapishu
Copy link
Copy Markdown
Collaborator

@yapishu yapishu commented Apr 10, 2026

This PR merges the urbit-mcp-proxy desk into %mcp as a single integrated control plane.

Features

  • Aggregate proxy endpoint at /apps/mcp/mcp. Point MCP client here and it sees the union of every upstream
    you've configured, with tools namespaced by server id.
    • Original MCP server is automatically added as a default upstream
    • Per-upstream tool allow/block lists, editable from the UI, so you can expose a narrow subset of a large API.
  • Upstream support for three types:
    • Remote MCP servers (HTTP transport, proxied through iris)
    • OpenAPI 3.0 REST APIs — the spec is fetched, cached, and dynamically converted to MCP tool calls on the fly
    • Google Discovery documents — auto-detected and walked recursively into MCP tools
  • OAuth 2.0 + PKCE manager (%oauth agent). Store provider credentials and config, attach them to upstreams, and the proxy injects bearer tokens per request. Grants are refreshed automatically before expiry with single-flight locking. Client secrets stay on the ship and are never surfaced to the browser.
    • This has been successfully tested with the X/Twitter and GMail APIs
  • GUI console at /apps/mcp

Note about breaking changes

I refactored the auth to use an X-API-Key header, both on the original /mcp endpoint as well as the new aggregated /apps/mcp/mcp endpoint; this is user-definable. With proxied tool whitelisting this allows for scoped clients, but breaks previously configured clients.

This is the only change to the original MCP server functionality, everything else is additive.

GUI screenshots

image image image

@yapishu yapishu requested a review from bonbud-macryg April 10, 2026 14:07
@github-actions
Copy link
Copy Markdown

Groundwire Verification Failed

This PR will not be reviewed because commits are not signed by a recognized Groundwire ID.

NOT_GROUNDWIRE 76340c90

Why?

This repository requires contributors to prove ownership of an onchain Groundwire identity.
Commit signatures are cryptographically verified against the signer's on-chain networking key.

How to fix this

  1. Get a Groundwire IDgroundwire.io/guide.html
  2. Install commit signing./hooks/install.sh <your-ship-url>
  3. Re-sign your commitsgit rebase --exec "true" HEAD~N (after configuring signing)

This repository is protected by Groundwire for GitHub.

Copy link
Copy Markdown
Contributor

@bonbud-macryg bonbud-macryg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise staggering genius, very cool

Comment thread desk/lib/docket.hoon
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls import in /peru.yaml at the root of this repo, same for all other Landscape dependencies.

Comment thread README.md
Comment on lines +9 to +15
2. **MCP proxy** at `/apps/mcp/mcp` — aggregates the native server plus any
number of remote MCP / OpenAPI / Google Discovery upstreams behind a single
endpoint, with per-server tool filtering and OAuth 2.0 + PKCE token
management. OpenAPI and Discovery spec docs are dynamically converted
to MCP tool calls.
3. **Operator console** at `/apps/mcp/` — a web UI for configuring upstreams,
OAuth providers, the API key, and inspecting tools.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The endpoint situation with /mcp and /apps/mcp is kind of weird now, clean layout might be:

  • /mcp - Urbit MCP endpoint
  • /apps/mcp - Urbit MCP UI
  • /mcp/servers - MCP proxy endpoint
  • /mcp/servers/{id} - endpoint for a single proxied MCP server

Comment thread README.md

Get your ship's web login code from the Dojo:
- `%mcp-server` — native MCP server bound to `/mcp`
- `%mcp-proxy` — aggregator bound to `/apps/mcp/api` and `/apps/mcp/mcp`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Endpoint layout as above

Comment thread desk/sur/mcp-proxy.hoon
Comment on lines +41 to +81
+$ state-0
$: %0
servers=(map server-id mcp-server-0)
server-order=(list server-id)
==
::
+$ state-1
$: %1
servers=(map server-id mcp-server-1)
server-order=(list server-id)
==
::
+$ state-2
$: %2
servers=(map server-id mcp-server)
server-order=(list server-id)
==
::
+$ state-3
$: %3
servers=(map server-id mcp-server)
server-order=(list server-id)
tool-filters=(map server-id tool-filter)
==
::
+$ state-4
$: %4
servers=(map server-id mcp-server)
server-order=(list server-id)
tool-filters=(map server-id tool-filter)
client-key=(unit @t) :: user-set x-api-key for /apps/mcp/mcp
internal-token=(unit @t) :: mcp-server's auto-gen token (cached)
==
::
+$ versioned-state
$% state-0
state-1
state-2
state-3
state-4
==
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need all these on the first release?

Comment thread desk/app/oauth.hoon
%- agent:dbug
=| state-0:oauth
=* state -
=/ refreshing *(set provider-id:oauth) :: in-flight refresh locks (non-persisted)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an Tlon convention for transient state in an agent? Never seen this before

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants