tinyhumansai/openhuman · error
MCP server '{}' not found
Error message
MCP server '{}' not found What it means
A SQLite lookup by primary key — get_server_conn(conn, server_id) against the mcp_servers table in the registry database — found no row, and the id string is echoed in the message. It means the id is stale (the server was uninstalled), foreign (belongs to a different workspace/profile database), or simply mistyped. The read-only SELECT means no state changed.
Source
Thrown at src/openhuman/mcp/registry/store.rs:363
}
}
pub fn get_server(config: &Config, server_id: &str) -> Result<InstalledServer> {
with_connection(config, |conn| get_server_conn(conn, server_id))
}
pub fn get_server_conn(conn: &Connection, server_id: &str) -> Result<InstalledServer> {
let mut stmt = conn.prepare(
"SELECT server_id, qualified_name, display_name, description, icon_url,
command_kind, command, args_json, env_keys_json, config_json,
installed_at, last_connected_at, transport, deployment_url, enabled
FROM mcp_servers WHERE server_id = ?1",
)?;
let mut rows = stmt.query(params![server_id])?;
if let Some(row) = rows.next()? {
map_server_row(row).map_err(Into::into)
} else {
anyhow::bail!("MCP server '{}' not found", server_id)
}
}
pub fn delete_server(config: &Config, server_id: &str) -> Result<bool> {
with_connection(config, |conn| {
let changed = conn
.execute(
"DELETE FROM mcp_servers WHERE server_id = ?1",
params![server_id],
)
.context("Failed to delete mcp_server")?;
Ok(changed > 0)
})
}
pub fn update_last_connected(config: &Config, server_id: &str) -> Result<()> {
let ts = now_ms();
with_connection(config, |conn| {View on GitHub (pinned to 7491200858)
Solutions
- List the installed servers (store::list_servers(config) or the mcp_clients list RPC) and use a fresh id.
- If the server should exist, reinstall it from the catalog and note the new id.
- Remove stale references (flows, saved tool configs, UI state) that still point at the deleted id.
Example fix
// before
let server = store::get_server(config, "srv_abc123")?; // bails: not found
// after — validate against the live table first
let installed = store::list_servers(config)?;
let server = installed.into_iter().find(|s| s.server_id == "srv_abc123")
.ok_or_else(|| anyhow::anyhow!("server 'srv_abc123' not installed — reinstall it"))?; Defensive patterns
Strategy: validation
Validate before calling
// Check existence against the live table before the point lookup
let exists = store::list_servers(config)?.iter().any(|s| s.server_id == server_id);
if !exists {
// refresh the UI list / offer reinstall instead of calling get_server
} Try / catch
Catch the bail and treat `not found` as a data-staleness signal: refresh the installed-server list, reconcile or drop the reference. Do not blind-retry the same id — nothing will create it.
Prevention
- Refresh installed-server lists after uninstall operations.
- Key automations on qualified_name (stable across reinstalls) rather than server_id (per-install).
- Keep UI state scoped to the same workspace/profile database as the RPC calls.
When it happens
Trigger: Calling get_server/get_server_conn (directly or via an RPC/agent tool that resolves an installed MCP server) with a server_id that is absent: a UI list out of sync after an uninstall elsewhere, a flow or agent holding a previously captured id, a hand-written RPC with a wrong id, or a different workspace pointing at a different database file.
Common situations: Stale frontend state after uninstall; multi-profile workspaces where each profile has its own DB; automations referencing deleted servers; ids copied between environments.
Related errors
- Smithery GET {qualified_name} returned HTTP {status}: {}
- Task source '{id}' not found
- Task source '{id}' not found.
- [mcp-registry] http_remote server_id={} has empty deployment
- MCP official registry GET {qualified_name} returned HTTP {st
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/8bb567166c5d2672.
Report an issue: GitHub.