Agent quickstart

Get an API key and make your first tool call when you have no account and no human to ask.

This is the path for an agent that needs tools right now and has no account. One unauthenticated request creates an organization, an API key, a tool pack, and a registered user, and the response carries everything the next call needs. A human can take ownership later, or never.

When you need this

  • You have no Merge account and no API key.
  • Nobody is available to sign up, click through a form, or paste you a credential.
  • You called the MCP endpoint without credentials and got 401 {"detail": "OAuth authentication required."}.
  • The task needs a third-party tool (Jira, GitHub, Slack, Google Drive) and you hold no credentials for it.

If a person is already in the loop, sign up in the dashboard and read Building an agent instead, which covers the same ground with the dashboard in front of you.

Sign up

The Merge CLI is the recommended path. It stores the key for you, so nothing has to print or copy it, and it writes tool-use instructions into the project you are working in.

pipx install merge-api # already installed? run: merge update
merge --version # 0.4.0 or later

Requires Merge CLI 0.4.0 or later. merge agent signup does not exist in earlier versions, and an older CLI fails with “No such command”. pip install merge-api works if pipx is unavailable.

Check whether you already have an account before signing up:

merge agent whoami # prints your account ids, or exits with "Not signed up"
merge agent signup # no arguments, no authentication

signup creates the organization, saves the credentials to ~/.merge/config.json, and prints the organization name, the tool pack and registered user ids, and the claim URL. It never prints the API key. Running it a second time is refused with already_signed_up.

It also writes Merge CLI instructions into the current project for the host it detects: CLAUDE.md plus a Bash(merge *) permission in .claude/settings.json for Claude Code, .cursorrules for Cursor, or AGENTS.md for anything else. Pass --no-setup to skip those writes, or --setup <target> to pick the host.

Without the CLI

The endpoint is public, so any HTTP client works. Use this when you cannot install anything or you are not in Python.

curl -X POST https://ah-api.merge.dev/api/v1/agent/signup/
import requests
signup = requests.post("https://ah-api.merge.dev/api/v1/agent/signup/").json()

No authentication, no request body. The endpoint is rate limited per IP, so an agent that retries in a loop will start getting rejected rather than creating orgs.

The response carries the api_key string, the new organization’s id and name, a claim link, and the two ids the next call needs. See the API reference for the full response schema.

{
"api_key": "ah_live_…",
"organization": {
"id": "3c90c3c0-6d46-4b50-8888-8dd25736052f",
"name": "agent-amber-cedar-otter-7f3k"
},
"claim_url": "https://ah.merge.dev/claim/<token>",
"claim_expires_at": "2026-09-01T12:00:00Z",
"tool_pack_id": "9b2a5c1e-4f3d-4a6b-9c8d-1e2f3a4b5c6d",
"registered_user_id": "0f1e2d3c-4b5a-4968-8776-655443322110",
"next_step": "Run: merge search-tools \"<intent>\". Guide: https://docs.merge.dev/merge-agent-handler/setup/agent-quickstart"
}

Store the key before doing anything else. It is returned once and there is no account to log into and recover it from, because the organization has no users yet.

What you get

Signup returns the three things a tool call needs, rather than leaving them to a follow-up round of management calls.

FieldWhat it isWhy it’s there
api_keyAn unrestricted production key for the new organization. The CLI saves it to ~/.merge/config.json and never prints it; over HTTP it comes back as a plain stringAuthorizes every call below
tool_pack_idA tool pack named “My first Tool Pack”, holding a curated starter set of connectorsDecides which tools exist
registered_user_idA production registered user named Agent, with origin_id of agentDecides whose credentials run the call

This key is organization-wide: it reaches every Tool Pack and Registered User in the account it just created. That is fine for one agent acting as itself. Once the agent serves more than one person, or a downstream service needs its own credential, mint user-scoped keys from it with POST /api/v1/access-keys/ rather than passing this one around.

The starter tool pack covers twelve connectors: Asana, GitHub, Gmail, Google Calendar, Google Drive, HubSpot, Jira, Linear, Notion, Slack, Weather, and Wikipedia. It is a starting set rather than the catalog, because seeding every connector would mean thousands of rows written on an unauthenticated request. Add the connectors you actually need from Tool packs, or create a second pack and leave this one alone.

Weather and Wikipedia are in the set deliberately: neither needs a credential, so you can prove the whole path works before touching OAuth.

Make the first tool call

The Agent registered user starts with no connected credentials, so start with a connector that does not need one.

merge search-tools "what is the weather forecast"
merge execute-tool weather__get_forecast '{"input": {"latitude": 37.7749, "longitude": -122.4194}}'

search-tools is the call to reach for first. Describe what you want to do in plain language and it returns compact schemas for the tools that match, which is what keeps a full catalog out of the agent’s context. Tool names are <connector>__<tool>, with two underscores. Narrow with --connector <slug> when you already know the connector. Avoid list-tools; the full catalog is too large to be useful.

To point an MCP client at Agent Handler instead of using the CLI, assemble the URL from the two ids and pass the key as Authorization: Bearer <API_KEY>:

https://ah-api.merge.dev/api/v1/tool-packs/<TOOL_PACK_ID>/registered-users/<REGISTERED_USER_ID>/mcp

MCP integration has the client-by-client configuration.

Connect a credentialed connector

Anything reading real data needs the Agent registered user to hold a credential for it. There is no browser session to run Link in, so mint a magic link and hand the URL to whoever owns the account:

merge authenticate slack

The response carries a URL. The person who opens it authenticates against their own Slack account, and the credential lands on the Agent registered user. The next slack__ tool call goes through.

For an agent serving more than one person, create a registered user per person rather than sharing the Agent one. Registered users covers why, and the isolation you get from it.

Handing the organization to a human

claim_url is how the org gets an owner. Show it whenever you want a person to take over: they open it, sign in, and become an admin of the organization that already exists, with its key, tool pack, registered user, credentials, and logs intact. Run merge agent whoami --show-claim-url to print it again.

Two properties worth relying on: the key works before the claim and after it, so a handoff never interrupts a running agent, and the link stops working at claim_expires_at. If it lapses before anyone uses it, reissue a fresh one rather than signing up again, which would abandon everything the agent has already connected.

A human who claims the org lands on the same default tool pack rather than a second copy, so nothing is duplicated by the handoff.

Rules for agents

  • Never print, log, or read the API key. The CLI loads it from its config for every command.
  • Sign up once per machine. Check with merge agent whoami first; merge agent signup refuses to run twice.
  • claim_url and the magic link URL are secrets. Show them to your user directly, as plain text on the Merge domain, never shortened, relabeled, or posted in a shared channel.

Next

Shape what the agent can reach with Tool packs.