Skip to content

tdfs4ds.mcp_launcher

tdfs4ds.mcp_launcher

Start a local Teradata MCP server (Community edition) from the tdfs4ds credentials.

start_mcp_server() runs teradata-mcp-server in a separate process on 127.0.0.1, logged on with the TDFS4DS_TD_* credentials, and points tdfs4ds.MCP_SERVER_URL at it so the consumer agent's MCP skills (DATA_QUERY, ALGORITHM) can use it. It is the notebook-side equivalent of::

teradata-mcp-server --mcp_transport streamable-http --mcp_host 127.0.0.1 \
    --mcp_port 8001 --auth_mode none --profile eda --database_uri teradata://...

Three things differ from that command line, on purpose:

  • The credentials never appear on a command line. Every setting of the server can be read from its environment (DATABASE_URI, MCP_PORT, ...), so the database URI is passed there: a command line is readable by every user of the machine (ps), a process environment is not.
  • The user name and password are percent-encoded. The server reads them with urlparse without decoding and hands them to SQLAlchemy, which decodes them; an unencoded @, :, / or # in a password would split the URI in the wrong place.
  • The server only listens on 127.0.0.1. With auth_mode none anyone who can reach the port queries the database under these credentials.

The server package is NOT a tdfs4ds dependency: it runs in its own process, so it can be installed in the kernel's environment (%pip install teradata-mcp-server) or in an isolated one (pipx install teradata-mcp-server) whose executable is on PATH. A token logon (TDFS4DS_TD_LOGDATA) cannot drive it: the server drops LOGDATA from its own connection URI, so it needs a user name and a password (TD2 or LDAP).

mcp_server_status() and stop_mcp_server() read the state file the start writes (~/.tdfs4ds/mcp_<port>.json, which never holds the password).

__all__ module-attribute

__all__ = ['start_mcp_server', 'stop_mcp_server', 'mcp_server_status', 'database_uri']

DEFAULT_MCP_PORT module-attribute

DEFAULT_MCP_PORT = 8001

DEFAULT_PROFILE module-attribute

DEFAULT_PROFILE = 'eda'

MCP_PATH module-attribute

MCP_PATH = '/mcp/'

_STATE_DIR module-attribute

_STATE_DIR = home() / '.tdfs4ds'

INSTALL_HINT module-attribute

INSTALL_HINT = 'teradata-mcp-server is not installed: %pip install teradata-mcp-server (or pipx install teradata-mcp-server, with its executable on PATH).'

_PREVIOUS module-attribute

_PREVIOUS: dict = {}

_CONFIG_KEYS module-attribute

_CONFIG_KEYS = ('MCP_SERVER_URL', 'MCP_SERVER_TRANSPORT', 'MCP_SERVER_EDITION')

database_uri

database_uri(host: str, username: str, password: str, database: Optional[str] = None, port: int = 1025) -> str

teradata://user:password@host:port/database with user, password and database percent-encoded.

_credentials

_credentials(env: Mapping[str, str], host=None, username=None, password=None, database=None, logmech=None) -> dict

The logon of the server: explicit values first, then TDFS4DS_TD_* from env.

_server_env

_server_env(creds: dict, port: int, profile: Optional[str], base: Optional[Mapping] = None) -> dict

The server's environment: the URI and every setting, nothing on its command line.

_server_command

_server_command() -> Optional[list]

How to run the server: its executable on PATH, else its module in this Python.

_state_file

_state_file(port: int) -> Path

_read_state

_read_state(port: int) -> dict

_port_open

_port_open(port: int, timeout: float = 1.0) -> bool

server_url

server_url(port: int = DEFAULT_MCP_PORT) -> str

_list_tools

_list_tools(url: str, timeout: float = 30.0) -> Optional[int]

Number of tools the server lists, or None when they cannot be listed.

_apply_config

_apply_config(port: int) -> None

_restore_config

_restore_config(port: int) -> None

start_mcp_server

start_mcp_server(port: int = DEFAULT_MCP_PORT, profile: Optional[str] = DEFAULT_PROFILE, *, host: Optional[str] = None, username: Optional[str] = None, password: Optional[str] = None, database: Optional[str] = None, logmech: Optional[str] = None, env: Optional[Mapping[str, str]] = None, check_credentials: bool = True, timeout: float = 60, set_config: bool = True, log_file: Optional[str] = None) -> dict

Start the Teradata MCP server on 127.0.0.1:<port> with the tdfs4ds credentials.

Parameters

port : int The server's port (8001). profile : str, optional The server's tool profile ('eda': exploration tools, enough for the agent's DATA_QUERY and ALGORITHM skills). None = every tool. host, username, password, database, logmech : str, optional The logon; by default TDFS4DS_TD_HOST / _USERNAME / _PASSWORD / _DATABASE / _LOGMECH (TD2 or LDAP). The database defaults to tdfs4ds.SCHEMA. env : mapping, optional Where to read TDFS4DS_TD_* (os.environ by default). check_credentials : bool Try the logon with the raw driver first and refuse to start the server when the database rejects it (an unreachable host does not block). timeout : float Seconds to wait for the server to answer. set_config : bool Point tdfs4ds.MCP_SERVER_URL at the server (Community edition, streamable HTTP); stop_mcp_server restores the previous values. log_file : str, optional The server's log (~/.tdfs4ds/mcp_<port>.log).

Returns

dict url, port, pid, profile, log, reused (a server started earlier was still running), ready, n_tools (None = not listed), notes. Never the password.

mcp_server_status

mcp_server_status(port: int = DEFAULT_MCP_PORT) -> dict

Is a server started by :func:start_mcp_server running on port?

stop_mcp_server

stop_mcp_server(port: int = DEFAULT_MCP_PORT, timeout: float = 15) -> bool

Stop the server started by :func:start_mcp_server on port. True when it is stopped.

A server this module did not start is never killed. The MCP settings that the start replaced are put back.