From 54a257013f084fd061e15e5814e37cac1b90fc1c Mon Sep 17 00:00:00 2001 From: Casper Nielsen Date: Mon, 20 Apr 2026 17:32:20 +0200 Subject: [PATCH 1/2] chore(docs): add dapr mcp server docs Signed-off-by: Casper Nielsen --- .../content/en/developing-ai/mcp/_index.md | 13 +- .../mcp/mcp-server-getting-started.md | 252 +++++++++++ .../mcp/mcp-server-integrations.md | 197 +++++++++ .../developing-ai/mcp/mcp-server-overview.md | 108 +++++ .../mcp/mcp-server-tool-reference.md | 390 ++++++++++++++++++ 5 files changed, 957 insertions(+), 3 deletions(-) create mode 100644 daprdocs/content/en/developing-ai/mcp/mcp-server-getting-started.md create mode 100644 daprdocs/content/en/developing-ai/mcp/mcp-server-integrations.md create mode 100644 daprdocs/content/en/developing-ai/mcp/mcp-server-overview.md create mode 100644 daprdocs/content/en/developing-ai/mcp/mcp-server-tool-reference.md diff --git a/daprdocs/content/en/developing-ai/mcp/_index.md b/daprdocs/content/en/developing-ai/mcp/_index.md index 013fc43339d..4c63fdf9936 100644 --- a/daprdocs/content/en/developing-ai/mcp/_index.md +++ b/daprdocs/content/en/developing-ai/mcp/_index.md @@ -6,7 +6,14 @@ weight: 25 description: "Dapr helps developers run secure and reliable Model Context Protocol (MCP) servers" --- -### What does Dapr do for MCP servers? - Using Dapr, developers can interact securely with MCP servers and enable fine-grained ACLs with built-in tracing and metrics, as well as resiliency policies to handle situations where an MCP server might be down or unresponsive. - \ No newline at end of file + +### `dapr-mcp-server` — MCP server for Dapr building blocks + +The [`dapr-mcp-server`](https://github.com/dapr/dapr-mcp-server) project is a production-ready MCP server that exposes Dapr's state, pub/sub, secrets, bindings, actors, service invocation, distributed lock, cryptography, and conversation building blocks as MCP tools. Point any MCP-compatible client (Claude Desktop, Claude Code, Cursor, VS Code, Dapr Agents) at it and your agents get a curated, safety-classified tool surface over your whole Dapr runtime. + +- [**Server overview**]({{% ref mcp-server-overview.md %}}) — what the server is, how it fits alongside the Dapr sidecar, when to use it. +- [**Getting started**]({{% ref mcp-server-getting-started.md %}}) — install, configure components, make your first tool call, full environment-variable reference. +- [**Tool reference**]({{% ref mcp-server-tool-reference.md %}}) — schemas, inputs, outputs, and safety classifications for all 18 tools. +- [**Integrations**]({{% ref mcp-server-integrations.md %}}) — Claude Desktop, Claude Code, VS Code, Cursor, Dapr Agents, and custom MCP clients. +- [**Authentication**]({{% ref mcp-authentication.md %}}) — securing the server with OIDC, SPIFFE, or Dapr Sentry. diff --git a/daprdocs/content/en/developing-ai/mcp/mcp-server-getting-started.md b/daprdocs/content/en/developing-ai/mcp/mcp-server-getting-started.md new file mode 100644 index 00000000000..252ef6acdf8 --- /dev/null +++ b/daprdocs/content/en/developing-ai/mcp/mcp-server-getting-started.md @@ -0,0 +1,252 @@ +--- +type: docs +title: "Getting started with dapr-mcp-server" +linkTitle: "Getting started" +weight: 40 +description: "Install dapr-mcp-server, point it at a Dapr sidecar, and make your first tool call" +--- + +This walk-through gets you from zero to a working MCP server that an agent can call, in about ten minutes. + +## Prerequisites + +- **Dapr CLI** and **Dapr runtime** v1.14+ — install instructions at [Getting started with Dapr]({{% ref getting-started %}}). +- **An MCP-compatible client** — Claude Desktop, Claude Code, Cursor, VS Code + GitHub Copilot, or a custom client built with the MCP SDK. Wiring for each of these lives on the [integrations page]({{% ref mcp-server-integrations.md %}}). +- **Go 1.25+** — only if you're installing from source. +- **Docker** — only if you're running the container image. + +## Step 1 — Install + +Pick one of the three install methods. + +### Container (recommended) + +```bash +docker pull ghcr.io/dapr/dapr-mcp-server:latest +``` + +### Pre-built binary + +Download the platform-specific archive from the [GitHub Releases page](https://github.com/dapr/dapr-mcp-server/releases), extract, and put the binary on your `PATH`. + +### From source + +```bash +go install github.com/dapr/dapr-mcp-server/cmd/dapr-mcp-server@latest +``` + +## Step 2 — Configure Dapr components + +`dapr-mcp-server` discovers components from the Dapr sidecar on startup and **only registers tools whose component type is present**. If you have no `pubsub.*` component, `publish_event` will not be exposed — and agents won't try to call it. + +Create a `resources/` folder with the components you want available. A minimum useful set for demos: + +```yaml +# resources/statestore.yaml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: statestore +spec: + type: state.in-memory + version: v1 + metadata: [] +--- +# resources/pubsub.yaml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: pubsub +spec: + type: pubsub.in-memory + version: v1 + metadata: [] +``` + +The [server's own `resources/` folder](https://github.com/dapr/dapr-mcp-server/tree/main/resources) ships examples for every supported component type — state, pub/sub, secrets, bindings, conversation, cryptography, and lock. Copy the ones you need. + +### Cryptography prerequisite + +If you plan to use `encrypt_data` / `decrypt_data`, the crypto component needs an RSA key pair. Generate one once: + +```bash +mkdir -p resources/keys +openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out resources/keys/private.pem +openssl rsa -in resources/keys/private.pem -pubout -out resources/keys/public.pem +``` + +Reference these paths from `resources/cryptography.yaml`. + +## Step 3 — Run the server + +### stdio transport (local IDE integration) + +```bash +dapr run --app-id dapr-mcp-server \ + --resources-path resources \ + -- dapr-mcp-server +``` + +The MCP client (Claude Desktop, Cursor, etc.) launches this command as a subprocess and speaks MCP over the subprocess's stdin/stdout. + +### Streamable HTTP transport (remote or shared clients) + +```bash +dapr run --app-id dapr-mcp-server \ + --resources-path resources \ + -- dapr-mcp-server --http localhost:8080 +``` + +Any MCP client that speaks streamable HTTP can now connect to `http://localhost:8080/`. + +## Step 4 — Verify + +Confirm the server is healthy and advertising tools. + +### HTTP transport + +```bash +curl -fsS http://localhost:8080/livez +# → "OK" + +curl -fsS http://localhost:8080/readyz +# → "OK" once the Dapr sidecar is reachable and tools are registered +``` + +### Via an MCP client + +Connect, list tools, and confirm you see at least `get_components`, `invoke_service`, `invoke_actor_method`, plus the tools for whichever components you configured. + +### Via the server logs + +Look for lines like: + +```json +{"level":"INFO","msg":"Discovered Dapr components","components":{"state":true,"pubsub":true}} +{"level":"INFO","msg":"Registered tools","count":9} +``` + +## Step 5 — First real call + +Point your MCP client at the server and run this scripted sequence: + +1. `get_components` — to discover the component names. +2. `save_state` with `storeName: statestore`, `key: demo`, `value: hello`. +3. `get_state` with the same `storeName` and `key` — expect `"hello"` back. +4. `publish_event` with `pubsubName: pubsub`, `topic: greetings`, `message: "hi"`. + +If all four succeed, the MCP ⇄ Dapr path is wired up correctly. + +## Configuration reference + +Every environment variable `dapr-mcp-server` reads, grouped by subsystem. Defaults in **bold** apply when the variable is unset. + +### Transport + +| Variable | Default | Description | +| --- | --- | --- | +| `--http` (CLI flag) | **unset → stdio** | If set to `host:port`, enables streamable HTTP on that address | +| `--health-check` (CLI flag) | **unset** | Probes `http://localhost:8080/livez` once and exits 0/1 (for Dockerfile `HEALTHCHECK`) | +| `DAPR_MCP_CORS_ORIGIN` | **`*`** | CORS `Access-Control-Allow-Origin` for HTTP transport | + +### Logging + +| Variable | Default | Description | +| --- | --- | --- | +| `DAPR_MCP_SERVER_LOG_LEVEL` | **`INFO`** | `DEBUG`, `INFO`, `WARN`, `ERROR` | + +### OpenTelemetry + +Standard [OTEL SDK environment variables](https://opentelemetry.io/docs/specs/otel/protocol/exporter/) plus a few server-specific toggles. + +| Variable | Default | Description | +| --- | --- | --- | +| `OTEL_EXPORTER_OTLP_ENDPOINT` | **empty** | Base OTLP endpoint for traces + metrics + logs | +| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | inherits base | Override for traces | +| `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` | inherits base | Override for metrics | +| `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | inherits base | Override for logs | +| `OTEL_EXPORTER_OTLP_PROTOCOL` | **`grpc`** | `grpc` or `http/protobuf` | +| `OTEL_EXPORTER_OTLP_TRACES_PROTOCOL` | inherits | Per-signal override | +| `OTEL_EXPORTER_OTLP_HEADERS` | **empty** | Comma-separated `key=value` headers (e.g., API keys) | +| `OTEL_SERVICE_NAME` | **`dapr-mcp-server`** | Service name attribute on every signal | +| `OTEL_SERVICE_VERSION` | **`v1.0.0`** | Service version attribute | +| `OTEL_METRIC_EXPORT_INTERVAL` | SDK default | Go `time.Duration` — e.g., `30s` | +| `OTEL_LOG_EXPORT_INTERVAL` | SDK default | Go `time.Duration` | +| `DAPR_MCP_SERVER_METRICS_ENABLED` | **`true`** | Set to `false` to disable metrics export | +| `DAPR_MCP_SERVER_LOGS_OTEL_ENABLED` | **`true`** | Set to `false` to keep logs stdout-only | + +### Authentication + +Authentication is opt-in. Set `AUTH_ENABLED=true` and `AUTH_MODE` to one of `oidc`, `spiffe`, `dapr-sentry`, or `hybrid`. + +| Variable | Default | Description | +| --- | --- | --- | +| `AUTH_ENABLED` | **`false`** | Master switch | +| `AUTH_MODE` | **`disabled`** | `oidc`, `spiffe`, `dapr-sentry`, `hybrid`, or `disabled` | +| `AUTH_SKIP_PATHS` | **`/livez,/readyz,/startupz`** | Comma-separated list of paths that bypass auth | + +#### OIDC + +| Variable | Default | Description | +| --- | --- | --- | +| `OIDC_ENABLED` | **`false`** (auto-set by `AUTH_MODE=oidc`) | Used only with `AUTH_MODE=hybrid` | +| `OIDC_ISSUER_URL` | **empty** | Your IdP's issuer URL (must serve `/.well-known/openid-configuration`) | +| `OIDC_CLIENT_ID` | **empty** | Expected `aud` claim | +| `OIDC_ALLOWED_ALGORITHMS` | **`RS256,ES256`** | Comma-separated list of JWT signing algs | +| `OIDC_SKIP_ISSUER_CHECK` | **`false`** | Dev-only: skip issuer validation | + +#### SPIFFE + +| Variable | Default | Description | +| --- | --- | --- | +| `SPIFFE_ENABLED` | **`false`** (auto-set by `AUTH_MODE=spiffe`) | Used only with `AUTH_MODE=hybrid` | +| `SPIFFE_TRUST_DOMAIN` | **empty** | e.g., `example.org` | +| `SPIFFE_SERVER_ID` | **empty** | This server's SPIFFE ID (e.g., `spiffe://example.org/dapr-mcp-server`) | +| `SPIFFE_ENDPOINT_SOCKET` | **empty** | Workload API socket (e.g., `unix:///tmp/spire-agent/public/api.sock`) | +| `SPIFFE_ALLOWED_CLIENTS` | **empty** | Comma-separated allowed client SPIFFE IDs | + +#### Dapr Sentry + +| Variable | Default | Description | +| --- | --- | --- | +| `DAPR_SENTRY_ENABLED` | **`false`** (auto-set by `AUTH_MODE=dapr-sentry`) | Used only with `AUTH_MODE=hybrid` | +| `DAPR_SENTRY_JWKS_URL` | **empty** | Dapr Sentry JWKS endpoint | +| `DAPR_SENTRY_TRUST_DOMAIN` | **empty** | Expected SPIFFE trust domain in the JWT | +| `DAPR_SENTRY_AUDIENCE` | **empty** | Expected `aud` claim (optional) | +| `DAPR_SENTRY_TOKEN_HEADER` | **`Authorization`** | Custom header to pull the JWT from | +| `DAPR_SENTRY_JWKS_REFRESH_INTERVAL` | **`5m`** | Go `time.Duration` — how often to refresh the JWKS cache | + +See [MCP authentication]({{% ref mcp-authentication.md %}}) for end-to-end setup for each mode. + +## Troubleshooting + +### "No tools appear in my MCP client except the three core ones" + +Component discovery ran but found no conditional components. Run `dapr components list --app-id dapr-mcp-server` to see what the sidecar actually loaded, or call `get_components` from the client — empty result confirms the issue. Check your `--resources-path` and YAML filenames. + +### "Authentication rejecting every request" + +- Confirm `AUTH_ENABLED=true` and `AUTH_MODE` match what your client sends. An OIDC client can't authenticate against `AUTH_MODE=spiffe`. +- For OIDC: `OIDC_ISSUER_URL` must be exactly the `iss` claim your tokens carry, down to trailing slash. +- For SPIFFE: `SPIFFE_ENDPOINT_SOCKET` must be readable by the `dapr-mcp-server` process. +- For Dapr Sentry: `DAPR_SENTRY_JWKS_URL` must be reachable from the server — try `curl -sv` it. + +### "OTEL backend shows nothing" + +- Set `OTEL_EXPORTER_OTLP_ENDPOINT`. Without it, nothing is exported. +- If you're sending to a non-local collector, set `OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf` and use the `:4318` port — many hosted backends don't accept gRPC. +- Check logs for `OpenTelemetry initialized successfully` on startup; absence means the SDK never spun up. + +### "Dapr client initialization failed after 5 attempts" + +The server retries `dapr.NewClient()` five times with a 2-second backoff. If all fail, the Dapr sidecar never came up on its expected gRPC endpoint (`localhost:50001` by default). Ensure `dapr run` is wrapping the server command, or set `DAPR_GRPC_ENDPOINT` explicitly when running standalone. + +### "Crypto tool calls fail with 'key not found'" + +The RSA key pair from Step 2 must exist at the exact paths referenced in `resources/cryptography.yaml`. Verify with `ls resources/keys/` and match against the component YAML. + +## Next steps + +- [Tool reference]({{% ref mcp-server-tool-reference.md %}}) — full schemas and safety classifications for every tool. +- [Integrations]({{% ref mcp-server-integrations.md %}}) — per-client wiring for Claude Desktop, VS Code, Cursor, Dapr Agents. +- [Authentication]({{% ref mcp-authentication.md %}}) — deep dive into each auth mode. diff --git a/daprdocs/content/en/developing-ai/mcp/mcp-server-integrations.md b/daprdocs/content/en/developing-ai/mcp/mcp-server-integrations.md new file mode 100644 index 00000000000..77db3bde2cd --- /dev/null +++ b/daprdocs/content/en/developing-ai/mcp/mcp-server-integrations.md @@ -0,0 +1,197 @@ +--- +type: docs +title: "Connecting MCP clients to dapr-mcp-server" +linkTitle: "Integrations" +weight: 60 +description: "Wiring dapr-mcp-server into Claude Desktop, Claude Code, VS Code, Cursor, Dapr Agents, and custom clients" +--- + +`dapr-mcp-server` speaks two transports — **stdio** for IDE integrations and **streamable HTTP** for remote or shared deployments. This page shows how to wire each of the common MCP clients to either. + +Assumes you have already completed the [Getting started]({{% ref mcp-server-getting-started.md %}}) walk-through. The binary is on your `PATH` and Dapr components are configured under `./resources`. + +## Claude Desktop + +Claude Desktop launches MCP servers as stdio subprocesses, so you need a wrapper command that starts Dapr + the server together. + +Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%AppData%\Claude\claude_desktop_config.json` (Windows): + +```json +{ + "mcpServers": { + "dapr": { + "command": "dapr", + "args": [ + "run", + "--app-id", "dapr-mcp-server", + "--resources-path", "/absolute/path/to/resources", + "--", + "dapr-mcp-server" + ] + } + } +} +``` + +Restart Claude Desktop. The `dapr` server should appear in the tool picker; hovering it shows the list of registered tools. + +**Tip:** use absolute paths everywhere in this file. Claude Desktop does not inherit your shell's working directory. + +## Claude Code (CLI) + +Claude Code can register MCP servers with a single command: + +```bash +claude mcp add dapr -- dapr run \ + --app-id dapr-mcp-server \ + --resources-path "$(pwd)/resources" \ + -- dapr-mcp-server +``` + +After restart, run `claude mcp list` to confirm `dapr` is healthy. + +For a remote HTTP instance, use the `--transport http` form: + +```bash +claude mcp add dapr --transport http --url https://dapr-mcp.example.com/ +``` + +## VS Code + GitHub Copilot + +VS Code's agent mode discovers MCP servers from `.vscode/mcp.json` in the workspace (or `~/.config/Code/User/mcp.json` globally). Create the file: + +```json +{ + "servers": { + "dapr": { + "type": "stdio", + "command": "dapr", + "args": [ + "run", + "--app-id", "dapr-mcp-server", + "--resources-path", "${workspaceFolder}/resources", + "--", + "dapr-mcp-server" + ] + } + } +} +``` + +Reload the window. The Copilot chat will list `dapr-mcp-server` tools under "Available tools". + +## Cursor + +Cursor uses `.cursor/mcp.json` at the project root (or `~/.cursor/mcp.json` for global): + +```json +{ + "mcpServers": { + "dapr": { + "command": "dapr", + "args": [ + "run", + "--app-id", "dapr-mcp-server", + "--resources-path", "./resources", + "--", + "dapr-mcp-server" + ] + } + } +} +``` + +Restart Cursor, open Settings → MCP, and confirm the server is in the "Connected" list. + +## Dapr Agents (Python) + +[Dapr Agents]({{% ref "dapr-agents/_index.md" %}}) consumes MCP servers natively via `dapr_agents.tool.mcp.MCPClient`. Run `dapr-mcp-server` with HTTP transport, then point the agent at it: + +```bash +# terminal 1 — the MCP server +dapr run --app-id dapr-mcp-server \ + --resources-path resources \ + -- dapr-mcp-server --http localhost:8088 +``` + +```python +# terminal 2 — the agent +import asyncio +from dapr_agents import DurableAgent +from dapr_agents.tool.mcp import MCPClient +from dapr_agents.llm import DaprChatClient + +async def load_mcp_tools() -> list: + client = MCPClient() + await client.connect_sse("dapr", url="http://localhost:8088") + return client.get_all_tools() + +def main() -> None: + tools = asyncio.run(load_mcp_tools()) + + agent = DurableAgent( + name="Steve", + role="Expert Dapr Microservices Client", + goal=( + "Translate user intents into precise, deterministic, and safe MCP tool calls. " + "Do not invent component names, keys, topics, or arguments — discover them via " + "the 'get_components' tool." + ), + instructions=[ + "Always use available MCP tools to satisfy user requests when appropriate.", + "Break complex tasks (e.g. 'encrypt and save') into sequential tool calls.", + "Heed ReadOnlyHint / DestructiveHint in the tool schema before executing.", + "On error, parse the message and correct the request; do not ask the user.", + ], + llm=DaprChatClient(component_name="llm-provider"), + tools=tools, + ) + agent.start() + +if __name__ == "__main__": + main() +``` + +The full reference implementation — with pub/sub, durable memory, and OpenTelemetry tracing — lives at [`test/app.py`](https://github.com/dapr/dapr-mcp-server/blob/main/test/app.py) in the server's repository. + +## Custom MCP clients + +Any MCP-compliant client works. Minimal Node example using `@modelcontextprotocol/sdk`: + +```ts +import { Client } from "@modelcontextprotocol/sdk/client/index.js"; +import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; + +const transport = new StreamableHTTPClientTransport( + new URL("http://localhost:8080/"), +); +const client = new Client({ name: "my-agent", version: "0.1.0" }, { capabilities: {} }); +await client.connect(transport); + +const tools = await client.listTools(); +console.log(tools.tools.map((t) => t.name)); +// → ['get_components', 'invoke_service', 'invoke_actor_method', 'save_state', ...] + +const result = await client.callTool({ + name: "get_components", + arguments: {}, +}); +console.log(result.content); +``` + +For other languages, see the [MCP SDK list](https://modelcontextprotocol.io/introduction#sdks) on the protocol site. + +## Securing the connection + +All of the examples above assume the server is running unauthenticated on `localhost`. For any non-local deployment: + +1. Run the server with `--http` and front it with the transport (TLS) of your choice. +2. Turn on authentication — see [MCP authentication]({{% ref mcp-authentication.md %}}) for OIDC, SPIFFE, and Dapr Sentry walk-throughs. +3. Pass the bearer token / certificate from your MCP client according to its own configuration (Claude Desktop and Claude Code both support `headers` blocks in recent versions). + +## Related + +- [Overview]({{% ref mcp-server-overview.md %}}) +- [Getting started]({{% ref mcp-server-getting-started.md %}}) +- [Tool reference]({{% ref mcp-server-tool-reference.md %}}) +- [Authentication]({{% ref mcp-authentication.md %}}) diff --git a/daprdocs/content/en/developing-ai/mcp/mcp-server-overview.md b/daprdocs/content/en/developing-ai/mcp/mcp-server-overview.md new file mode 100644 index 00000000000..d55ce2c6df9 --- /dev/null +++ b/daprdocs/content/en/developing-ai/mcp/mcp-server-overview.md @@ -0,0 +1,108 @@ +--- +type: docs +title: "dapr-mcp-server overview" +linkTitle: "Server overview" +weight: 30 +description: "What dapr-mcp-server is, how it fits alongside the Dapr sidecar, and when to use it" +--- + +## What is dapr-mcp-server? + +[`dapr-mcp-server`](https://github.com/dapr/dapr-mcp-server) is a production-ready [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server, written in Go, that exposes Dapr's building blocks as MCP tools for AI agents. Instead of teaching every agent how to call Dapr's gRPC / HTTP APIs, you point the agent at this server and it gets a curated, safety-classified tool surface for state, pub/sub, secrets, service invocation, actors, bindings, distributed locks, cryptography, and conversation components. + +It is the *server-side* counterpart to clients like Claude Desktop, Cursor, VS Code Copilot, or [Dapr Agents]({{% ref "dapr-agents/_index.md" %}}). It does not generate text itself; it gives an LLM-powered client a safe, discoverable path into Dapr. + +## How it fits + +```text + ┌───────────────────┐ MCP (stdio / ┌────────────────────┐ Dapr APIs ┌──────────────┐ + │ MCP client │ ◄── streamable HTTP)──► dapr-mcp-server │◄── gRPC / HTTP ──────►│ Dapr sidecar │ + │ (agent / IDE) │ │ (18 tools, 9 pkgs)│ │ (daprd) │ + └───────────────────┘ └──────────────┬─────┘ └──────┬───────┘ + │ │ + │ ▼ + │ ┌────────────────────┐ + │ │ Dapr components │ + │ │ state, pubsub, │ + │ │ secrets, bindings, │ + │ │ actors, lock, LLM, │ + │ │ crypto ... │ + │ └────────────────────┘ + ▼ + OpenTelemetry (traces, + metrics, logs) to any + OTLP-compatible backend +``` + +The MCP client speaks only MCP. The Dapr sidecar speaks only Dapr's own APIs. `dapr-mcp-server` is the deterministic translator in the middle: every tool call becomes a specific, parameter-validated Dapr call, annotated with OpenTelemetry spans and enforced by an optional authentication layer. + +## Capabilities + +Each capability below corresponds to a package in the server and a set of tools. See the [tool reference]({{% ref mcp-server-tool-reference.md %}}) for schemas, example payloads, and safety classifications. + +| Capability | Tools | Dapr API | +| --- | --- | --- | +| Component discovery | `get_components` | [Metadata API]({{% ref metadata_api.md %}}) | +| Service invocation | `invoke_service` | [Service Invocation API]({{% ref service_invocation_api.md %}}) | +| Actors | `invoke_actor_method` | [Actors API]({{% ref actors_api.md %}}) | +| State management | `save_state`, `get_state`, `delete_state`, `execute_transaction` | [State API]({{% ref state_api.md %}}) | +| Pub/Sub | `publish_event`, `publish_event_with_metadata` | [Pub/Sub API]({{% ref pubsub_api.md %}}) | +| Bindings | `invoke_output_binding` | [Bindings API]({{% ref bindings_api.md %}}) | +| Secrets | `get_secret`, `get_bulk_secrets` | [Secrets API]({{% ref secrets_api.md %}}) | +| Conversation | `converse_with_llm` | [Conversation API]({{% ref conversation_api.md %}}) | +| Cryptography | `encrypt_data`, `decrypt_data` | [Cryptography API]({{% ref cryptography_api.md %}}) | +| Distributed locking | `acquire_lock`, `release_lock` | [Distributed Lock API]({{% ref distributed_lock_api.md %}}) | + +**Dynamic registration.** Tools register only when the corresponding Dapr component exists in the sidecar. If your deployment has no `pubsub.*` component, the pub/sub tools aren't exposed to the client and agents won't try to call them. Call `get_components` first to see what's actually live. + +## Transports + +Two transports, chosen per deployment: + +| Transport | When to use | How to enable | +| --- | --- | --- | +| **stdio** | Local IDE integration (Claude Desktop, Cursor, VS Code, Claude Code). One-process-per-client model; the IDE launches the binary as a subprocess. | Default — run `dapr-mcp-server` with no `--http` flag. | +| **Streamable HTTP** | Remote or shared deployments — Kubernetes, long-lived service, multiple concurrent clients. Carries MCP over chunked HTTP using the [streamable HTTP transport](https://modelcontextprotocol.io/specification) from the MCP spec. | `dapr-mcp-server --http ` — for example `--http localhost:8080` or `--http :8080`. | + +The HTTP transport also mounts Kubernetes-style health endpoints (`/livez`, `/readyz`, `/startupz`) and CORS middleware (configurable via `DAPR_MCP_CORS_ORIGIN`). + +## Security model + +Authentication is **off by default**. For anything beyond local development, set `AUTH_ENABLED=true` and pick a mode: + +| Mode | Who it fits | Summary | +| --- | --- | --- | +| `oidc` | Human-facing apps and agents that already carry OIDC ID tokens | Validates JWTs issued by your IdP (Auth0, Entra, Keycloak, etc.). Set `OIDC_ISSUER_URL` + `OIDC_CLIENT_ID`. | +| `spiffe` | Workload-to-workload in SPIFFE / SPIRE environments | X.509 SVID mTLS via a SPIFFE Workload API socket. Set `SPIFFE_TRUST_DOMAIN`, `SPIFFE_SERVER_ID`, `SPIFFE_ENDPOINT_SOCKET`. | +| `dapr-sentry` | Dapr-native clients that already hold a Dapr Sentry JWT | Validates JWTs issued by the local Dapr Sentry instance. Set `DAPR_SENTRY_JWKS_URL`, `DAPR_SENTRY_TRUST_DOMAIN`, `DAPR_SENTRY_AUDIENCE`. | +| `hybrid` | Mixed workloads — humans with OIDC and services with SPIFFE/Sentry on the same endpoint | Accepts any of the above; first successful validator wins. | + +See the [MCP authentication guide]({{% ref mcp-authentication.md %}}) for full per-mode setup and the [getting started page]({{% ref mcp-server-getting-started.md %}}) for the complete environment-variable reference. + +## Observability + +OpenTelemetry is wired through every tool call: + +- **Traces** — every tool invocation is a span with `tool.name`, `tool.duration_ms`, and the downstream Dapr call nested underneath. Incoming trace context from MCP clients is propagated forward via W3C `traceparent` + `baggage`. +- **Metrics** — per-tool latency histograms and invocation counters; HTTP-transport metrics for request/response sizing. +- **Logs** — structured JSON via `slog`; optional export to an OTLP collector so every log line carries the active trace ID. + +Point all three at a collector by setting `OTEL_EXPORTER_OTLP_ENDPOINT` (see [getting started]({{% ref mcp-server-getting-started.md %}}#observability) for the full variable set). Defaults produce gRPC exports to `localhost:4317`. + +## When to reach for this server + +Choose `dapr-mcp-server` when your agent needs to: + +- Persist durable state or coordinate distributed work. +- Publish events onto a shared bus, or invoke another microservice. +- Access secrets, actors, locks, cryptography primitives, or a separate LLM — all behind a single uniform tool surface. +- Run in a production environment with OpenTelemetry observability and deployment-grade authentication. + +It's **not** the right answer for pure local computation, ad-hoc shell tasks, or toy projects that never leave the laptop. For those, keep the agent free of a runtime dependency. + +## Next steps + +- [Get started]({{% ref mcp-server-getting-started.md %}}) — install, configure a sidecar, make a first tool call. +- [Tool reference]({{% ref mcp-server-tool-reference.md %}}) — schemas and safety tags for every tool. +- [Integrations]({{% ref mcp-server-integrations.md %}}) — Claude Desktop, VS Code, Cursor, Dapr Agents. +- [Authentication]({{% ref mcp-authentication.md %}}) — secure the server with OIDC, SPIFFE, or Dapr Sentry. diff --git a/daprdocs/content/en/developing-ai/mcp/mcp-server-tool-reference.md b/daprdocs/content/en/developing-ai/mcp/mcp-server-tool-reference.md new file mode 100644 index 00000000000..f3f3f56ddb1 --- /dev/null +++ b/daprdocs/content/en/developing-ai/mcp/mcp-server-tool-reference.md @@ -0,0 +1,390 @@ +--- +type: docs +title: "MCP server tool reference" +linkTitle: "Tool reference" +weight: 50 +description: "Complete reference for every MCP tool exposed by dapr-mcp-server, including input schemas, safety classifications, and example payloads" +--- + +This page is the authoritative reference for every tool exposed by [`dapr-mcp-server`](https://github.com/dapr/dapr-mcp-server). The server emits these same schemas to MCP clients at connection time; this document mirrors them in human- and agent-readable form so you can plan tool calls without inspecting the live server. + +## Conventions + +### Registration modes + +| Mode | When | Tools | +| --- | --- | --- | +| **Core** — always registered | On every startup, regardless of configured components | `get_components`, `invoke_service`, `invoke_actor_method` | +| **Conditional** — registered only when a matching Dapr component is configured | Server inspects components at startup via `daprd` metadata and registers the corresponding tool group | `state.*` → state tools · `pubsub.*` → pub/sub tools · `bindings.*` → binding tool · `secretstores.*` → secret tools · `lock.*` → lock tools · `conversation.*` → conversation tool · `crypto.*` → crypto tools | + +Call `get_components` first to learn which tools your client will actually see. + +### Safety classification + +Every tool is tagged with one or more of: + +| Tag | Meaning | +| --- | --- | +| `read-only` | No state change; safe to call repeatedly without consequence | +| `side-effect` | Changes external state (publishes, writes, acquires a lock, etc.) | +| `destructive` | Can delete or overwrite data, trigger production behavior, expose secrets | +| `idempotent` | Repeated calls with identical input produce the same end state | +| `not-idempotent` | Repeated calls produce additional effects (second publish → second message) | + +Use these tags to decide whether a call is safe to auto-retry, whether it needs human approval, and how to compose tools in a workflow. + +--- + +## Metadata + +### `get_components` + +Retrieves the list of Dapr components currently loaded in the sidecar. Always call this first when you need to discover valid component names or capabilities. + +**Safety:** `read-only`, `idempotent` + +**Inputs:** none. + +**Returns:** array of components, each with: + +| Field | Type | Description | +| --- | --- | --- | +| `name` | string | Unique component name (e.g., `statestore-redis`) | +| `type` | string | Component type (e.g., `state.redis`, `pubsub.kafka`) | +| `version` | string (optional) | Component version (e.g., `v1`) | +| `capabilities` | array of strings | Component capabilities advertised by Dapr | + +**Example response** + +```json +{ + "components": [ + {"name": "statestore", "type": "state.redis", "version": "v1", "capabilities": ["TRANSACTIONAL", "ETAG"]}, + {"name": "pubsub", "type": "pubsub.redis", "version": "v1", "capabilities": []} + ] +} +``` + +--- + +## Service invocation + +### `invoke_service` + +Calls a method on another Dapr-enabled service. Wraps the Dapr runtime's [Service Invocation API]({{% ref service_invocation_api.md %}}). + +**Safety:** `destructive`, `not-idempotent`, `side-effect` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `appID` | string | ✓ | Dapr app-id of the target service (e.g., `order-processor`) | +| `method` | string | ✓ | Method / endpoint on the target (e.g., `status`) | +| `data` | string | ✓ | Request body payload, typically JSON-encoded | +| `httpVerb` | string | ✓ | HTTP verb — `GET`, `POST`, `PUT`, `DELETE`. Default: `POST` | +| `metadata` | map[string]string | – | Optional HTTP headers | + +**Returns:** parsed response or raw response data, wrapped as the MCP result content. + +**Example request** + +```json +{ + "appID": "order-processor", + "method": "orders", + "httpVerb": "POST", + "data": "{\"orderId\":\"A-12\",\"qty\":2}", + "metadata": {"Content-Type": "application/json"} +} +``` + +--- + +## Actors + +### `invoke_actor_method` + +Executes a method on a Dapr virtual actor instance. Wraps the [Actors API]({{% ref actors_api.md %}}). + +**Safety:** `destructive`, `not-idempotent`, `side-effect` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `actorType` | string | ✓ | Registered actor type (e.g., `payment-processor`) | +| `actorID` | string | ✓ | Unique actor instance ID (e.g., `user-1001`) | +| `method` | string | ✓ | Method name on the actor (e.g., `ProcessOrder`) | +| `data` | string | ✓ | Payload passed to the actor method, typically JSON | + +**Returns:** structured result with `actor_type`, `actor_id`, `actor_method`, `actor_response`. + +--- + +## State management + +Registered when any `state.*` component is configured. Wraps the [State Management API]({{% ref state_api.md %}}). + +### `save_state` + +Persists a single key/value pair. + +**Safety:** `side-effect`, `idempotent` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `storeName` | string | ✓ | State store component name (e.g., `statestore`) | +| `key` | string | ✓ | Storage key. Convention: `||||` | +| `value` | string | ✓ | Value to persist, plain string or JSON-encoded | + +**Returns:** `key_saved`, `store_name`. + +### `get_state` + +Retrieves the value for a single key. + +**Safety:** `read-only`, `idempotent` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `storeName` | string | ✓ | State store component name | +| `key` | string | ✓ | Key to read | + +**Returns:** `key`, `value` (or `nil` if not found). + +### `delete_state` + +Removes a key. + +**Safety:** `destructive`, `idempotent`, `side-effect` + +**Inputs:** same shape as `get_state`. + +**Returns:** `key_deleted`, `store_name`. + +### `execute_transaction` + +Executes a batch of save/delete operations atomically. Requires a transactional state store (see `capabilities` from `get_components`). + +**Safety:** `destructive`, `not-idempotent`, `side-effect` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `storeName` | string | ✓ | State store component name | +| `items` | array of TransactionItem | ✓ | Operations to execute atomically | + +Each `TransactionItem`: + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `key` | string | ✓ | State key | +| `value` | string | ✓ | Value to set; ignored when `isDelete=true` | +| `isDelete` | boolean | ✓ | `true` to delete the key, `false` to save/update | + +**Returns:** `operations_executed` count, `store_name`. + +--- + +## Pub/Sub + +Registered when any `pubsub.*` component is configured. Wraps the [Pub/Sub API]({{% ref pubsub_api.md %}}). + +### `publish_event` + +Publishes a message to a topic. + +**Safety:** `not-idempotent`, `side-effect` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `pubsubName` | string | ✓ | Pub/sub component name | +| `topic` | string | ✓ | Topic name (e.g., `orders`) | +| `message` | string | ✓ | Payload, typically JSON-encoded | + +**Returns:** `status`, `pubsub_name`, `topic`. + +### `publish_event_with_metadata` + +Same as `publish_event` plus message metadata (headers / routing / TTL). + +**Safety:** `not-idempotent`, `side-effect` + +**Inputs:** adds `metadata` (map[string]string) — e.g., `{"ttlInSeconds": "60"}`. + +**Returns:** `status`, `pubsub_name`, `topic`, `metadata_keys` count. + +--- + +## Bindings + +Registered when any `bindings.*` component is configured. Wraps the [Output Bindings API]({{% ref bindings_api.md %}}). + +### `invoke_output_binding` + +Invokes an operation on an output binding to reach an external system (webhook, queue, object store, database, etc.). + +**Safety:** `destructive`, `not-idempotent`, `side-effect` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `bindingName` | string | ✓ | Binding component name | +| `operation` | string | ✓ | Binding-specific operation (e.g., `create`, `get`, `delete`) | +| `data` | string | ✓ | Payload | +| `metadata` | map[string]string | ✓ | Binding-specific metadata (e.g., `key` for a storage binding) | + +**Returns:** `binding_name`, `operation`, `response_data`. + +--- + +## Secrets + +Registered when any `secretstores.*` component is configured. Wraps the [Secrets API]({{% ref secrets_api.md %}}). + +### `get_secret` + +Retrieves a single secret by name. + +**Safety:** `read-only`, `idempotent` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `storeName` | string | ✓ | Secret store component name (e.g., `vault`) | +| `secretName` | string | ✓ | Name of the secret | +| `metadata` | map[string]string | – | Optional per-request metadata (e.g., `version_id`) | + +**Returns:** secret key/value pairs as JSON. + +### `get_bulk_secrets` + +Retrieves every secret the application has access to from a store. **High-risk** — invoke only when the user explicitly asks to enumerate. + +**Safety:** `read-only`, `idempotent` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `storeName` | string | ✓ | Secret store component name | +| `metadata` | map[string]string | – | Optional per-request metadata | + +**Returns:** count of secrets retrieved plus the full JSON payload. + +--- + +## Conversation + +Registered when any `conversation.*` component is configured. Wraps the [Conversation API]({{% ref conversation_api.md %}}). + +### `converse_with_llm` + +Delegates a reasoning / text generation turn to a downstream LLM component. Useful when the current agent needs to specialize (route to a reasoning-heavy model) or resume a long-running conversation session. + +**Safety:** `read-only`, `idempotent` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `name` | string | ✓ | LLM component name (e.g., `ollama`, `openai`) | +| `prompt` | string | ✓ | User prompt / instruction | +| `contextId` | string | – | Continues an existing session; omit to start a new one | +| `temperature` | float64 | – | `0.0`–`1.0`. Default `0.7` | + +**Returns:** full LLM response object including choices and tool calls if any. + +--- + +## Cryptography + +Registered when any `crypto.*` component is configured. Wraps the [Cryptography API]({{% ref cryptography_api.md %}}). + +### `encrypt_data` + +Encrypts plaintext using a cryptography component. + +**Safety:** `destructive`, `not-idempotent`, `side-effect` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `componentName` | string | ✓ | Crypto component name | +| `plainText` | string | ✓ | Plaintext to encrypt | + +**Returns:** `cipher_text`. + +### `decrypt_data` + +Reverses `encrypt_data`. + +**Safety:** `read-only`, `idempotent` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `componentName` | string | ✓ | Crypto component name | +| `cipherText` | string | ✓ | Base64-encoded ciphertext produced by `encrypt_data` | + +**Returns:** `plain_text`, `component_name`. + +--- + +## Distributed locking + +Registered when any `lock.*` component is configured. Wraps the [Distributed Lock API]({{% ref distributed_lock_api.md %}}). + +### `acquire_lock` + +Attempts to acquire a named lock. Always pair with `release_lock` in the same workflow. + +**Safety:** `idempotent`, `side-effect` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `storeName` | string | ✓ | Lock store component name | +| `resourceID` | string | ✓ | Unique resource name to lock | +| `lockOwner` | string | ✓ | Unique owner ID (e.g., `ai-agent-42`) | +| `expiryInSeconds` | int32 | ✓ | Auto-release timeout. Recommend 5–60 s | + +**Returns:** `lock_acquired` (bool), `resource_id`, `owner_id`. + +### `release_lock` + +Releases a lock acquired earlier by the same owner. + +**Safety:** `not-idempotent`, `side-effect` + +**Inputs:** + +| Field | Type | Required | Description | +| --- | --- | :-: | --- | +| `storeName` | string | ✓ | Lock store component name | +| `resourceID` | string | ✓ | Resource name from the matching `acquire_lock` | +| `lockOwner` | string | ✓ | Same owner ID as the matching `acquire_lock` | + +**Returns:** `release_status_code`, `release_status_text`, `resource_id`. Status codes: `SUCCESS`, `LOCK_UNEXIST`, `LOCK_BELONG_TO_OTHERS`, `INTERNAL_ERROR`. + +--- + +## Related + +- [Overview]({{% ref mcp-server-overview.md %}}) — what `dapr-mcp-server` is and when to use it +- [Getting started]({{% ref mcp-server-getting-started.md %}}) — install, configure, first request +- [Authentication]({{% ref mcp-authentication.md %}}) — securing the server with OAuth2, SPIFFE, or Dapr Sentry +- [Integrations]({{% ref mcp-server-integrations.md %}}) — wiring up Claude Desktop, VS Code, Cursor, dapr-agents From 34b6ef9a8add6856de626b136a070a4df1722e7f Mon Sep 17 00:00:00 2001 From: Casper Nielsen Date: Tue, 21 Apr 2026 09:44:28 +0200 Subject: [PATCH 2/2] fix(docs): handle dupe keys in hugo.yaml. Move dapr mcp server under own folder inside MCP Signed-off-by: Casper Nielsen --- .../content/en/developing-ai/mcp/_index.md | 11 ++----- .../mcp/dapr-mcp-server/_index.md | 14 +++++++++ .../mcp-server-getting-started.md | 2 +- .../mcp-server-integrations.md | 4 +-- .../mcp-server-overview.md | 30 ++++--------------- .../mcp-server-tool-reference.md | 2 +- hugo.yaml | 5 ---- 7 files changed, 25 insertions(+), 43 deletions(-) create mode 100644 daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/_index.md rename daprdocs/content/en/developing-ai/mcp/{ => dapr-mcp-server}/mcp-server-getting-started.md (99%) rename daprdocs/content/en/developing-ai/mcp/{ => dapr-mcp-server}/mcp-server-integrations.md (96%) rename daprdocs/content/en/developing-ai/mcp/{ => dapr-mcp-server}/mcp-server-overview.md (66%) rename daprdocs/content/en/developing-ai/mcp/{ => dapr-mcp-server}/mcp-server-tool-reference.md (99%) diff --git a/daprdocs/content/en/developing-ai/mcp/_index.md b/daprdocs/content/en/developing-ai/mcp/_index.md index 4c63fdf9936..2bf87e894de 100644 --- a/daprdocs/content/en/developing-ai/mcp/_index.md +++ b/daprdocs/content/en/developing-ai/mcp/_index.md @@ -8,12 +8,5 @@ description: "Dapr helps developers run secure and reliable Model Context Protoc Using Dapr, developers can interact securely with MCP servers and enable fine-grained ACLs with built-in tracing and metrics, as well as resiliency policies to handle situations where an MCP server might be down or unresponsive. -### `dapr-mcp-server` — MCP server for Dapr building blocks - -The [`dapr-mcp-server`](https://github.com/dapr/dapr-mcp-server) project is a production-ready MCP server that exposes Dapr's state, pub/sub, secrets, bindings, actors, service invocation, distributed lock, cryptography, and conversation building blocks as MCP tools. Point any MCP-compatible client (Claude Desktop, Claude Code, Cursor, VS Code, Dapr Agents) at it and your agents get a curated, safety-classified tool surface over your whole Dapr runtime. - -- [**Server overview**]({{% ref mcp-server-overview.md %}}) — what the server is, how it fits alongside the Dapr sidecar, when to use it. -- [**Getting started**]({{% ref mcp-server-getting-started.md %}}) — install, configure components, make your first tool call, full environment-variable reference. -- [**Tool reference**]({{% ref mcp-server-tool-reference.md %}}) — schemas, inputs, outputs, and safety classifications for all 18 tools. -- [**Integrations**]({{% ref mcp-server-integrations.md %}}) — Claude Desktop, Claude Code, VS Code, Cursor, Dapr Agents, and custom MCP clients. -- [**Authentication**]({{% ref mcp-authentication.md %}}) — securing the server with OIDC, SPIFFE, or Dapr Sentry. +- [**Dapr MCP server**]({{% ref "dapr-mcp-server" %}}) — a production-ready MCP server that exposes Dapr's building blocks as MCP tools. +- [**Authentication**]({{% ref mcp-authentication.md %}}) — securing MCP servers with OIDC, SPIFFE, or Dapr Sentry. diff --git a/daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/_index.md b/daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/_index.md new file mode 100644 index 00000000000..8e83efc5a83 --- /dev/null +++ b/daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/_index.md @@ -0,0 +1,14 @@ +--- +type: docs +title: "Dapr MCP server" +linkTitle: "Dapr MCP server" +weight: 30 +description: "A production-ready Model Context Protocol (MCP) server that exposes Dapr's building blocks as MCP tools for AI agents" +--- + +The [`dapr-mcp-server`](https://github.com/dapr/dapr-mcp-server) project is a production-ready MCP server that exposes Dapr's state, pub/sub, secrets, bindings, actors, service invocation, distributed lock, cryptography, and conversation building blocks as MCP tools. Point any MCP-compatible client (Claude Desktop, Claude Code, Cursor, VS Code, Dapr Agents) at it and your agents get a curated, safety-classified tool surface over your whole Dapr runtime. + +- [**Server overview**]({{% ref mcp-server-overview.md %}}) — what the server is, how it fits alongside the Dapr sidecar, when to use it. +- [**Getting started**]({{% ref mcp-server-getting-started.md %}}) — install, configure components, make your first tool call, full environment-variable reference. +- [**Tool reference**]({{% ref mcp-server-tool-reference.md %}}) — schemas, inputs, outputs, and safety classifications for all 18 tools. +- [**Integrations**]({{% ref mcp-server-integrations.md %}}) — Claude Desktop, Claude Code, VS Code, Cursor, Dapr Agents, and custom MCP clients. diff --git a/daprdocs/content/en/developing-ai/mcp/mcp-server-getting-started.md b/daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-getting-started.md similarity index 99% rename from daprdocs/content/en/developing-ai/mcp/mcp-server-getting-started.md rename to daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-getting-started.md index 252ef6acdf8..5ca049403a1 100644 --- a/daprdocs/content/en/developing-ai/mcp/mcp-server-getting-started.md +++ b/daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-getting-started.md @@ -2,7 +2,7 @@ type: docs title: "Getting started with dapr-mcp-server" linkTitle: "Getting started" -weight: 40 +weight: 20 description: "Install dapr-mcp-server, point it at a Dapr sidecar, and make your first tool call" --- diff --git a/daprdocs/content/en/developing-ai/mcp/mcp-server-integrations.md b/daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-integrations.md similarity index 96% rename from daprdocs/content/en/developing-ai/mcp/mcp-server-integrations.md rename to daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-integrations.md index 77db3bde2cd..17e6285bac9 100644 --- a/daprdocs/content/en/developing-ai/mcp/mcp-server-integrations.md +++ b/daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-integrations.md @@ -2,7 +2,7 @@ type: docs title: "Connecting MCP clients to dapr-mcp-server" linkTitle: "Integrations" -weight: 60 +weight: 40 description: "Wiring dapr-mcp-server into Claude Desktop, Claude Code, VS Code, Cursor, Dapr Agents, and custom clients" --- @@ -105,7 +105,7 @@ Restart Cursor, open Settings → MCP, and confirm the server is in the "Connect ## Dapr Agents (Python) -[Dapr Agents]({{% ref "dapr-agents/_index.md" %}}) consumes MCP servers natively via `dapr_agents.tool.mcp.MCPClient`. Run `dapr-mcp-server` with HTTP transport, then point the agent at it: +[Dapr Agents]({{% ref "../../dapr-agents" %}}) consumes MCP servers natively via `dapr_agents.tool.mcp.MCPClient`. Run `dapr-mcp-server` with HTTP transport, then point the agent at it: ```bash # terminal 1 — the MCP server diff --git a/daprdocs/content/en/developing-ai/mcp/mcp-server-overview.md b/daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-overview.md similarity index 66% rename from daprdocs/content/en/developing-ai/mcp/mcp-server-overview.md rename to daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-overview.md index d55ce2c6df9..0535e4a6f57 100644 --- a/daprdocs/content/en/developing-ai/mcp/mcp-server-overview.md +++ b/daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-overview.md @@ -2,7 +2,7 @@ type: docs title: "dapr-mcp-server overview" linkTitle: "Server overview" -weight: 30 +weight: 10 description: "What dapr-mcp-server is, how it fits alongside the Dapr sidecar, and when to use it" --- @@ -10,31 +10,11 @@ description: "What dapr-mcp-server is, how it fits alongside the Dapr sidecar, a [`dapr-mcp-server`](https://github.com/dapr/dapr-mcp-server) is a production-ready [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server, written in Go, that exposes Dapr's building blocks as MCP tools for AI agents. Instead of teaching every agent how to call Dapr's gRPC / HTTP APIs, you point the agent at this server and it gets a curated, safety-classified tool surface for state, pub/sub, secrets, service invocation, actors, bindings, distributed locks, cryptography, and conversation components. -It is the *server-side* counterpart to clients like Claude Desktop, Cursor, VS Code Copilot, or [Dapr Agents]({{% ref "dapr-agents/_index.md" %}}). It does not generate text itself; it gives an LLM-powered client a safe, discoverable path into Dapr. +It is the *server-side* counterpart to clients like Claude Desktop, Cursor, VS Code Copilot, or [Dapr Agents]({{% ref "../../dapr-agents" %}}). It does not generate text itself; it gives an LLM-powered client a safe, discoverable path into Dapr. ## How it fits -```text - ┌───────────────────┐ MCP (stdio / ┌────────────────────┐ Dapr APIs ┌──────────────┐ - │ MCP client │ ◄── streamable HTTP)──► dapr-mcp-server │◄── gRPC / HTTP ──────►│ Dapr sidecar │ - │ (agent / IDE) │ │ (18 tools, 9 pkgs)│ │ (daprd) │ - └───────────────────┘ └──────────────┬─────┘ └──────┬───────┘ - │ │ - │ ▼ - │ ┌────────────────────┐ - │ │ Dapr components │ - │ │ state, pubsub, │ - │ │ secrets, bindings, │ - │ │ actors, lock, LLM, │ - │ │ crypto ... │ - │ └────────────────────┘ - ▼ - OpenTelemetry (traces, - metrics, logs) to any - OTLP-compatible backend -``` - -The MCP client speaks only MCP. The Dapr sidecar speaks only Dapr's own APIs. `dapr-mcp-server` is the deterministic translator in the middle: every tool call becomes a specific, parameter-validated Dapr call, annotated with OpenTelemetry spans and enforced by an optional authentication layer. +An MCP client (agent or IDE) speaks MCP over stdio or streamable HTTP. The Dapr sidecar (`daprd`) speaks Dapr's own gRPC / HTTP APIs and fronts your components (state, pub/sub, secrets, bindings, actors, distributed lock, cryptography, conversation). `dapr-mcp-server` is the deterministic translator between the two: every tool call becomes a specific, parameter-validated Dapr call, annotated with OpenTelemetry spans (exported to any OTLP-compatible backend) and enforced by an optional authentication layer. ## Capabilities @@ -77,7 +57,7 @@ Authentication is **off by default**. For anything beyond local development, set | `dapr-sentry` | Dapr-native clients that already hold a Dapr Sentry JWT | Validates JWTs issued by the local Dapr Sentry instance. Set `DAPR_SENTRY_JWKS_URL`, `DAPR_SENTRY_TRUST_DOMAIN`, `DAPR_SENTRY_AUDIENCE`. | | `hybrid` | Mixed workloads — humans with OIDC and services with SPIFFE/Sentry on the same endpoint | Accepts any of the above; first successful validator wins. | -See the [MCP authentication guide]({{% ref mcp-authentication.md %}}) for full per-mode setup and the [getting started page]({{% ref mcp-server-getting-started.md %}}) for the complete environment-variable reference. +See the [MCP authentication guide]({{% ref "../mcp-authentication.md" %}}) for full per-mode setup and the [getting started page]({{% ref mcp-server-getting-started.md %}}) for the complete environment-variable reference. ## Observability @@ -105,4 +85,4 @@ It's **not** the right answer for pure local computation, ad-hoc shell tasks, or - [Get started]({{% ref mcp-server-getting-started.md %}}) — install, configure a sidecar, make a first tool call. - [Tool reference]({{% ref mcp-server-tool-reference.md %}}) — schemas and safety tags for every tool. - [Integrations]({{% ref mcp-server-integrations.md %}}) — Claude Desktop, VS Code, Cursor, Dapr Agents. -- [Authentication]({{% ref mcp-authentication.md %}}) — secure the server with OIDC, SPIFFE, or Dapr Sentry. +- [Authentication]({{% ref "../mcp-authentication.md" %}}) — secure the server with OIDC, SPIFFE, or Dapr Sentry. diff --git a/daprdocs/content/en/developing-ai/mcp/mcp-server-tool-reference.md b/daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-tool-reference.md similarity index 99% rename from daprdocs/content/en/developing-ai/mcp/mcp-server-tool-reference.md rename to daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-tool-reference.md index f3f3f56ddb1..e42509d5516 100644 --- a/daprdocs/content/en/developing-ai/mcp/mcp-server-tool-reference.md +++ b/daprdocs/content/en/developing-ai/mcp/dapr-mcp-server/mcp-server-tool-reference.md @@ -2,7 +2,7 @@ type: docs title: "MCP server tool reference" linkTitle: "Tool reference" -weight: 50 +weight: 30 description: "Complete reference for every MCP tool exposed by dapr-mcp-server, including input schemas, safety classifications, and example payloads" --- diff --git a/hugo.yaml b/hugo.yaml index 73414832ed9..c2404885814 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -133,11 +133,6 @@ params: # current doc set. version: v1.17 - # Flag used in the "version-banner" partial to decide whether to display a - # banner on every page indicating that this is an archived version of the docs. - # Set this flag to "true" if you want to display the banner. - archived_version: false - # A link to latest version of the docs. Used in the "version-banner" partial to # point people to the main doc site. url_latest_version: https://docs.dapr.io