---
title: "MCP server"
description: "Connect your coding agent to mordn. It signs you in once, then creates agents, publishes config, mints keys, adds knowledge and hands you the install code — no dashboard round-trip."
---

mordn runs a remote [Model Context Protocol](https://modelcontextprotocol.io) server at
`https://www.mordn.com/mcp`. Connect it to Claude Code, Cursor, Windsurf, VS Code or
Claude Desktop and your coding agent can do everything the dashboard does for getting
an agent live: create it, publish its configuration, mint the server API key, point it
at your docs, and give you the exact route and component to paste in.

You sign in with your mordn account once, in the browser, when the client first
connects. No API key to copy, no `.env` to hand-edit — the agent puts the key where
it belongs.

> **Note**
>
> **Brand new to mordn?** Connecting is also how you sign up. The OAuth screen creates
> your account if you do not have one yet, and `mordn_create_agent` creates your
> first agent. Under a minute from "add an AI assistant to my app" to a working chat.

## Connect

1. **Claude Code**

    ```bash
    claude mcp add --transport http mordn https://www.mordn.com/mcp
    ```
    The first tool call opens your browser to sign in. Then try: *"Add a mordn agent to
    this app that answers questions about our docs at https://docs.example.com."*

2. **Cursor**

    Add to `~/.cursor/mcp.json` (or the project's `.cursor/mcp.json`) and click
    **Connect** in Settings → MCP when the server appears:
    ```json title=".cursor/mcp.json"
    {
      "mcpServers": {
        "mordn": { "url": "https://www.mordn.com/mcp" }
      }
    }
    ```

3. **Windsurf / VS Code**

    Both accept the same remote-server shape:
    ```json title="mcp_config.json"
    {
      "mcpServers": {
        "mordn": { "serverUrl": "https://www.mordn.com/mcp" }
      }
    }
    ```
    VS Code: **MCP: Add Server → HTTP**, URL `https://www.mordn.com/mcp`.

4. **Claude Desktop (stdio-only clients)**

    Bridge with `mcp-remote`:
    ```json title="claude_desktop_config.json"
    {
      "mcpServers": {
        "mordn": {
          "command": "npx",
          "args": ["-y", "mcp-remote", "https://www.mordn.com/mcp"]
        }
      }
    }
    ```

## What your agent can do

| Tool | What it does |
| --- | --- |
| `mordn_get_started` | The 60-second orientation: install shape, the identity rule, and the tool sequence. Agents call this first. |
| `mordn_create_agent` | Create an agent, publish version 1 (model, system prompt, layout, features) and make it installable: `runtime: "server"` mints a live `MORDN_CHAT_KEY`; `runtime: "hosted"` (no server route — Vite, Lovable, Bolt) enables [hosted mode](/docs/hosted-mode) for your `origin` and identity (`supabaseUrl`, `jwksUrl`, or `anonymous`) and returns the public publishable key. Both return the install code. Optionally ingest a docs URL in the same call. |
| `mordn_enable_hosted_mode` | Switch an existing agent to hosted mode, or add origins later (the key stays the same). Returns the publishable key and the component. |
| `mordn_install_snippet` | Code for your framework (`nextjs-app`, `nextjs-pages`, `remix`, `express`, `vite`), auth provider (`clerk`, `authjs`, `supabase`, `lucia`, `custom`, `none`) and runtime (`server`: route + component with `getUserId` already correct; `hosted`: component with `publishableKey` and `getUserToken`). |
| `mordn_add_knowledge` | Ground the agent in a page, sitemap, `llms.txt`, a depth-limited crawl, or raw text. Answers cite the source. |
| `mordn_describe_config` | Return the canonical `AgentConfig` paths, types, defaults, enum values and constraints directly from the installed widget package. There is no separate MCP field list to drift. |
| `mordn_get_config` / `mordn_update_config` | Read the complete published config, then apply a deep canonical patch and publish a new version. Omitted fields are preserved; rollback stays available in the dashboard. |
| `mordn_list_models` | The live model catalog. |
| `mordn_create_api_key` | Another server key for an existing agent (e.g. one per environment). |
| `mordn_list_agents` / `mordn_agent_status` | What you have, whether it is published, and real conversation counts — the quickest way to confirm an install worked. |

## A typical session

> **You:** Add an AI assistant to this app. It should answer questions from our docs at
> https://docs.acme.dev and be a full-page chat at /assistant.
>
> **Agent:** calls `mordn_get_started`, then `mordn_create_agent` with
> `layout: "page"`, `knowledgeUrl: "https://docs.acme.dev/sitemap.xml"`, `framework:
> "nextjs-app"`, `auth: "clerk"` → gets the key and the code → writes
> `app/api/chat/[[...chat]]/route.ts`, `components/assistant.tsx`,
> `app/assistant/page.tsx`, appends `MORDN_CHAT_KEY` to `.env.local` → runs the build →
> calls `mordn_agent_status` after you send the first message.

> **You (in a Vite + Supabase app):** Add a mordn agent to this app. It runs on
> https://app.acme.dev and localhost:5173; our Supabase project is https://xyz.supabase.co.
>
> **Agent:** calls `mordn_create_agent` with `runtime: "hosted"`, `framework: "vite"`,
> `auth: "supabase"`, `origin: "https://app.acme.dev"`, `additionalOrigins:
> ["http://localhost:5173"]`, `supabaseUrl: "https://xyz.supabase.co"` → gets the
> publishable key and the component → writes `src/components/Assistant.tsx` with
> `getUserToken` reading the Supabase session. No route, no env var →
> calls `mordn_agent_status` after you send the first message.

## Edit configuration without losing capabilities

The MCP does not maintain aliases such as a second top-level `layout` or flatten
structured prompts into strings. Configuration has one contract: the widget's
canonical `AgentConfig`.

1. Call `mordn_describe_config` to discover every supported path and constraint.
2. Call `mordn_get_config` to inspect what is currently published.
3. Call `mordn_update_config` with only an `agentId`, a canonical `patch`, and an
   optional version `label`.

`patch` uses [JSON Merge Patch](https://www.rfc-editor.org/rfc/rfc7396) semantics:
omitted fields stay untouched, nested objects merge, arrays replace, and `null`
explicitly removes an optional field. Unknown or invalid fields fail the call instead
of disappearing from the next published version.

```json
{
  "agentId": "agt_…",
  "patch": {
    "client": {
      "display": { "starterPromptsLayout": "grid" },
      "starterPrompts": [
        {
          "title": "Brief my portfolios",
          "subtitle": "Performance, risk, and notable moves"
        }
      ]
    }
  },
  "label": "Improve the empty state"
}
```

The server merges against the complete published document, validates the result with
the same schema used by the widget and dashboard, and preserves fields introduced by a
newer control plane rather than stripping them.

## Security

> **Security**
>
> - The server acts **only as you**. Every tool runs as the Clerk user who authorized the
>   connection, through the same ownership checks the dashboard uses. There is no way to
>   pass another user or another account's agent.
> - `mordn_create_agent` and `mordn_create_api_key` return the plaintext key **once**; only
>   its hash is stored. Your agent is instructed to write it to server-only env, never
>   into client code. Revoke keys any time in the dashboard.
> - The install code keeps mordn's identity boundary: `getUserId` reads your verified
>   server session, never a header or body. See [Security model](/docs/security).
> - Disconnecting the server in your client revokes its access; you can also revoke the
>   OAuth grant from your account.

## Prefer a prompt over a server?

The same install is available as a plain-Markdown skill your agent can fetch without
any connection: [SKILL.md](https://mordn.com/SKILL.md), or the copyable prompt on the
[Build with agents](https://mordn.com/agents) page. The MCP server is the faster path because it can
create the agent and the key for you; the skill file stops at "get a key from the
dashboard".
