Implementation:MaterializeInc Materialize MCP Agents
Overview
The MCP Materialize Agents server is a variant of the MCP Materialize server built on the FastMCP framework. It exposes Materialize data products to AI agents via the Model Context Protocol, providing structured tool discovery with Pydantic-based input models and a system prompt to guide agent behavior.
The implementation resides in misc/mcp-materialize-agents/mcp_materialize_agents/mcp_materialize_agents/.
Architecture
| Module | Purpose |
|---|---|
__init__.py |
Server initialization, connection pool, tool discovery, and agent-oriented tool registration |
config.py |
Configuration dataclass and CLI argument parsing |
Server Initialization
Connection Pool
The create_client async context manager creates a psycopg_pool.AsyncConnectionPool with the same pattern as the base MCP server. Key differences:
- The application name is set to
mcp_materialize_agents. - Instead of yielding an
MzClientwrapper, it yields the rawAsyncConnectionPooldirectly.
@asynccontextmanager
async def create_client(cfg: Config) -> AsyncIterator[AsyncConnectionPool]:
async with AsyncConnectionPool(
conninfo=cfg.dsn,
min_size=cfg.pool_min_size,
max_size=cfg.pool_max_size,
kwargs={"application_name": "mcp_materialize_agents"},
configure=configure,
) as pool:
yield pool
Resource Loading
The server loads two static resources at module level using importlib.resources:
| Resource | Variable | Purpose |
|---|---|---|
tools.sql |
TOOL_QUERY |
SQL query for discovering available data product indexes |
system_prompt.md |
INSTRUCTIONS |
System prompt provided to agents describing available capabilities |
TOOL_QUERY = (
files("mcp_materialize_agents.mcp_materialize_agents") / "tools.sql"
).read_text(encoding="utf-8")
INSTRUCTIONS = (
files("mcp_materialize_agents.mcp_materialize_agents") / "system_prompt.md"
).read_text(encoding="utf-8")
Data Product Model
The DataProduct class is a Pydantic BaseModel used to represent a discoverable data product (a Materialize view backed by an index). It uses Field descriptors so that agents receive structured documentation about how to format tool inputs:
class DataProduct(BaseModel):
name: str = Field(
description=(
"Fully qualified name of the data product with double quotes "
'(e.g. \'"database"."schema"."view_name"\'). '
"Use this exact name when querying."
)
)
This model ensures that agents provide properly quoted, fully qualified names when invoking tools.
Configuration
The config.py module mirrors the structure of the base MCP server configuration with the following differences:
| Parameter | CLI Flag | Env Var | Default |
|---|---|---|---|
dsn |
--mz-dsn |
MZ_DSN |
postgresql://materialize@localhost:6875/materialize
|
transport |
--transport |
MCP_TRANSPORT |
stdio
|
host |
--host |
MCP_HOST |
0.0.0.0
|
port |
--port |
MCP_PORT |
8000
|
pool_min_size |
--pool-min-size |
MCP_POOL_MIN_SIZE |
1
|
pool_max_size |
--pool-max-size |
MCP_POOL_MAX_SIZE |
10
|
log_level |
--log-level |
MCP_LOG_LEVEL |
INFO
|
Notable differences from the base MCP server config:
- Transport choices are limited to
stdioandhttp(no SSE support). - The default port is
8000instead of transport-dependent values.
@dataclass(frozen=True)
class Config:
dsn: str
transport: str
host: str
port: int
pool_min_size: int
pool_max_size: int
log_level: str
Comparison with Base MCP Server
| Feature | MCP Server | MCP Agents |
|---|---|---|
| Framework | mcp.server.Server |
mcp.server.FastMCP
|
| Client wrapper | MzClient class |
Direct pool usage |
| Input validation | JSON Schema | Pydantic models |
| System prompt | None | system_prompt.md instructions
|
| Transports | stdio, SSE, HTTP | stdio, HTTP |
| Default port | 3001 (SSE) / 8001 (HTTP) | 8000 |
Key Source Files
| File | Path |
|---|---|
| Server entry point | misc/mcp-materialize-agents/mcp_materialize_agents/mcp_materialize_agents/__init__.py
|
| Configuration | misc/mcp-materialize-agents/mcp_materialize_agents/mcp_materialize_agents/config.py
|