> ## Documentation Index
> Fetch the complete documentation index at: https://docs.duvo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Building an MCP Server for Duvo

> Build a custom MCP server that Duvo can connect to. Covers transport, authentication, tool design, and deployment requirements.

> **Note:** Building a Custom MCP server requires software development expertise. This page assumes familiarity with API development and deployment. If you're new to MCP, start with the [official MCP documentation](https://modelcontextprotocol.io/docs/getting-started/intro), which has tutorials and SDKs in multiple languages.

To build an MCP server that Duvo can use, your server needs to meet a few technical requirements so Duvo can connect to it as a [custom MCP Connection](/mcp/custom-mcp-servers). This page covers transport, authentication, tool design, and deployment. For the user-facing setup steps in Duvo once your server is live, see the [Custom MCP connection page](/user-guide/connections/available-connections/custom-mcp).

## Requirements

For Duvo to call your MCP server, it must meet these technical requirements:

* **Cloud accessibility** — The server must be reachable over the public internet via HTTPS. Localhost and private-network-only endpoints are not supported.
* **Streamable HTTP transport** — Duvo requires MCP's Streamable HTTP transport. Servers that only expose STDIO or the older HTTP/SSE transport cannot connect.
* **Valid HTTPS certificate** — Self-signed certificates may fail to connect; use a certificate from a trusted CA.

## Authentication options

Pick whichever method fits your deployment:

* **None** — No auth. Use this only when the server handles auth at the network layer or genuinely has no auth surface.
* **Static API key or token** — Each teammate enters their own key when they sign into the Connection. Duvo passes the key as a bearer token (or however your server expects it).
* **Custom HTTP headers** — Each teammate provides their own header values when they sign in. Use this for any auth that doesn't fit "API key as bearer token".
* **OAuth** — Recommended for multi-user deployments. Duvo detects [Dynamic Client Registration (RFC 7591)](https://datatracker.ietf.org/doc/html/rfc7591) automatically; if your server supports DCR, teammates can connect with no Client ID/Secret setup at all.

### Implementing OAuth with DCR

Supporting DCR is the most polished experience for Duvo users. The MCP server side typically needs:

* A `GET /.well-known/oauth-protected-resource` endpoint declaring the authorization server (RFC 9728)
* A `WWW-Authenticate: Bearer resource_metadata=...` challenge on 401 responses
* A backing OAuth authorization server that implements [RFC 7591 Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591)

If your authorization server doesn't support DCR, you can still use OAuth — teammates will enter a pre-registered Client ID and Client Secret when setting up the Connection, and you'll need to register Duvo's redirect URI (`https://platform.duvo.ai/v1/oauth/mcp/callback`) on your provider.

## Designing your tools

A few practical guidelines that pay off when Duvo Agents call your tools:

* **Describe every tool clearly.** The description is what an Agent sees when deciding whether to call it.
* **Use flat input schemas.** A single top-level object reads better than wrapping params in `query`, `body`, etc.
* **Return structured data when possible** (JSON, not just human-readable strings). The Agent can pick out the field it needs without re-parsing.
* **Surface errors as proper MCP errors** rather than 200 responses with an error string in the body. Duvo's Agents can retry or escalate more reliably this way.
* **Idempotency keys** on destructive operations are a good defense against accidental double-calls.

## Hosting

You're free to host MCP servers wherever you like — Cloud Run, Lambda + API Gateway, Fly, a VM, a managed PaaS, your own Kubernetes cluster. Anything that can expose a public HTTPS endpoint works.

For small-scale deployments, a single container behind a TLS-terminating load balancer is usually enough. Add caching where it helps, and rate-limit defensively if the underlying system is sensitive to bursts.

## After deploying

Once your server is running publicly:

1. Open the [Connections page](https://app.duvo.ai/integrations) in Duvo.
2. Click **Add custom connection** at the bottom of the catalog.
3. Pick your auth method, enter the server URL, and click **Create**.
4. Each teammate signs into the new Connection with their own credentials.

For the full UI walkthrough, see [Custom MCP](/user-guide/connections/available-connections/custom-mcp).

## Related

* [Connect a custom MCP to Duvo](/mcp/custom-mcp-servers) — add your finished server to Duvo as a Connection
* [Custom MCP connection page](/user-guide/connections/available-connections/custom-mcp) — full setup walkthrough
* [Official MCP documentation](https://modelcontextprotocol.io) — protocol spec, SDKs, and reference servers
