Hub Proxy Client Configuration
Per-client setup instructions for connecting to PodWarden through Hub
This page covers client-specific configuration for connecting to PodWarden through Hub. See Hub MCP Proxy for the overview and tunnel setup.
Let the dashboard write the config for you
The fastest route is not to assemble any of this by hand. Hub builds the finished configuration, with your instance's real UUID and — for a token connection — the real secret already substituted:
- Sign in to Hub and open Dashboard → MCP access (/dashboard/mcp)
- Stay on the PodWarden Core instances tab. Each connected Core is a card
showing its address,
https://mcp.podwarden.com/<instance-uuid>, with a copy button - Click Connect an AI client on the card for the Core you want
- Pick OAuth or Access token, then copy the block it shows you
The dialog opens from an instance card, so it is there once a Core has connected. If none has yet, mint a token on API Keys instead and assemble the configuration from the snippets below.
The rest of this page is the equivalent configuration per client. The dialog emits a single native-HTTP form; some clients need it adapting, which is why the Claude Desktop sections below differ from what the dialog shows.
The two endpoints
There are two ways to authenticate and they use different URLs. Using the wrong URL for your credential is the most common way a connection fails.
| OAuth | Personal access token | |
|---|---|---|
| URL | https://mcp.podwarden.com/<instance-uuid> | https://mcp.podwarden.com/mcp — no path segment |
| Auth header | none | Authorization: Bearer pwp_... |
| Who it acts as | you, for as long as the session lasts | the person who minted the token |
| Best for | a desktop client you sit in front of | an agent, a runner, or a headless box |
Do not put a UUID in the path of a token connection. A personal access token
already carries the one instance it may reach, and Hub refuses a path that
disagrees with the token's scope rather than reconciling it — so a /<uuid> URL
that happens to match works only by coincidence and breaks the moment the snippet
is reused for a different token.
Finding your instance UUID
The UUID is minted by the Core itself on first run and stored in the Core's own database, so it survives a database move or restore. You can read it from:
- the instance card on Dashboard → MCP access, which shows the whole address and copies it in one click; or
list_instancesfrom an already-connected MCP session, which reports the instances in your organization and their UUIDs.
Do not assume the example host
Hub can be deployed on more than one MCP host, and mcp.podwarden.com is only the
one used in the examples on this page. The address on your instance card is the
authoritative one — it is what the dashboard's Connect dialog builds its configs
from. Use it rather than the example host, and keep whatever host it gives you when
you switch between the two URL shapes above.
Personal access token
Mint one while signed in to Hub. You give it a name and an expiry — 30 days, 90 days, 1 year, or no expiry, with 90 days preselected. The secret is shown once.
Which instance it is scoped to depends on where you mint it. In the Connect an AI client dialog the scope is fixed to the Core whose card you opened it from and is shown read-only. On the API Keys page you pick the instance from a list.
To reach a second instance, mint a second token. There is no way to move an existing token to another instance — its scope is fixed at mint.
Claude Desktop
Claude Desktop uses mcp-remote as a stdio-to-HTTP bridge. Requires Node.js.
{
"mcpServers": {
"podwarden": {
"command": "npx",
"args": [
"mcp-remote",
"https://mcp.podwarden.com/mcp",
"--header",
"Authorization:${PODWARDEN_HUB_TOKEN}"
],
"env": {
"PODWARDEN_HUB_TOKEN": "Bearer pwp_YOUR_TOKEN_HERE"
}
}
}
}The token is placed in env rather than inline in args to avoid a Windows escaping bug.
Claude Code
claude mcp add --transport http podwarden https://mcp.podwarden.com/mcp \
--header "Authorization: Bearer pwp_YOUR_TOKEN_HERE"Cursor
Open Cursor Settings > MCP > "Add new global MCP server" and paste:
{
"mcpServers": {
"podwarden": {
"url": "https://mcp.podwarden.com/mcp",
"headers": {
"Authorization": "Bearer pwp_YOUR_TOKEN_HERE"
}
}
}
}OAuth
Clients that add a remote MCP server and sign you in interactively need no token at all. Point them at the instance you want — one connection addresses one instance, so add one remote server per Core.
Clients that take a remote HTTP server
This is the form the dashboard's Connect dialog emits. Replace the UUID with your own instance's, and name the server after the Core so several connections stay tellable apart.
{
"mcpServers": {
"podwarden-home": {
"type": "http",
"url": "https://mcp.podwarden.com/00000000-0000-0000-0000-000000000000"
}
}
}Claude Desktop is the exception. It does not accept a url entry for a remote MCP
server — it needs the mcp-remote bridge, as in the token configuration
above. We have not verified an OAuth-over-mcp-remote configuration, so this page
does not print one; use Claude Desktop's own "Add connector" dialog, which does its
own OAuth sign-in, or connect Claude Desktop with a personal access token instead.
Claude Code (OAuth)
claude mcp add --transport http podwarden-home \
https://mcp.podwarden.com/00000000-0000-0000-0000-000000000000What happens on the first call
- The client calls the URL with no credential and receives a
401carrying aWWW-Authenticatechallenge. - It opens your browser to sign in. You sign in once.
- The Core's tools appear. Every later call is attributed to your user id and re-checked against your organization — the instance in the path never grants access on its own.
The session expires. When it does, the client repeats step 1 and you sign in again. That is the trade against a personal access token, which does not expire until you give it an expiry or revoke it.
Other clients
Any MCP-compatible client can connect using the Streamable HTTP transport.
| Setting | Token connection | OAuth connection |
|---|---|---|
| Endpoint | https://mcp.podwarden.com/mcp | https://mcp.podwarden.com/<instance-uuid> |
| Transport | Streamable HTTP | Streamable HTTP |
| Auth header | Authorization: Bearer pwp_YOUR_TOKEN_HERE | none — the client is challenged and signs in |
What each connection can reach
Both methods reach the same six-tool Hub facade described in
Hub MCP Proxy, with one difference: a
personal access token does not get memory_search or memory_save. Organization
memory is a shared human workspace, and a long-lived agent token writing notes
under its minter's name is not a default worth having. A token connection
therefore sees four tools: find, call_instance_tool, list_instances, and
load_skill.
Tools that require a live human at a browser — node access grants, for instance —
are filtered out of find's results for a token connection, and are refused if
called anyway.
Troubleshooting
Instance shows "Disconnected" in Hub
- Verify Hub URL and instance key (
pwh_) are correct (Settings > Hub > Test Connection) - Check that the tunnel toggle is enabled (Settings > MCP > Hub MCP Tunnel)
- Check PodWarden container logs for "Hub tunnel" messages
- If the instance was recently restarted, wait for the reconnect (up to 5 minutes with backoff)
Tool calls return errors
- Check the access level — if set to "Read Only", mutating tools will return errors
- Verify the tool exists on your instance (
find) - Check PodWarden's MCP Activity Log for error details
"No instances connected" from AI client
- Your PodWarden instance may not have connected yet. Check Hub Dashboard > MCP.
- The tunnel takes a few seconds to establish after PodWarden starts.
- If recently restarted, wait for reconnect (up to 5 minutes with backoff).
The instance UUID is refused
First check the status code. A 404 means the path is not a UUID at all — a
truncated or mistyped address never reaches the MCP handler and falls through to an
ordinary not-found. That is the most likely cause of a first-attempt failure, and it
is deliberate: an unauthenticated request to a non-UUID path must not be answered
with an auth challenge.
A 403 means the address parsed and was then refused. It carries a machine-readable
error field, and which one you get says what to fix:
error | What it means | What to do |
|---|---|---|
instance_not_found | The UUID names no instance in your organization. A UUID from another organization gives this same answer even though it exists — the two cases are deliberately indistinguishable, so the response cannot be used to probe for other tenants' instances. | Re-copy the address from the instance card on Dashboard → MCP access. |
instance_out_of_scope | You put a UUID in the path of a personal access token connection, and it is not the instance that token is scoped to. | Connect to the bare /mcp — the token carries its instance. Or mint a token scoped to the instance you meant. |
instance_not_pinned | The credential is a tunnel key pinned to one instance and the address names a different one. This also fires for every address if the instance the pin names no longer exists in your organization. | Address the instance the pin names. If no address works, that instance is gone: revoke the key and mint a new one. There is no re-pin. |
The connection works but a tool is missing
- A personal access token connection does not get
memory_search/memory_save. Tools that require a live browser session are filtered out offind's results for a token connection and are refused if called anyway. Sign in with OAuth for those. - Check the access level on the Core — if it is set to Read Only, mutating tools return errors.
The client asks me to sign in again
An OAuth session expires. If you want a connection that does not, mint a personal
access token and use the bare /mcp endpoint instead.