zylon-ai/private-gpt · error · ValueError
MCP tool {tool_name!r} is no longer available from server {c
Error message
MCP tool {tool_name!r} is no longer available from server {config.name!r}. What it means
RuntimeError/ValueError raised inside the per-invocation MCP tool wrapper: each call opens a fresh McpClient, lists the server's current tools, and refuses to execute if tool_name is not among them. This guards against stale tool registrations — the tool existed when the chat session/config was built but the server no longer advertises it (renamed, removed, or upgraded schema).
Source
Thrown at private_gpt/server/mcp/mcp_service.py:198
tool_name: str,
name: str | None,
type: str | None,
description: str | None,
input_schema: dict[str, object] | None,
) -> "ToolSpec":
"""Build an MCP tool whose client session is scoped to each invocation."""
from private_gpt.components.chat.models.chat_config_models import (
ToolExecutionMetadata,
ToolSpec,
)
async def invoke_mcp_tool(**kwargs: object) -> object:
client = McpClient(config)
try:
tools = await client.list_tools()
available = {item.name for item in tools}
if tool_name not in available:
raise ValueError(
f"MCP tool {tool_name!r} is no longer available from "
f"server {config.name!r}."
)
return await client.call_tool(tool_name, dict(kwargs))
finally:
await client.close()
rebuild_kwargs = {
"config": config,
"tool_name": tool_name,
"name": name,
"type": type,
"description": description,
"input_schema": input_schema,
}
return ToolSpec.from_defaults(
name=name or tool_name,
type=type,View on GitHub (pinned to 4a030776a3)
Solutions
- Re-fetch the server's tool list (client.list_tools()) and update the stored ToolSpec/tool name to the current one.
- Pin or align the MCP server version with the one the config was authored against.
- Check the MCP server logs to confirm whether the tool was deliberately removed; if so migrate usage to its replacement.
- If it should still exist, verify the server connection config (URL/auth) points at the right instance.
Example fix
# before
tool = ToolExecutionMetadata(tool_name='search_docs') # renamed upstream
# after
tools = await McpClient(config).list_tools()
assert 'docs_search' in {t.name for t in tools}
tool = ToolExecutionMetadata(tool_name='docs_search') Defensive patterns
Strategy: type-guard
Validate before calling
async def tool_exists(config, tool_name: str) -> bool:
client = McpClient(config)
try:
tools = await client.list_tools()
return tool_name in {t.name for t in tools}
finally:
await client.close() Type guard
const toolIsAvailable = async (config: McpConfig, name: string): Promise<boolean> => {
const client = new McpClient(config);
try {
const tools = await client.listTools();
return tools.some((t) => t.name === name);
} finally {
await client.close();
}
}; Try / catch
try {
await invokeTool(toolName, args);
} catch (e: any) {
if (/no longer available/.test(String(e?.message))) {
await refreshToolRegistry(); // re-list and re-map names, then retry once
} else throw e;
} Prevention
- Refresh and persist tool registries after any MCP server upgrade.
- Validate stored tool names against list_tools() on session load.
- Subscribe to MCP servers/tools/list_changed notifications when the client supports it.
When it happens
Trigger: A saved chat config or tool spec referencing tool 'old_name' while the MCP server now exposes 'new_name'; the MCP server was restarted with tools disabled/removed; the server URL now points to a different deployment; intermittent server-side registration failures during list_tools.
Common situations: MCP server upgrades that rename tools; feature-flagged tools disabled in production but enabled where the config was authored; stale persisted chat configs replayed against a newer server; environment drift between staging and prod servers.
Related errors
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/af9de53fd334509b.
Report an issue: GitHub.