tinyhumansai/openhuman · error · anyhow::Error

[mcp-registry] http_remote server_id={} has empty deployment

Error message

[mcp-registry] http_remote server_id={} has empty deployment_url

What it means

The dynamic MCP registry (`mcp_clients`) tried to connect to a server recorded with `Transport::HttpRemote` whose `url` (deployment URL) is an empty string, and bails before dialing. The row exists but its `deployment_url` was never populated — this happens with hand-edited/imported DB rows or a registry write path that recorded the transport without resolving a URL.

Source

Thrown at src/openhuman/mcp/registry/connections.rs:413

    // Branch on transport variant. Both branches end with `initialize` +
    // `list_tools` so a misconfigured server fails loudly at connect
    // instead of silently at first `call_tool`.
    let client = match &server.transport {
        Transport::Stdio => {
            let stdio = Arc::new(McpStdioClient::new(
                server.command.clone(),
                server.args.clone(),
                env,
                None,
                identity,
            ));
            stdio.initialize().await?;
            ActiveClient::Stdio(stdio)
        }
        Transport::HttpRemote { url } => {
            if url.is_empty() {
                anyhow::bail!(
                    "[mcp-registry] http_remote server_id={} has empty deployment_url",
                    server.server_id
                );
            }
            // Refresh an expired OAuth access token before dialing so the agent
            // never connects with a stale token (silent refresh-token grant; a
            // no-op for static-token / no-auth servers).
            if let Err(e) = super::oauth::refresh_if_expired(config, &server.server_id).await {
                tracing::warn!(
                    "[mcp-registry] oauth refresh failed for server_id={} (using existing token): {e}",
                    server.server_id
                );
            }
            // Build static auth from the (possibly just-refreshed) stored env:
            // each entry is a request header (key = header name, value = the
            // secret, e.g. `Authorization` -> `Bearer <token>`), from the install
            // form's declared `remotes[].headers` or a captured OAuth token.
            let env_now: Vec<(String, String)> = store::load_env_values(config, &server.server_id)

View on GitHub (pinned to 7491200858)

Solutions

  1. Re-register the server through the normal install path so the deployment URL is recorded (`mcp_registry` install/connect flows).
  2. Or update the row's deployment_url in `mcp_clients.db` to the real endpoint.
  3. If the URL is genuinely unknown, remove the broken entry and re-add the server by URL.
  4. Check server logs for the interrupted install that left the row half-populated.
Defensive patterns

Strategy: validation

Validate before calling

// before connecting a registered http_remote server:
if matches!(server.transport, Transport::HttpRemote { ref url } if url.is_empty()) {
    anyhow::bail!("server {} has no deployment_url; re-register it", server.server_id);
}

Prevention

When it happens

Trigger: `mcp_registry` connect for a server whose `mcp_clients.db` row has `transport = 'http_remote'` and an empty/NULL deployment_url; servers registered from a smithery-style install that failed to record the deployment URL.

Common situations: Manually inserted/edited registry rows; partial installs interrupted before the deployment URL was written; restoring a DB backup across versions with schema drift.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/4bd22de14ede5d30. Report an issue: GitHub.