MCP Server for Agents

View as Markdown
PREVIEW This feature is in private preview. It is under active development and may have stability or performance issues. It isn't subject to our backwards compatibility guarantees.
To enable this feature in your Materialize region, contact our team.

Materialize provides a built-in Model Context Protocol (MCP) endpoint that lets AI agents discover and query your real-time data products over HTTP. The MCP interface is served directly by the database; no sidecar process or external server is required.

Endpoint: POST /api/mcp/agents (HTTP port, default 6876)

The endpoint uses JSON-RPC 2.0 over HTTP POST and supports the MCP initialize, tools/list, and tools/call methods.

Connect to the MCP server

Step 1. Get your credentials

You need your email address (or service account name) and an app password.

To create an app password:

  1. Log in to the Materialize Console.
  2. Go to Account > App Passwords > New app password.
  3. Copy the generated password — you won’t be able to see it again.
Use the login role credentials you created for MCP access (see Authentication and access control).

Step 2. Encode your credentials in Base64

MCP clients send credentials as a Base64-encoded user:password string. Run this in your terminal:

printf '<user>:<app_password>' | base64

For example:

printf 'svc-mcp-agent@mycompany.com:my_app_password_here' | base64
# Output: c3ZjLW1jcC1hZ2VudEBteWNvbXBhbnkuY29tOm15X2FwcF9wYXNzd29yZF9oZXJl

Step 3. Get your hostname

Find your region hostname in the Materialize Console under Connect. It looks like:

<region-id>.materialize.cloud

Your full MCP endpoint URL is:

https://<region-id>.materialize.cloud/api/mcp/agents

Use your Materialize host and the HTTP port (default 6876):

http://<host>:6876/api/mcp/agents

Step 4. Configure your MCP client

Create a .mcp.json file in your project directory:

{
  "mcpServers": {
    "materialize-agents": {
      "type": "http",
      "url": "https://<region-id>.materialize.cloud/api/mcp/agents",
      "headers": {
        "Authorization": "Basic <base64-token>"
      }
    }
  }
}

Add to your Claude Desktop MCP configuration (claude_desktop_config.json):

{
  "mcpServers": {
    "materialize-agents": {
      "url": "https://<region-id>.materialize.cloud/api/mcp/agents",
      "headers": {
        "Authorization": "Basic <base64-token>"
      }
    }
  }
}

In Cursor’s MCP settings (.cursor/mcp.json):

{
  "mcpServers": {
    "materialize-agents": {
      "url": "https://<region-id>.materialize.cloud/api/mcp/agents",
      "headers": {
        "Authorization": "Basic <base64-token>"
      }
    }
  }
}

Any MCP-compatible client can connect by sending JSON-RPC 2.0 requests:

curl -X POST https://<region-id>.materialize.cloud/api/mcp/agents \
  -H "Content-Type: application/json" \
  -H "Authorization: "Basic <base64-token>"" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list"
  }'

Enabling the endpoint

The agents endpoint is disabled by default. Enable it at runtime using system parameters:

Parameter Default Description
enable_mcp_agents false Enable or disable the /api/mcp/agents endpoint.
enable_mcp_agents_query_tool false Show or hide the query tool on the agents endpoint.
mcp_max_response_size 1000000 Maximum response size in bytes. Queries exceeding this limit return an error.
ALTER SYSTEM SET enable_mcp_agents = true;

When the endpoint is disabled, requests return HTTP 503 (Service Unavailable).

Authentication and access control

Accessing the MCP endpoint requires basic authentication, just as connecting via a SQL client (e.g. psql). The authenticated role determines which data products are visible based on RBAC privileges.

Use the credentials of a Materialize user or service account:

  • User ID: Your email address or service account name.
  • Password: An app password.

For production use, we recommend creating a dedicated service account and granting it a role with limited privileges (see Required privileges).

Create a functional role for MCP privileges, then assign it to a login role:

CREATE ROLE mcp_agent;
CREATE ROLE my_agent LOGIN PASSWORD 'secret';
GRANT mcp_agent TO my_agent;

Authenticate using the login role credentials (my_agent). You can create additional login roles and grant them the same mcp_agent role as needed.

Define and document data products for your agents

The MCP server allows agents to discover and query documented data products. In Materialize, you can make a data product discoverable to agents by creating a materialized view, adding a comment, and optionally adding an index for faster lookups. A comment is required, so agents understand the purpose of each data product.

1. Create a dedicated cluster and schema

Use a dedicated cluster and schema to isolate agent workloads. This ensures agent queries do not consume resources from your other clusters, and limits visibility to only the data products you choose to expose.

CREATE CLUSTER mcp_cluster SIZE '25cc';
CREATE SCHEMA mcp_schema;

2. Create and index a view

Create a materialized view in the dedicated schema. We recommend installing an index on the dedicated cluster for faster lookups. Every indexed column becomes a required input parameter in the tool’s schema.

SET cluster = mcp_cluster;

CREATE MATERIALIZED VIEW mcp_schema.payment_status AS
  SELECT order_id, user_id, status, updated_at
  FROM orders
  JOIN payments USING (order_id);

CREATE INDEX payment_status_order_id_idx ON mcp_schema.payment_status (order_id);

3. Add a comment

The comment on the index becomes the data product’s description. Column comments on the underlying view become parameter descriptions. Write comments that help a language model understand when and how to use the tool.

COMMENT ON INDEX mcp_schema.payment_status_order_id_idx IS
  'Given an order ID, return the current payment status and last update time.
   Use this tool to drive user-facing payment tracking.';

COMMENT ON COLUMN mcp_schema.payment_status.order_id IS
  'The unique identifier for the order';

4. Verify your data products

To confirm which data products are visible to your agent role, run:

SET ROLE mcp_agent;
SELECT * FROM mz_internal.mz_mcp_data_products;

If a data product is missing, check that:

  • The view has an index with a comment.
  • The role has USAGE on the database, schema, and cluster.
  • The role has SELECT on the view.

Required privileges

The role used to authenticate with the MCP endpoint must have:

  • USAGE on the database and schema containing the view.
  • SELECT on the view.
  • USAGE on the cluster where the index is installed.

Lock the role to the dedicated cluster and schema so that all agent queries are isolated.

On Cloud, create a functional role and grant it to a service account. The service account’s app password is used for MCP authentication.

CREATE ROLE mcp_agent;

GRANT USAGE ON DATABASE materialize TO mcp_agent;
GRANT USAGE ON SCHEMA mcp_schema TO mcp_agent;
GRANT SELECT ON ALL TABLES IN SCHEMA mcp_schema TO mcp_agent;
GRANT USAGE ON CLUSTER mcp_cluster TO mcp_agent;

-- Lock the role to the dedicated cluster and schema.
-- This ensures all queries from this role run on mcp_cluster
-- and only see objects in mcp_schema by default.
ALTER ROLE mcp_agent SET cluster TO mcp_cluster;
ALTER ROLE mcp_agent SET search_path TO mcp_schema;

-- Grant the role to your service account
GRANT mcp_agent TO '<service-account-name>';

Create a functional role for privileges, then assign it to a login role:

-- Functional role (cannot log in, holds privileges)
CREATE ROLE mcp_agent;

GRANT USAGE ON DATABASE materialize TO mcp_agent;
GRANT USAGE ON SCHEMA mcp_schema TO mcp_agent;
GRANT SELECT ON ALL TABLES IN SCHEMA mcp_schema TO mcp_agent;
GRANT USAGE ON CLUSTER mcp_cluster TO mcp_agent;

-- Lock the role to the dedicated cluster and schema.
-- This ensures all queries from this role run on mcp_cluster
-- and only see objects in mcp_schema by default.
ALTER ROLE mcp_agent SET cluster TO mcp_cluster;
ALTER ROLE mcp_agent SET search_path TO mcp_schema;

-- Login role (used for authentication)
CREATE ROLE my_agent LOGIN PASSWORD 'secret';
GRANT mcp_agent TO my_agent;

You can create additional login roles and grant them the same mcp_agent role as needed.

If any privilege is missing, the data product will not appear in the agent’s tool list.

Tools

get_data_products

Discover all available data products. Returns a lightweight list with name, cluster, and description for each product.

Parameters: None.

Example response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "[\n  [\n    \"\\\"materialize\\\".\\\"mcp_schema\\\".\\\"payment_status\\\"\",\n    \"mcp_cluster\",\n    \"Given an order ID, return the current payment status.\"\n  ]\n]"
      }
    ],
    "isError": false
  }
}

get_data_product_details

Get the full details for a specific data product, including its JSON schema with column names, types, and descriptions.

Parameter Type Required Description
name string Yes Exact name from the get_data_products list.

Example response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "[\n  [\n    \"\\\"materialize\\\".\\\"mcp_schema\\\".\\\"payment_status\\\"\",\n    \"mcp_cluster\",\n    \"Given an order ID, return the current payment status.\",\n    \"{\\\"order_id\\\": {\\\"type\\\": \\\"integer\\\", \\\"position\\\": 1}, \\\"status\\\": {\\\"type\\\": \\\"text\\\", \\\"position\\\": 3}}\"\n  ]\n]"
      }
    ],
    "isError": false
  }
}

read_data_product

Read rows from a data product.

Parameter Type Required Description
name string Yes Fully-qualified name, e.g. "materialize"."public"."payment_status".
limit integer No Maximum rows to return. Default: 500, max: 1000.
cluster string No Cluster override. If omitted, uses the cluster from the catalog.

Example response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "[\n  [\n    1001,\n    42,\n    \"shipped\",\n    \"2026-03-26T10:30:00Z\"\n  ]\n]"
      }
    ],
    "isError": false
  }
}

query

NOTE: The query tool is disabled by default. To enable it, set the enable_mcp_agents_query_tool system parameter to true.

Execute a SQL SELECT statement against your data products.

Parameter Type Required Description
cluster string Yes Exact cluster name from the data product details.
sql_query string Yes PostgreSQL-compatible SELECT statement.

Example response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "[\n  [\n    42,\n    \"shipped\"\n  ]\n]"
      }
    ],
    "isError": false
  }
}
Back to top ↑