---
title: "Connecting an agent"
description: "How to connect an AI agent to Notarium: a personal access token (PAT), an OAuth connector for web clients, and the POST /mcp transport."
---

# Connecting an agent

An agent talks to Notarium through a single endpoint — `POST /mcp`. This is the built-in [MCP gateway](/docs/agents/intent-tools/): the same engine and the same data as in the web editor, but with a narrow set of intent tools instead of direct access to storage. You can connect an agent two ways: with a personal access token (PAT) for programmatic clients, or with an OAuth connector for the browser-based claude.ai and chatgpt.com.

## Transport: POST /mcp

The `POST /mcp` endpoint implements the streamable-HTTP transport from the official `@modelcontextprotocol/sdk`. It is **stateless**: every request spins up a fresh server with your token's permissions and returns a single JSON response (not an SSE stream). `GET` and `DELETE` return `405` — there are no server-initiated streams here.

The endpoint is compatible with the Claude API MCP connector, Claude Code, and any HTTP-MCP client that can send a Bearer token.

```bash
curl -sS https://notarium.example.com/mcp \
  -H "Authorization: Bearer ntp_<id>_<secret>" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

## Option 1. Personal access token (PAT)

A PAT is the primary path for programmatic clients (Claude API, Claude Code, configurable MCP clients). The token is passed in the `Authorization: Bearer <pat>` header.

The token format is `ntp_<id>_<secret>`: the `ntp_` prefix makes the token easy to spot in logs and leaks, the id part is for fast lookup, and the secret is stored in the database only as a hash and shown exactly once, at issue time.

You can issue a token two ways:

- **In the UI** — the tokens section in settings. You set a name, a level (`read` or `write`), and optionally a scope narrowed to specific spaces and an expiry.
- **Via the API** — `POST /api/me/tokens`. It requires the `self:manage` permission, which means only you can issue a token — through a session — and never the agent itself (a leaked token cannot issue a new one).

> [!important] A token's permissions are a ceiling
> A `read` token does not even **see** the writing tools in `tools/list` — they don't "show up and then refuse," they're simply absent from the list. A token's set of spaces determines which spaces the agent can reach; anything outside them is unreachable by design. A token's permissions can be changed after issuance (name, level, set of spaces) without recreating the secret — the change takes effect on the next call.

## Option 2. OAuth connector for web clients

The web interfaces of **claude.ai** and **chatgpt.com** accept only OAuth when you add a "custom connector" — there's no field to paste a Bearer token. For this, Notarium ships a thin **OAuth 2.1 facade** (Notarium acts as its own Authorization Server — there's nothing to delegate to; a self-host owns the accounts).

How it works:

1. A request to `POST /mcp` without a token returns `401` with a `WWW-Authenticate` header pointing to the discovery documents (RFC 9728 / RFC 8414).
2. The client goes through `GET /oauth/authorize` — you log in with your current session and, on the consent screen, choose spaces (multi-select, defaulting to "All spaces").
3. `POST /oauth/token` with PKCE (the S256 method) issues an access token (`nto_…`) and, with `offline_access`, a refresh token (`ntr_…`).

The issued token maps to the same principal and is validated at the same checkpoint as a PAT and a session. Its level is `read` or `write`, but **never `manage`**: a leaked connector token cannot issue a new token or grant access. You can manage connections and change their level or set of spaces in the Connected apps section without going through consent again.

> [!note] Claude and ChatGPT connect via OAuth
> Notarium is added to ChatGPT as an ordinary connector on top of the same OAuth — just like in claude.ai: log in with your current session, choose spaces on the consent screen, and the agent sees your usual set of intent tools.

## The none mode: no token

If an instance is launched with `AUTH_MODE=none` (desktop, dev, a trusted intranet — the operator deliberately turns authentication off), the gateway runs without authentication: `/mcp` acts as a single all-access principal, and claude.ai/ChatGPT add it as an authless connector out of the box. There is no OAuth facade in this mode.

> [!warning] An authless server is public
> In `none` mode, whoever knows the URL can call it. That's acceptable only for single-user, demo, or trusted-network setups. For a multi-user instance, use `AUTH_MODE=password` (the default).

## Next

- [Agent rules](/docs/agents/agent-files/) — how to make sessions start with `start_session` instead of you asking for it every time.
- [Intent tools](/docs/agents/intent-tools/) — the full set of 21 tools and the order of calls.
- [Security and visibility](/docs/agents/security/) — how permissions are applied on every call.
- [Quick start: connect an agent](/docs/getting-started/connect-agent/) — a minimal end-to-end example.
