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

# MCP server

> Connect Claude, Cursor, or any MCP client to your Sidenet organization.

Sidenet exposes its API over the [Model Context Protocol](https://modelcontextprotocol.io),
so an AI assistant can inspect and manage your agents, networks, prompt blocks,
workflows and tools directly.

<Info>
  **Endpoint** — `https://api.sidenet.ai/api/mcp/sidenet-api/mcp` (Streamable HTTP)
</Info>

## What it can do

The server exposes the **whole API reference** — one tool per endpoint, plus
`get_connection_info` for confirming which organization the connection is scoped
to. Each tool is named after its endpoint's title in the API reference — "List
agents" (`GET /v1/agents`) is `list_agents`, "Run workflow" is `run_workflow` —
and a new endpoint becomes a tool the moment it is documented.

That means everything the API can do, an MCP client can do: read and create
agents, workflows, prompt blocks, networks, tools, tool providers, users and
groups; save drafts, publish, activate and delete; run agents, networks,
workflows and experiments; and manage workflow schedules.

<Warning>
  These tools act for real. `run_workflow` executes the workflow — its steps
  call tools and models, and those side effects are not undoable. Publish and
  activate change what your organization's users get immediately, and the
  delete tools remove things permanently. An assistant should reach for them
  because you asked, not to explore — `get_workflow` describes a workflow
  without running anything.
</Warning>

The one exception is streaming chat. `POST /v1/chat` streams its response, and
an MCP tool call returns a single result, so the chat-stream endpoints are not
tools — `run_agent` and `run_network` are the same capability in request/response
form. Use the SDK or the HTTP API for streaming chat.

## Connecting

### With an API key

Best for Claude Code, Cursor, and anything you configure from a file. Use an API
key from **studio.sidenet.ai → API keys**.

```bash theme={null}
claude mcp add --transport http sidenet https://api.sidenet.ai/api/mcp/sidenet-api/mcp \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "X-User-Id: you@example.com"
```

Or, in a client that reads `.mcp.json` / `claude_desktop_config.json`:

```json theme={null}
{
  "mcpServers": {
    "sidenet": {
      "type": "http",
      "url": "https://api.sidenet.ai/api/mcp/sidenet-api/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY",
        "X-User-Id": "you@example.com"
      }
    }
  }
}
```

An API key belongs to exactly one organization, so a connection made this way is
scoped to that organization and cannot switch.

### With OAuth

Best for Claude Cowork and claude.ai, which have no field for a header. Add
`https://api.sidenet.ai/api/mcp/sidenet-api/mcp` as a custom connector. The client
discovers the flow on its own and opens a Sidenet consent screen, which asks for
an API key — the same one you'd paste into a config file. Approve, and the client
receives a token.

That token is a **handle on the key**, not a separate credential: it reaches
exactly what the key reaches, and revoking the key in the studio disconnects the
client immediately. You can also revoke a single client's token without touching
the key.

<Note>
  Because the token is bound to one API key, an OAuth connection is scoped to
  that key's organization, exactly like a header connection.
</Note>

## Which organization am I in?

Every connection is pinned to one organization by its credential. `get_connection_info`
reports which one, so an assistant can confirm the workspace before it starts
naming agents. To work in a different organization, connect with a key from it.

### Connecting to several organizations

Add one connector per organization, each with that organization's API key.

Clients that manage connectors for you — Claude Cowork, claude.ai — key them by
URL and reject a duplicate, so label each URL with the organization's **id**:

```
https://api.sidenet.ai/api/mcp/sidenet-api~eb89cdfb/mcp
https://api.sidenet.ai/api/mcp/sidenet-api~a71f0c42/mcp
```

The label after `~` doesn't select the organization — your key does that — it
just makes the URL distinct. It is checked against the key, so a URL labelled for
one organization used with another's key is refused rather than quietly working
on the wrong data. A mismatch tells you which labels would have worked.

Use either the first block of the id or the whole thing. You'll find it in the
studio URL while viewing that organization:

```
https://studio.sidenet.ai/api/orgs/eb89cdfb-36a0-4743-ba57-2321ee5a2247/...
                                   ^^^^^^^^
```

<Note>
  Names aren't accepted as labels. An id never changes, so the URL keeps working
  after someone renames the organization.
</Note>

<Note>
  The plain `https://api.sidenet.ai/api/mcp/sidenet-api/mcp` keeps working
  unchanged — labels are only needed when you want more than one connector.
</Note>

## End-user identity

User-scoped endpoints (chat runs, threads, user workflows) act on behalf of an
end user as well as an organization — the same `X-User-Id` you can send over
HTTP. Every tool therefore accepts an optional `userId`, and a tool that needs
one will say so in its error; the org-scoped tools work without it.

With a header connection you can set it once for the whole session by sending
`X-User-Id` alongside `Authorization`.

## Results

Tools return `{ status, ok, data }`, mirroring the HTTP response. A `404` or
`400` comes back as data rather than an error, so the assistant can read the
reason and correct itself.

Every tool declares its result shape, so the answer arrives as MCP
`structuredContent` — a parsed object — not as a JSON string the client has to
parse itself.

Very large responses are cut off with `truncated: true` and a note. Narrowing the
request — a filter, a page, or fetching one record by id — returns the rest.

The tool catalogue is the response most likely to hit that limit, because every
tool carries its full JSON schema. `list_tools` accepts `basic: true`, which
returns just the provider `id`/`name`/`type`/`base_url` and each tool's
`id`/`name`/`description` — enough to choose a tool, small enough to keep in
context. Fetch the same tool again without `basic` when you need its schema. It
also accepts `limit` and `offset` to page through the catalogue.

## Permissions

An MCP connection can reach exactly what its credential can reach, and nothing
more: every tool call is re-authenticated and re-authorized against the same
middleware as a direct HTTP request. Revoking an API key in the studio ends
access immediately.
