Documentation

Connecting your agent (MCP)

Connect Claude, Cursor, Claude Code, Hermes, OpenClaw, or Codex to your AgentLeverage organization so your AI agent can use your org's tools directly.

AgentLeverage exposes your organization's tools through a remote MCP server (Model Context Protocol). Connecting is a process: point a client at the endpoint, sign in or paste a token, approve access, then the tools show up in the agent.

There are two ways to authenticate, and which one you use decides who the agent acts as:

  • OAuth 2.1 / DCR. The agent acts as you. Jobs show up in your Jobs history like the ones you start in the app. This is the path for Claude's custom connector and for Cursor's custom MCP server.
  • API token in the client config. The token is a separate principal: its jobs appear in Jobs badged as the token / agent.

Either way, the agent only ever reaches your own organization. Pick the right org at consent — the connector is bound to the organization that was active. Membership is re-checked on every call.

Your exact endpoint and copy-ready configs live on the signed-in Agents page in the sidebar. This page stays in lockstep with that surface.

Your endpoint

Every client points at the same URL. The production endpoint is:

https://www.agentleverage.co/api/mcp

Copying the URL from the Agents page guarantees you get the right one for a non-production environment. Already connected with /api/mcp/mcp? That path still works — it's a permanent alias, not deprecated.

OAuth clients request user:org:read, tools:read, and tools:execute.

The process

  1. Discover. Copy the endpoint. Point the client at this URL.
  2. Sign in or paste a token. OAuth acts as you. A token is a separate principal.
  3. Approve. Grant the scopes. Pick the org that should own the connection.
  4. Tools appear. Reload or restart the client if the tools are not listed yet.

Claude (custom connector)

This is a first-class OAuth path, and it works in Claude on the web, on desktop, and on mobile. No token, no config file.

  1. Open Settings → Connectors in Claude and choose Add custom connector.
  2. Paste the endpoint URL above and confirm.
  3. Claude sends you to AgentLeverage to sign in. Use the account you normally sign in with.
  4. Approve the access Claude asks for. It requests permission to read your organization and to read and run tools.

That's it. Claude discovers the rest on its own, so there is nothing to register ahead of time on your side.

Two things worth knowing:

  • Pick the right organization when you sign in. The connector is bound to the organization that was active when you approved it. To point it at a different org, remove the connector and add it again with that org active.
  • Remove the connector in Claude to disconnect it. Delete it from Settings → Connectors and Claude stops calling us. If you also want the underlying grant revoked on our side, ask support and we'll cut it.
  • Leaving the organization cuts the connector off. We re-check your membership on every call, so an offboarded member's connector stops reaching that org immediately, whether or not anyone removes it in Claude.
  • Your own MCP servers come through too. A connector sees the AgentLeverage tools plus every enabled server you've added under MCP servers, named <server>__<tool>. Approve the tools:read scope to see them and tools:execute to run them.

Cursor

Lead with OAuth so the agent acts as you. A token in ~/.cursor/mcp.json is the fallback when you want a separate principal.

  1. Open Cursor Settings → Tools & MCP and choose New MCP Server.
  2. Paste the endpoint URL. Leave headers empty so Cursor can run OAuth.
  3. Sign in to AgentLeverage and approve. Pick the organization that should own the connector.
  4. Restart Cursor if the tools do not appear right away.

Or drop this URL-only block into ~/.cursor/mcp.json (global) or .cursor/mcp.json (per-project):

{
  "mcpServers": {
    "agentleverage": {
      "url": "https://www.agentleverage.co/api/mcp"
    }
  }
}

Token fallback

Set an AGENTLEVERAGE_TOKEN environment variable to your API token, then restart Cursor. Cursor auto-detects the transport from the URL — no type field is needed.

{
  "mcpServers": {
    "agentleverage": {
      "url": "https://www.agentleverage.co/api/mcp",
      "headers": {
        "Authorization": "Bearer ${env:AGENTLEVERAGE_TOKEN}"
      }
    }
  }
}

Claude Code

Claude Code has no connector UI, so it uses a bearer token. Create a token on the API tokens settings page, add the server to your .mcp.json (project scope) or ~/.claude.json (user scope), then restart Claude Code:

{
  "mcpServers": {
    "agentleverage": {
      "type": "http",
      "url": "https://www.agentleverage.co/api/mcp",
      "headers": {
        "Authorization": "Bearer <YOUR_AGENTLEVERAGE_TOKEN>"
      }
    }
  }
}

The "type": "http" field is required for remote servers.

Hermes

Hermes Agent reads MCP servers from ~/.hermes/config.yaml under mcp_servers. HTTP servers use url plus headers. There is no connector UI — edit the YAML, then /reload-mcp or restart.

mcp_servers:
  agentleverage:
    url: "https://www.agentleverage.co/api/mcp"
    headers:
      Authorization: "Bearer <YOUR_AGENTLEVERAGE_TOKEN>"

OpenClaw

OpenClaw config is JSON5 under mcp.servers in ~/.openclaw/openclaw.json — not a Claude-style mcp.json. Prefer the Control UI, or the CLI. See the OpenClaw MCP docs.

  1. Open Control UI Settings → MCP → Add server. Choose Streamable HTTP and paste the endpoint URL.

  2. Or run:

    openclaw mcp add agentleverage --url https://www.agentleverage.co/api/mcp --transport streamable-http
  3. For OAuth HTTP servers, set auth: "oauth" then openclaw mcp login agentleverage.

  4. Probe with openclaw mcp doctor agentleverage --probe. Restart or reload if a running Gateway does not pick up the new server.

OAuth shape:

{
  "mcp": {
    "servers": {
      "agentleverage": {
        "url": "https://www.agentleverage.co/api/mcp",
        "transport": "streamable-http",
        "auth": "oauth"
      }
    }
  }
}

Token fallback uses headers.Authorization:

{
  "mcp": {
    "servers": {
      "agentleverage": {
        "url": "https://www.agentleverage.co/api/mcp",
        "transport": "streamable-http",
        "headers": {
          "Authorization": "Bearer <YOUR_AGENTLEVERAGE_TOKEN>"
        }
      }
    }
  }
}

Codex

OpenAI Codex reads TOML — ~/.codex/config.toml (user) or .codex/config.toml (project) — not JSON. Do not paste a Claude mcpServers blob here.

Create a token, export it as AGENTLEVERAGE_TOKEN, then run codex mcp add or paste the table:

codex mcp add agentleverage --url https://www.agentleverage.co/api/mcp --bearer-token-env-var AGENTLEVERAGE_TOKEN
[mcp_servers.agentleverage]
url = "https://www.agentleverage.co/api/mcp"
bearer_token_env_var = "AGENTLEVERAGE_TOKEN"

bearer_token_env_var is the environment variable name, not the token itself.

Other OAuth 2.1 clients

Any client that speaks OAuth 2.1 can add the endpoint the same way Claude does: it reads the discovery documents at the endpoint, registers itself, and sends you through the same sign-in and approval screens. ChatGPT's Developer-mode connectors work this way. We test Claude and Cursor; other clients should work, but we don't verify them.

For a client with no connector UI at all, fall back to a bearer token in its config, using the Claude Code, Hermes, OpenClaw, or Codex shape — whichever matches the client's file format.

Claude Desktop with a token instead

If you would rather use a token than a connector in Claude Desktop, the mcp-remote bridge still works. Add this to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/; Windows: %APPDATA%\Claude\), then fully quit and relaunch Claude Desktop:

{
  "mcpServers": {
    "agentleverage": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://www.agentleverage.co/api/mcp",
        "--transport",
        "http-only",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "AUTH_HEADER": "Bearer <YOUR_AGENTLEVERAGE_TOKEN>"
      }
    }
  }
}

In the --header argument, write Authorization:${AUTH_HEADER} with no space after the colon — the Bearer prefix (with its space) belongs in the AUTH_HEADER environment variable. A space in the argument breaks the header.

What your agent can do

Once connected, your agent sees your organization's tools in its tool list. Your agent can check your org's credit balance (get_credit_balance), read transaction history and usage stats (get_credit_history, get_credit_usage_stats), and list, read, or cancel any job in your organization (list_jobs, get_job, cancel_job) — including jobs you or a teammate started in the app, so you can ask it to check on a run you kicked off yourself. It cannot reach another organization's jobs, and jobs run signed-out on the public site stay invisible to it.

It can also browse the organization's uploaded files (list_files) and mint a short-lived download URL (get_file_download_url). That is how it finds a recording that is already in Files and passes the storagePath into Speaker Separation or Audio Redaction, without you pasting the path by hand. It cannot delete jobs, files, or tags.

bg_remover takes either a public https:// image URL (imageUrl) or the storage path of an image already in your organization (imageFileUrl) — one or the other, never both. The URL is the path an agent can drive on its own: we download the image server-side, store it in your organization's files, and the finished job shows the original beside the cutout. Only https:// works, and a URL that resolves to a private, loopback, link-local, or cloud-metadata address is refused before any job is created. For an image already in Files, call list_files with mimeCategory image and pass the returned storagePath. Download the cutout with get_file_download_url (when the job output has a fileId) or get_job_result_asset_url with role cutout.

audio_redaction still needs a file that is already in your organization. It takes the storage path of an audio recording. Call list_files with mimeCategory audio to find it — do not guess a path. This tool cannot upload a local file; upload in the app first, then ask the agent to redact. Download the bleeped copy with get_file_download_url using redactedAudio.fileId from get_job. Redaction is automatic and should be reviewed by a human before the output leaves the organization.

speaker_separation labels speakers in a recording. It does not take raw audio in the tool call. For a file already in Files, pass list_files's storagePath as audioFileUrl. To upload a local file, use the mint-and-PUT flow below. After the job completes, rename speakers with update_speaker_labels (ids like A / B from get_job). The labeled transcript lives on the job output and is ready to copy as text. Isolated stems and srt downloads are built in the browser from the source recording, so those files are not minted by a tool.

meeting_summarizer turns pasted notes or a finished speaker_separation job into minutes: summary, decisions, action items (owner and deadline when those were said), speaker attribution, timestamp references, and open questions. Pass meetingNotes or sourceJobId (the completed speaker-separation job id in this organization). It does not take a recording and does not re-upload audio. It creates a new job; the source job is not changed or deleted. 2 credits per run. tools:execute is required.

quote_check checks quotes, decisions, and action items against a labeled speaker_separation transcript. Pass sourceJobId (a completed meeting_summarizer job in this organization that itself chained from speaker_separation) or a pasted summary plus transcriptJobId (a completed speaker_separation job). Each item comes back verified, paraphrase-supported, unsupported, or misattributed, with the supporting span when one exists. It creates a new job; the minutes and transcript jobs are not changed or deleted. 2 credits per run. tools:execute is required.

invoice_processor extracts vendor, totals, and line items from pasted invoice text (invoiceText) or from a file you uploaded to your organization's invoices bucket.

review_voc_pack clusters competitor reviews into pain themes with cited quotes. Pass a pasted corpus (preferred) and/or reviewUrls. G2, Capterra, Trustpilot, and similar aggregator pages are never fetched — paste those reviews. Optional maxReviews and focus (pricing, support, bugs, other). Poll get_job for themes, featureGaps, positioningHooks, warnings, and a disclaimer. Themes are synthesized; verify quotes before publishing. 2 credits per run.

If your organization proxies additional upstream MCP servers, those tools appear too, namespaced per server.

Admins can review and manage the full tool catalog under Settings → MCP servers.

Tool titles and annotations

Each listed tool carries a human title and MCP behavior hints so clients can show a label and know what a call does:

  • title. The name in the client's tool picker, for example "Speaker separation" for speaker_separation.
  • readOnlyHint. true for org reads: credits, jobs, files, and MCP-server config. false for anything that creates a job, spends credits, or writes.
  • destructiveHint. true only for delete_mcp_server, which removes your own upstream-server config. Agents cannot delete jobs, files, or tags over MCP.
  • idempotentHint. true when repeating the same call has no extra effect, such as update_speaker_labels. Job creators are false: each call starts a new job.
  • openWorldHint. true when the tool may fetch the public internet: youtube_transcript, news_analyzer, review_voc_pack (review page URLs we are allowed to fetch), bg_remover (imageUrl), and test_mcp_server_connection. Everything else stays inside your organization.

Uploading a file

Speaker Separation and Invoice Processor cannot take the file bytes in the MCP tool call. The agent mints a short-lived upload URL, PUTs the file straight to storage, then starts the job with the path that came back. The token needs the tools:execute scope for every step that spends credits, including minting the URL.

ToolMintThen callMax sizeAllowed typesURL lifetime
Speaker Separationcreate_audio_upload_urlspeaker_separation with audioFileUrl set to the returned path100 MBMP3, WAV, M4A, FLAC, OGG, WEBM (audio/mpeg, audio/wav, audio/x-wav, audio/mp4, audio/x-m4a, audio/ogg, audio/webm, audio/flac, audio/x-flac)5 minutes
Invoice Processorcreate_invoice_upload_urlinvoice_processor with the returned path, bucket, and the same mimeType10 MBPDF, JPG, PNG, TIFF, WebP (application/pdf, image/jpeg, image/png, image/tiff, image/webp)5 minutes

The PUT Content-Type must be the same MIME type you sent when minting. After the URL expires, PUT fails and you mint again. A path that belongs to another organization is refused. For invoices, the wrong bucket or a path you never uploaded is also refused before a job is created and before credits move.

You can paste invoice text instead of uploading a file. Skip the mint and PUT, and call invoice_processor with invoiceText only.

To run Speaker Separation on a recording that is already in Files, skip the mint and PUT. Call list_files with mimeCategory audio (and optional search), then pass the matching storagePath as audioFileUrl.

The examples below talk to the MCP endpoint as JSON-RPC. Set AGENTLEVERAGE_TOKEN to your agl_ token (or replace <YOUR_AGENTLEVERAGE_TOKEN>). The Accept header must list both application/json and text/event-stream. Responses are SSE-framed: read the data: lines.

Speaker Separation

export AGENTLEVERAGE_TOKEN="<YOUR_AGENTLEVERAGE_TOKEN>"
export MCP_URL="https://www.agentleverage.co/api/mcp"

# Already in Files? List audio, then pass storagePath as audioFileUrl.
curl -sS "$MCP_URL" \
  -H "Authorization: Bearer $AGENTLEVERAGE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_files","arguments":{"mimeCategory":"audio","search":"standup"}}}'

Or upload a local file:

# 1. Mint
curl -sS "$MCP_URL" \
  -H "Authorization: Bearer $AGENTLEVERAGE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"create_audio_upload_url","arguments":{"filename":"meeting.wav","mimeType":"audio/wav","size":123456}}}'

The mint result includes signedUploadUrl, path, bucket, expiresInSeconds (300), maxBytes, and allowedMimeTypes. Copy signedUploadUrl and path into the next two commands:

# 2. PUT the raw file (same Content-Type you minted with)
curl -sS -X PUT "$SIGNED_UPLOAD_URL" \
  -H "Content-Type: audio/wav" \
  --data-binary @meeting.wav

# 3. Start the job
curl -sS "$MCP_URL" \
  -H "Authorization: Bearer $AGENTLEVERAGE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"speaker_separation","arguments":{"audioFileUrl":"organizations/org_yourorg/files/123-meeting.wav","audioMetadata":{"filename":"meeting.wav","mimeType":"audio/wav","size":123456}}}}'

The job call returns a handle immediately (PENDING). Poll get_job with that jobId until the status is COMPLETED, then read the labeled transcript and segments from the job output. To rename Speaker A / Speaker B, call update_speaker_labels with the same jobId and speakers: [{ "id": "A", "label": "Alex" }, …].

curl -sS "$MCP_URL" \
  -H "Authorization: Bearer $AGENTLEVERAGE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_job","arguments":{"jobId":"job_replace_with_id"}}}'

Meeting minutes from that job

No re-upload. Pass the completed Speaker Separation jobId as sourceJobId. The call returns a new job handle; poll get_job the same way. The source job is left as it is.

curl -sS "$MCP_URL" \
  -H "Authorization: Bearer $AGENTLEVERAGE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"meeting_summarizer","arguments":{"sourceJobId":"job_replace_with_id"}}}'

Or paste notes instead:

curl -sS "$MCP_URL" \
  -H "Authorization: Bearer $AGENTLEVERAGE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"meeting_summarizer","arguments":{"meetingNotes":"Alex: Ship Friday.\nSam: I will write the runbook by Wednesday."}}}'

Quote check from those minutes

No re-upload. Pass the completed Meeting Summarizer jobId as sourceJobId. The call returns a new job handle; poll get_job the same way. The minutes job and the Speaker Separation job are left as they are.

curl -sS "$MCP_URL" \
  -H "Authorization: Bearer $AGENTLEVERAGE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"quote_check","arguments":{"sourceJobId":"job_replace_with_minutes_id"}}}'

Or paste a summary and the Speaker Separation job id:

curl -sS "$MCP_URL" \
  -H "Authorization: Bearer $AGENTLEVERAGE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"quote_check","arguments":{"summary":"Decision: Ship Friday.\nAction: Sam writes the runbook.","transcriptJobId":"job_replace_with_id"}}}'

Invoice Processor

Text only, no upload:

curl -sS "$MCP_URL" \
  -H "Authorization: Bearer $AGENTLEVERAGE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"invoice_processor","arguments":{"invoiceText":"INVOICE\nVendor: Acme Supplies\nInvoice Number: INV-1001\nTotal: 42.00"}}}'

Or upload a PDF / image, then pass the mint result through:

# 1. Mint
curl -sS "$MCP_URL" \
  -H "Authorization: Bearer $AGENTLEVERAGE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"create_invoice_upload_url","arguments":{"filename":"invoice.pdf","mimeType":"application/pdf","size":20480}}}'

# 2. PUT the raw file
curl -sS -X PUT "$SIGNED_UPLOAD_URL" \
  -H "Content-Type: application/pdf" \
  --data-binary @invoice.pdf

# 3. Start the job with the returned path, bucket, and the same mimeType
curl -sS "$MCP_URL" \
  -H "Authorization: Bearer $AGENTLEVERAGE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"invoice_processor","arguments":{"filePath":"organizations/org_yourorg/invoices/123-invoice.pdf","bucket":"invoices","mimeType":"application/pdf"}}}'

Poll get_job the same way as Speaker Separation. Invoice Processor charges 3 credits per run; Speaker Separation charges 2 credits per minute, rounded up. Meeting Summarizer charges 2 credits per run. Quote Check charges 2 credits per run.

Troubleshooting

SymptomFix
Client can't reach the serverConfirm the URL ends in /api/mcp and you copied it from Agents. If you're still on the old /api/mcp/mcp URL, it should still work — that alias isn't going away.
Connector sign-in ends without connectingMake sure you approved every permission the client asked for, including organization access. Declining one leaves the connector unable to run tools.
Connector works but every tool is refusedThe connection has no organization. Remove the connector, sign in with the right organization active, and approve organization access.
401 Unauthorized with a tokenCheck the Authorization header is Bearer <token> and the token is valid.
Claude Desktop does nothingMake sure you edited the right claude_desktop_config.json and fully quit and relaunched the app.
Hermes tools don't appearEdit ~/.hermes/config.yaml, then /reload-mcp or restart.
OpenClaw saves the server but exposes no toolsRun openclaw mcp doctor agentleverage --probe. Config belongs under mcp.servers.
Codex rejects the fileCodex is TOML ([mcp_servers.agentleverage]), not JSON. bearer_token_env_var is the env-var name.
Tools don't appearRestart the client after editing its config; some clients only read MCP config on startup.
Non-prod / preview URLA localhost or preview URL isn't reachable by an external client — use your production app to copy a stable endpoint.
Upload URL expired or PUT 403Minted URLs last 5 minutes. Mint again, PUT immediately, then start the job. The PUT Content-Type must match the minted mimeType.
File upload tool refusedThe token needs tools:execute. A tools:read-only token can list jobs but cannot mint an upload URL or start a job.
Job create rejected after uploadUse the path (and for invoices, bucket + mimeType) from the mint you just did. A path from another organization, the wrong bucket, or a path you never PUT is refused and does not create a job or charge credits.
Connecting your agent (MCP) | AgentLeverage