HKUDS/DeepTutor · error · UserMcpError
mcp.blocked_url
mcp.blocked_url
Error message
error
What it means
When validate_url=True, the candidate server URL is passed to validate_mcp_url(url, strict=True); if it fails (non-http(s) scheme, unreachable host, loopback/private address, or otherwise blocked), the returned error message is wrapped in a UserMcpError with code mcp.blocked_url.
Source
Thrown at deeptutor/services/mcp/user_config.py:189
raise UserMcpError("mcp.invalid_name", f"Invalid server name {name!r}")
if name.startswith(_RESERVED_NAME_PREFIXES):
raise UserMcpError(
"mcp.name_reserved",
f"{name!r} starts with a reserved tool-name prefix",
)
transport = cfg.resolved_type()
if transport == "stdio" or cfg.command:
raise UserMcpError(
"mcp.stdio_not_allowed",
"A server you configure yourself must be a remote URL: a stdio "
"server runs a command on the host and stays administrator-only.",
)
if transport not in ("sse", "streamableHttp"):
raise UserMcpError("mcp.no_transport", "Provide an http(s) URL for the server")
if validate_url:
ok, error = validate_mcp_url(cfg.url, strict=True)
if not ok:
raise UserMcpError("mcp.blocked_url", error)
def _read_raw(owner_id: str) -> MCPConfig:
"""The file as stored, *without* the connectability filtering.
Writes must preserve entries this deployment refuses to connect (a stdio
entry left over from a hand edit), or saving one server would silently
delete another.
"""
path = user_mcp_path(owner_id)
if not path.exists():
return MCPConfig()
try:
return MCPConfig.model_validate(json.loads(path.read_text(encoding="utf-8")))
except (OSError, json.JSONDecodeError, ValueError):
return MCPConfig()
View on GitHub (pinned to 3e82f13042)
Solutions
- Use a publicly reachable https:// URL for the server
- If you need a local server for development, run with validate_url disabled (admin/local mode) or expose it via a tunnel the validator permits
- Check the exact reason inside the error message returned by validate_mcp_url — it names the specific rule that failed
Example fix
# before await save_user_server(user_id, "local", McpServerConfig(url="http://localhost:8080/sse", type="sse"), validate_url=True) # after await save_user_server(user_id, "prod", McpServerConfig(url="https://mcp.example.com/sse", type="sse"), validate_url=True)
Defensive patterns
Strategy: try-catch
Validate before calling
from deeptutor.services.mcp import validate_mcp_url
ok, reason = validate_mcp_url(cfg.url, strict=True)
if not ok:
show_error(reason) Try / catch
try:
await save_user_server(user_id, name, cfg, validate_url=True)
except UserMcpError as e:
if e.code == "mcp.blocked_url":
show_error(f"URL rejected: {e.message}")
else:
raise Prevention
- Pre-validate URLs with validate_mcp_url before saving
- Default to public https endpoints for user-configured servers
When it happens
Trigger: Calling _assert_self_service_allowed with validate_url=True (via load_user_mcp_config or save_user_server) where cfg.url is non-http(s), points at localhost/private networks, or violates the strict SSRF rules in validate_mcp_url.
Common situations: Pointing a user MCP server at a local development server (http://localhost:3000/sse), an internal IP, or leaving a placeholder URL; strict mode is enabled during interactive 'add server' flows.
Related errors
- mcp.stdio_not_allowed
- Invalid math animator config: {details}
- Invalid folder path
- Access denied
- mcp.configure_command_or_url
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/2c140240a56b61b1.
Report an issue: GitHub.