Skip to main content

Connect an MCP client

Your agent reaches an MCP server through Catalyst's MCP proxy endpoint instead of connecting to the upstream server directly. This page shows how to point a standard MCP client at that endpoint, authenticate, and discover tools. No Catalyst SDK is required — any MCP client that speaks Streamable HTTP works.

Prerequisites

  • An MCPServer connection in your project. If you don't have one, add an MCP server first.
  • The App ID your agent runs as, and its API token.
  • The caller App ID granted access to the server's tools — a new MCP server denies everything until you grant access.

The endpoint

Catalyst exposes each MCP server on your project's HTTP endpoint at a path keyed by the connection name:

<DAPR_HTTP_ENDPOINT>/v1.0/diagrid/mcp/<mcp-server-name>
  • DAPR_HTTP_ENDPOINT is your project's HTTP endpoint. diagrid dev run injects it into your app as an environment variable; for a hosted project it is the HTTP endpoint shown in the Catalyst console (for example https://http-prj<project-id>.api.r1.diagrid.io). During local development it is http://localhost:3500.
  • <mcp-server-name> is the name of the MCPServer connection — not the upstream URL, which Catalyst keeps hidden.

Authenticate every request with your App ID's API token in the dapr-api-token header. Catalyst injects the upstream server's own credentials separately, so the agent never holds them.

Connect and discover tools

Point your MCP client at the Catalyst endpoint and set the token header. The example uses the Python mcp library with the Streamable HTTP transport:

import os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

DAPR_HTTP_ENDPOINT = os.getenv("DAPR_HTTP_ENDPOINT", "http://localhost:3500")
DAPR_API_TOKEN = os.getenv("DAPR_API_TOKEN", "")
MCP_URL = f"{DAPR_HTTP_ENDPOINT}/v1.0/diagrid/mcp/mcp-server"

headers = {"dapr-api-token": DAPR_API_TOKEN}

async with streamablehttp_client(url=MCP_URL, headers=headers) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools() # only the tools you're granted
result = await session.call_tool("add", {"a": 2, "b": 3})

MCP clients are available in Python, TypeScript, Java, C#, and Go. Set the same URL and dapr-api-token header in whichever client your agent framework uses.

session.list_tools() returns only the tools the calling App ID is allowed to use — Catalyst filters discovery, so unauthorized tools are invisible rather than merely un-callable. A call_tool for a tool you're not granted is rejected with 403 Forbidden before it reaches the upstream server.

Discover available servers

To list the MCP servers the calling App ID may reach, send a GET to the discovery path:

curl -s "$DAPR_HTTP_ENDPOINT/v1.0/diagrid/mcp" \
-H "dapr-api-token: $DAPR_API_TOKEN"

The response is a JSON array of the servers in scope for this caller, each with the path to connect on:

[
{ "name": "mcp-server", "connect": { "path": "/v1.0/diagrid/mcp/mcp-server" } }
]

The list contains only servers the caller is authorized for, so it stays empty until access is granted.

What's next