Getting started with the Dapr MCP server

Install the Dapr MCP server, run it with a Dapr sidecar, and connect an MCP client over stdio or streamable HTTP

This guide installs the Dapr MCP server, runs it next to a Dapr sidecar with two in-memory components, and connects an MCP client to it.

Prerequisites

Step 1: Install the server

Pick one of the following.

Each GitHub release publishes a binary per platform, named dapr-mcp-server-<os>-<arch>, with a checksums.txt file. Builds are available for linux-amd64, linux-arm64, darwin-amd64, darwin-arm64, and windows-amd64 (with an .exe suffix).

Download the binary, check it against checksums.txt, and move it onto your PATH. On Arm, use linux-arm64.

curl -LO https://github.com/dapr/dapr-mcp-server/releases/latest/download/dapr-mcp-server-linux-amd64
curl -LO https://github.com/dapr/dapr-mcp-server/releases/latest/download/checksums.txt
sha256sum --ignore-missing -c checksums.txt
chmod +x dapr-mcp-server-linux-amd64
sudo mv dapr-mcp-server-linux-amd64 /usr/local/bin/dapr-mcp-server

Download the binary, check it against checksums.txt, and move it onto your PATH. On an Intel Mac, use darwin-amd64.

curl -LO https://github.com/dapr/dapr-mcp-server/releases/latest/download/dapr-mcp-server-darwin-arm64
curl -LO https://github.com/dapr/dapr-mcp-server/releases/latest/download/checksums.txt
shasum -a 256 --ignore-missing -c checksums.txt
chmod +x dapr-mcp-server-darwin-arm64
sudo mv dapr-mcp-server-darwin-arm64 /usr/local/bin/dapr-mcp-server

In PowerShell, download the binary to $Env:LOCALAPPDATA\dapr-mcp-server, check it against checksums.txt, and add the folder to your user PATH:

$base = "https://github.com/dapr/dapr-mcp-server/releases/latest/download"
$dir = "$Env:LOCALAPPDATA\dapr-mcp-server"
New-Item -ItemType Directory -Force -Path $dir | Out-Null
Invoke-WebRequest "$base/dapr-mcp-server-windows-amd64.exe" -OutFile "$dir\dapr-mcp-server.exe"
Invoke-WebRequest "$base/checksums.txt" -OutFile "$dir\checksums.txt"
$expected = ((Select-String -Path "$dir\checksums.txt" -Pattern "dapr-mcp-server-windows-amd64.exe").Line -split "\s+")[0]
$actual = (Get-FileHash "$dir\dapr-mcp-server.exe" -Algorithm SHA256).Hash.ToLower()
if ($actual -ne $expected) { throw "Checksum mismatch for dapr-mcp-server.exe" }
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
if (($userPath -split ";") -notcontains $dir) {
    [Environment]::SetEnvironmentVariable("Path", (($userPath, $dir) | Where-Object { $_ }) -join ";", "User")
}

Open a new terminal so the updated PATH takes effect.

</div>

Requires Go 1.26.6 or later.

go install github.com/dapr/dapr-mcp-server/cmd/dapr-mcp-server@latest

A binary built this way reports its version as dev, because the version is stamped in only by the release build.

Multi-arch images (linux/amd64, linux/arm64) are published to the GitHub Container Registry, tagged with the release version. Stable releases also update latest.

docker pull ghcr.io/dapr/dapr-mcp-server:latest

The image runs as a non-root user, listens on port 8080 with --http 0.0.0.0:8080 by default, and includes a HEALTHCHECK. See Run on Kubernetes for how to pair it with a sidecar.

Check the install:

dapr-mcp-server --version

Step 2: Define components

The server registers tools only for building blocks that have a component loaded. Create a components folder with an in-memory state store and pub/sub broker:

mkdir -p components

components/statestore.yaml:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
spec:
  type: state.in-memory
  version: v1

components/pubsub.yaml:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: pubsub
spec:
  type: pubsub.in-memory
  version: v1

With these two components the server registers the three core tools plus the state and pub/sub tools. Add components of other types (bindings.*, secretstores.*, lock.*, crypto.*, conversation.*) to expose their tools. See the tool reference for the full mapping.

Step 3: Run and connect

Over stdio (Claude Desktop, Cursor)

With stdio, the MCP client starts the server process itself. Run the sidecar on its own first, on a fixed gRPC port:

dapr run --app-id dapr-mcp-server --dapr-grpc-port 50001 --resources-path ./components

Leave it running, then point your client at the binary. Use the absolute path, because clients don’t always inherit your shell’s PATH. On Windows, that’s the full path to dapr-mcp-server.exe, with each backslash doubled in JSON (for example, C:\\Users\\<you>\\AppData\\Local\\dapr-mcp-server\\dapr-mcp-server.exe).

Edit claude_desktop_config.json (on macOS, ~/Library/Application Support/Claude/claude_desktop_config.json; on Windows, %APPDATA%\Claude\claude_desktop_config.json) and restart Claude Desktop:

{
  "mcpServers": {
    "dapr": {
      "command": "/usr/local/bin/dapr-mcp-server",
      "env": {
        "DAPR_GRPC_PORT": "50001"
      }
    }
  }
}

Add the server to ~/.cursor/mcp.json, or to .cursor/mcp.json in a project:

{
  "mcpServers": {
    "dapr": {
      "command": "/usr/local/bin/dapr-mcp-server",
      "env": {
        "DAPR_GRPC_PORT": "50001"
      }
    }
  }
}
claude mcp add dapr --env DAPR_GRPC_PORT=50001 -- /usr/local/bin/dapr-mcp-server

Ask the assistant to list your Dapr components. It calls get_components and reports statestore and pubsub. From there, try “save the key greeting with value hello to the state store” and “read it back”.

The server writes its logs as JSON to stderr, so they never mix with the MCP messages on stdout. Most clients show stderr in their MCP log view.

Over streamable HTTP

Pass --http with a listen address to serve MCP over streamable HTTP. Here dapr run starts both the sidecar and the server, and sets DAPR_GRPC_PORT for it:

dapr run --app-id dapr-mcp-server --resources-path ./components -- dapr-mcp-server --http localhost:8080

The MCP endpoint is http://localhost:8080/. Check that the server is up and can reach its sidecar:

curl http://localhost:8080/readyz
Invoke-RestMethod http://localhost:8080/readyz

A 200 response with "status":"healthy" means it’s ready. A 503 means the sidecar isn’t reachable; PowerShell reports it as an error.

Connect a client that supports streamable HTTP:

{
  "mcpServers": {
    "dapr": {
      "url": "http://localhost:8080/"
    }
  }
}
claude mcp add --transport http dapr http://localhost:8080/
import asyncio

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


async def main():
    async with streamablehttp_client("http://localhost:8080/") as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            print([tool.name for tool in tools.tools])
            result = await session.call_tool("get_components", {})
            print(result.structuredContent)


asyncio.run(main())

Run on Kubernetes

On Kubernetes, run the container image with the Dapr sidecar injected. The injector sets DAPR_GRPC_PORT in the server’s container, so no extra configuration is needed to find the sidecar. Point the probes at the server’s health endpoints:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dapr-mcp-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dapr-mcp-server
  template:
    metadata:
      labels:
        app: dapr-mcp-server
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "dapr-mcp-server"
    spec:
      containers:
        - name: dapr-mcp-server
          image: ghcr.io/dapr/dapr-mcp-server:latest
          ports:
            - containerPort: 8080
          startupProbe:
            httpGet:
              path: /startupz
              port: 8080
            failureThreshold: 30
            periodSeconds: 2
          livenessProbe:
            httpGet:
              path: /livez
              port: 8080
          readinessProbe:
            httpGet:
              path: /readyz
              port: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: dapr-mcp-server
spec:
  selector:
    app: dapr-mcp-server
  ports:
    - port: 8080
      targetPort: 8080

Add authentication and telemetry settings as env entries on the container; see the configuration reference.

Streamable HTTP sessions are held in the server’s memory. If you run more than one replica, configure session affinity on whatever routes traffic to them, so that each client keeps reaching the same replica.

Next steps