← Docs · 日本語

AgenTrux MCP Server

AgenTrux runs a hosted MCP server. Point any MCP-spec-compliant client (Cursor / Claude Desktop / Claude / Cline …) at the URL below and connect directly — no plugin to install. You add one MCP Server URL to your client config and you are done.

You never paste a JWT or an activation code into the config. On first connect the client runs the OAuth flow, and from then on it refreshes the token automatically under the hood.

Endpoint

Item Value
MCP connection URL (for OAuth clients) https://api.agentrux.com/mcp/c/<connection-id> (issued in the Console; 1 URL = 1 Script)
Default URL (headless) https://api.agentrux.com/mcp (only for Bearer tokens obtained via client_credentials / device flow)
Transport Streamable HTTP (POST / GET / DELETE)
MCP protocol version 2025-06-18 (negotiated; see below)
Auth OAuth 2.1 + PKCE (Bearer JWT)
Token audience (resource) the connection URL itself (https://api.agentrux.com/mcp/c/<connection-id>)

Client configuration

Do not put tokens or secrets in the config. On first connect the client runs the OAuth flow; afterwards it refreshes automatically.

Cursor (.cursor/mcp.json)

{
  "mcpServers": {
    "agentrux": {
      "url": "https://api.agentrux.com/mcp/c/your-connection-id",
      "transport": "streamable-http"
    }
  }
}

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "agentrux": {
      "url": "https://api.agentrux.com/mcp/c/your-connection-id",
      "transport": "streamable-http"
    }
  }
}

One MCP Server entry maps to one connection context (Script). To switch between multiple Scripts, register separate entries ("agentrux-A", "agentrux-B" …); each gets its own permissions (scopes) in its token.

Connecting from Claude Code (CLI)

Claude Code has a dedicated guide: it connects with two commands, and with the channels feature new Topic events are pushed into an idle session so Claude reacts without polling. Channels needs its own setup, so the steps live on a separate page: Connect Claude Code to AgenTrux.

Authentication flow (discovery)

The MCP connection URL is protected by OAuth 2.1 and returns 401 Unauthorized to any request without a token. The MCP client auto-discovers everything it needs from that 401, following RFC 9728 (Protected Resource Metadata) and RFC 8414 (Authorization Server Metadata).

1. POST /mcp/c/<connection-id> (no token)
   ◄─ 401 Unauthorized
      WWW-Authenticate: Bearer realm="agentrux-mcp", resource_metadata="..."

2. GET /.well-known/oauth-protected-resource/mcp/c/<connection-id>   ← RFC 9728 (per-connection)
   ◄─ { "resource": "https://api.agentrux.com/mcp/c/<connection-id>",
        "authorization_servers": ["<issuer>"],
        "scopes_supported": ["topic.read", "topic.write"],
        "bearer_methods_supported": ["header"],
        "resource_documentation": "https://api.agentrux.com/.well-known/agent-card.json" }

3. GET /.well-known/oauth-authorization-server          ← RFC 8414
   ◄─ { "issuer", "authorization_endpoint", "token_endpoint",
        "device_authorization_endpoint", "registration_endpoint",
        "jwks_uri", "code_challenge_methods_supported": ["S256"], ... }

4. POST /oauth/register                                 ← Dynamic Client Registration (RFC 7591)
   ◄─ { "client_id", ... }   (public client, token_endpoint_auth_method="none")

5. User authentication (authorization code + PKCE, or device flow):
   open browser to /oauth/authorize  →  user clicks Allow  →  POST /oauth/token
   (or device flow: POST /oauth/device/authorize  →  approve in browser  →  POST /oauth/token)
   ◄─ access_token (Bearer JWT)

6. POST /mcp/c/<connection-id> (Authorization: Bearer <access_token>)
   ◄─ 200 OK

Key points:

Protocol version negotiation

On initialize, the server echoes the client's requested protocolVersion when it is one it supports, otherwise it returns its latest supported version, 2025-06-18. That latest version matches the MCP interface version advertised in the A2A Agent Card, so the initialize response and the published card never disagree.

Available tools

After connecting, tools/list enumerates the tools below; invoke them with tools/call.

Tool Purpose Required scope Main args
publish_event Publish an inline JSON event (≤256 KiB) to a Topic topic.write topic_id (required), payload, event_type, metadata, idempotency_key
read_events Read events from a Topic with cursor pagination topic.read topic_id (required), order (asc/desc, default asc), after, before, limit (1–1000, default 50), event_type
get_event Fetch a single event by event_id topic.read topic_id (required), event_id (required)
list_topics List Topics accessible to the connected workspace (none)
list_grants List Grants (Topic permissions) for the connected Script (none)
request_payload_upload Get a presigned S3 PUT URL to upload a large file (>256 KiB) as a Topic payload object. Compute checksum_sha256, PUT the bytes to the returned presigned_put_url with required_headers, then call publish_event with the returned payload_object_id (pob_...). Bytes go straight to S3, so there is no body-size limit. topic.write topic_id (required), size_bytes (required), checksum_sha256 (required), content_type
request_payload_download Get a presigned S3 GET URL to download a committed large payload object by its payload_object_id (pob_...), e.g. one returned by read_events/get_event. GET the returned presigned_get_url to fetch the bytes directly from S3. topic.read topic_id (required), payload_object_id (required)

read_events returns next_cursor (asc), next_before_cursor (desc) and frontier_cursor; use order='desc' for the most recent messages first, and pass frontier_cursor as after on later calls to poll only for new messages. after and before are mutually exclusive.

request_payload_upload returns payload_object_id (pob_...), presigned_put_url, presigned_expires_at, max_size_bytes and required_headers. request_payload_download returns presigned_get_url, presigned_expires_at, size_bytes, content_type and checksum_sha256.

IDs are passed with prefixes: Topic = top_<uuid>, Event = evt_<uuid>, Payload object = pob_<uuid>, idempotency key = idk_<...>.

tools/call example

{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/call",
  "params": {
    "name": "publish_event",
    "arguments": {
      "topic_id": "top_01234567-89ab-cdef-0123-456789abcdef",
      "event_type": "note.created",
      "payload": { "text": "hello from MCP" }
    }
  }
}

Success response (result.content):

{ "event_id": "evt_...", "next_read_cursor": "..." }

Sessions and notifications

Error handling

The MCP transport is JSON-RPC 2.0.

{
  "jsonrpc": "2.0",
  "id": 7,
  "error": {
    "code": -32603,
    "message": "tool execution failed",
    "data": { "http_status": 403, "code": "FORBIDDEN", "detail": "insufficient_scope" }
  }
}

data.code is one of FORBIDDEN / NOT_FOUND / INVALID / CONFLICT / RATE_LIMITED etc., and data.http_status carries the corresponding HTTP status.

{
  "jsonrpc": "2.0",
  "id": 7,
  "error": {
    "code": -32603,
    "message": "monthly egress limit exceeded",
    "data": {
      "http_status": 402,
      "code": "PAYMENT_REQUIRED",
      "metric": "egress_bytes",
      "current_bytes": 10737418240,
      "limit_bytes": 10737418240,
      "next_action": "top_up_or_upgrade"
    }
  }
}

Related links