Connecting to the MCP server
How to connect Claude Code, Cursor, Claude Desktop, and other MCP clients to the Oxagen MCP server.
Prerequisites
You need an Oxagen API key. Create one on the workspace's Settings → API keys tab. A workspace key acts as a Member of its workspace, never as the person who created it. An organization key from Organization → API keys also connects, but its calls run at the organization level with no workspace. See Authentication.
The MCP server endpoint is:
https://mcp.oxagen.sh/mcpTransport: streamable HTTP (the current MCP protocol standard).
Manual configuration by client
Claude Code
Register the server from a terminal. The URL is a positional argument:
claude mcp add --transport http oxagen https://mcp.oxagen.sh/mcp \
--header "Authorization: Bearer $OXAGEN_API_KEY"Add --scope project to write the entry to .mcp.json at the repository root, so everyone who clones the repo gets the server. That file looks like this:
{
"mcpServers": {
"oxagen": {
"type": "http",
"url": "https://mcp.oxagen.sh/mcp",
"headers": {
"Authorization": "Bearer ${OXAGEN_API_KEY}"
}
}
}
}Run claude mcp list to confirm the server connects.
Claude Desktop
On a machine enrolled for Claude Desktop, enrollment already wrote an oxagen entry, so skip this step. See Enrolled machines.
Claude Desktop's config file starts only local (stdio) servers, and its remote connectors sign in with OAuth, which the Oxagen MCP server does not use. Bridge to the HTTP endpoint with mcp-remote, which needs Node.js on your machine. Add this to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"oxagen": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.oxagen.sh/mcp", "--header", "Authorization:${OXAGEN_AUTH_HEADER}"],
"env": {
"OXAGEN_AUTH_HEADER": "Bearer ox_…"
}
}
}
}The header value goes through env because some launchers split an argument that contains a space. Restart Claude Desktop after saving.
Cursor
Add this to ~/.cursor/mcp.json (%USERPROFILE%\.cursor\mcp.json on Windows), or to .cursor/mcp.json in a project. Replace ox_… with your workspace API key:
{
"mcpServers": {
"oxagen": {
"url": "https://mcp.oxagen.sh/mcp",
"headers": {
"Authorization": "Bearer ox_…"
}
}
}
}Reload Cursor, then confirm that search_steering and read_steering appear in its Oxagen tool list.
Dashboard rule
A Cursor team admin can add a rule that asks the agent to read the workspace's steering records before each task. Team rules need a Cursor Team or Enterprise plan.
- In Oxagen, open Agents, choose the Cursor agent, and open Steering.
- Under Dashboard rule, select Copy in the Cursor team dashboard readout.
- Open Rules in the Cursor dashboard.
- Add a team rule and paste the copied text.
- Leave the file pattern empty, enable the rule, and save it.
Select Enforce this rule if team members must keep it enabled. Cursor's team rule guide explains these settings.
The rule calls search_steering for the task's repository, then read_steering for the records the task needs. It reads every always-on result and follows mentions of other records.
Enrolled hosts
Enroll the machine with oxagen agent enroll --harness cursor to install the hooks that the Cursor editor and CLI both read. Enrollment also delivers steering at the start of a run and records its manifest, which lists what was included or cut. See Wrap an agent.
Enrollment adds no Cursor MCP server entry. Keep the MCP configuration and dashboard rule above. Cursor sends model calls to its own servers, so Oxagen's model gateways do not add steering to those calls.
Codex
export OXAGEN_API_KEY=ox_…
codex mcp add oxagen --url https://mcp.oxagen.sh/mcp --bearer-token-env-var OXAGEN_API_KEY
codex mcp listThis writes the entry to ~/.codex/config.toml. Codex reads the key from OXAGEN_API_KEY when it connects, so the key never lands in the file:
[mcp_servers.oxagen]
url = "https://mcp.oxagen.sh/mcp"
bearer_token_env_var = "OXAGEN_API_KEY"VS Code (with MCP extension)
Add this to your VS Code settings.json:
{
"mcp": {
"servers": {
"oxagen": {
"type": "http",
"url": "https://mcp.oxagen.sh/mcp",
"headers": {
"Authorization": "Bearer ox_…"
}
}
}
}
}Programmatic (Node.js / TypeScript)
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(
new URL("https://mcp.oxagen.sh/mcp"),
{
headers: {
Authorization: `Bearer ${process.env.OXAGEN_API_KEY}`,
},
}
);
const client = new Client(
{ name: "my-app", version: "1.0.0" },
{ capabilities: {} }
);
await client.connect(transport);
// List available tools
const tools = await client.listTools();
// Call a tool
const result = await client.callTool({
name: "list_workspace_memories",
arguments: { harness: "claude-code" }
});A tool has the name of the capability behind it, with no translation step: verb-first snake_case, such as list_workspace_memories or list_agent_tools. See MCP tools for the list.
Enrolled machines
On a machine you enrolled with oxagen agent enroll, no config file needs an API key. Enrollment adds an oxagen MCP server to Claude Code's user config (~/.claude.json), to Claude Desktop's config, and to Stella's config. That entry holds no Oxagen key. It reaches Oxagen through the collector on the machine, which holds the credential.
- Calls go out under the machine's gateway key. Among Oxagen's own tools, that key can call only those that change nothing and are not high-sensitivity.
- The connection also lists the tools of the workspace's own MCP servers. See External MCP servers.
record_reflectionandremember_lessonwork only through this entry. Called with an API key, they refuse withno_watched_run.- Enrollment adds no entry for Codex or Cursor.
oxagen codegraph initadds one for every agent on the machine.
Restart Claude Desktop to load the entry. Claude Code loads it in the next session it starts.
Scope and isolation
Every connection to the MCP server runs in the org the API key belongs to, and in its workspace when it is a workspace key. The server routes each tool call to that tenant. A caller cannot reach another org's data through the connection, even with that org's resource IDs.
Verifying the connection
The tool list loads with any well-formed key, so call a tool to confirm the key works. get_install_instructions makes a safe first call. The client field is required:
{
"name": "get_install_instructions",
"arguments": { "client": "claude-code" }
}Supported client values: claude-code, cursor, claude-desktop, codex, vscode. The tool returns copy-ready setup steps for that client, with placeholders for your key. Add an enrollmentToken, and the claude-code, codex, and cursor steps enroll the machine instead.
Troubleshooting
401 Unauthorized: The request has no Authorization: Bearer header, or the header is malformed. Check the header in your client's config.
A tool call fails with MCP request unauthorized: Oxagen refused the key, and the message names the reason. invalid_token means an unknown or revoked key. The others are expired_token, workspace_archived, and sso_required, which means the organization requires single sign-on and the key's creator has not signed in through it. Create a new key on the workspace's Settings → API keys tab.
Tool call denied: A key acts with its own role, never its creator's. A workspace key is a Member of its workspace, or a custom role on Enterprise, so a tool that needs an Owner or Admin refuses it with forbidden. A rule can also hold the call for a person's approval. See Authentication and RBAC and roles. Oxagen records each denial as a capability.invoke_denied event in Organization → Audit.
Tool not in the list: The server lists the same Oxagen tools for every key, and a rule answers each call when the call is made. An Oxagen tool missing from the list is not exposed on the MCP surface. See MCP tools. The tools of the workspace's own MCP servers appear only on an enrolled machine's connection. See Enrolled machines.
Connection drops during a long tool call: A proxy between your client and the server may close a long-held connection. Long-running capabilities, such as starting a background task, return a task ID at once, and Inngest runs the work in the background.