langchain-ai/deepagents · error · ValueError

Invalid MCP server name

Error message

Invalid MCP server name {server_name!r}: token storage names must match [A-Za-z0-9_-]+ to keep the on-disk path inside {tokens_dir}.

What it means

The MCP token-store wrapper validates the server name at construction because the server name becomes a file name under the tokens directory. Names containing path separators or other unsafe characters could escape the token directory, so only [A-Za-z0-9_-]+ is allowed. This is a fail-fast guard in TokenStore.__init__ (mcp_auth.py:324).

Solutions

  1. Rename the MCP server entry to a simple identifier using only letters, digits, underscores, or hyphens (e.g. 'github-mcp').
  2. Strip whitespace and transliterate/replace special characters in the name before constructing the store.
  3. If generating names programmatically, pass them through re.sub(r'[^A-Za-z0-9_-]', '-', name) first.

Example fix

// before
store = McpTokenStore(server_name="https://mcp.example.com/sse", url=...)
// after
import re
name = re.sub(r"[^A-Za-z0-9_-]", "-", "https://mcp.example.com/sse")  # e.g. 'https---mcp-example-com-sse'
store = McpTokenStore(server_name=name, url=...)
Defensive patterns

Strategy: validation

Validate before calling

import re
def valid_server_name(name: str) -> bool:
    return bool(re.fullmatch(r"[A-Za-z0-9_-]+", name))

if not valid_server_name(server_name):
    server_name = re.sub(r"[^A-Za-z0-9_-]", "-", server_name)

Type guard

import re
def is_safe_token_name(name: object) -> TypeGuard[str]:
    return isinstance(name, str) and re.fullmatch(r"[A-Za-z0-9_-]+", name) is not None

Prevention

When it happens

Trigger: Constructing the token store (directly or via `mcp login`/auth flows) with a server name that is empty or contains characters outside [A-Za-z0-9_-], e.g. slashes, spaces, dots, or unicode.

Common situations: MCP server entries in config with URLs or paths used as names (e.g. 'https://mcp.example.com/v1'), names copied from docs containing spaces or slashes, or a typo'd/whitespace-padded server key in .mcp.json.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/d8fc21c4ab3652ed. Report an issue: GitHub.

Appendix: source

Thrown at libs/code/deepagents_code/mcp_auth.py:324

class FileTokenStorage(TokenStorage):
    """File-backed `TokenStorage` under the selected profile's state directory."""

    def __init__(self, server_name: str, *, server_url: str | None = None) -> None:
        """Bind this storage to a configured MCP server identity.

        Raises:
            ValueError: If `server_name` contains characters that would let
                it escape the MCP token-store directory when used as the
                token-file basename.
        """
        if not _SAFE_SERVER_NAME_RE.fullmatch(server_name):
            tokens_dir = PATHS.display(token_store_dir())
            msg = (
                f"Invalid MCP server name {server_name!r}: token storage "
                "names must match [A-Za-z0-9_-]+ to keep the on-disk path "
                f"inside {tokens_dir}."
            )
            raise ValueError(msg)
        self._server_name = server_name
        self._server_url = server_url

    @property
    def path(self) -> Path:
        """On-disk token file path for this server."""
        stem = _token_file_stem(self._server_name, self._server_url)
        return token_store_dir() / f"{stem}.json"

    @property
    def refresh_lock_path(self) -> Path:
        """Sibling lock file that serializes token refreshes across processes.

        A dedicated `.lock` file (never the token file itself) lets `filelock`
        coordinate refreshes between dcode processes and provider instances
        without ever holding an exclusive lock on the credential file. It holds
        no token material.
        """

View on GitHub (pinned to a1af029e6e)