Merge CLI

Search, discover, and execute Agent Handler tools from the command line.

The Merge CLI is a lightweight command-line tool for interacting with Agent Handler. Built specifically for AI coding agents - Claude Code, Cursor, Codex - that need progressive tool discovery without overwhelming the context window. Search returns compact schemas; execute runs the tool; the agent doesn’t have to load every tool in the catalog up front.

It’s also useful for humans. Quick exploration, scripted automation, sanity-checking a Tool Pack from a terminal.

Install

pipx is the recommended installer. It keeps the CLI isolated from your other Python packages.

$pipx install merge-api
$merge --version

pip install merge-api works too, but pipx avoids dependency conflicts when you upgrade.

Pick an auth mode

This section is about authenticating the CLI to Agent Handler. Connecting the third-party accounts your tools act on (Notion, Salesforce, and every other Connector) is a separate step that happens per account through a magic link. See Authenticate a Connector.

Two ways to authenticate. Pick one based on context.

OAuth (merge login)API key (merge configure)
Best forInteractive use on your own machine - local agents, explorationAutomation - CI, scripts, headless agents
SetupOne browser-based loginPaste API key + Tool Pack ID + Registered User ID
Where credentials live~/.merge/config.json (OAuth tokens)~/.merge/config.json (API key)
Token refreshAutomaticN/A - keys don’t expire
Tied toYour dashboard userA specific Registered User

OAuth (merge login). Opens a browser, completes OAuth, stores a token. Use this when you’re a developer building locally and want the CLI to act as you.

$merge login

API key (merge configure). Interactive prompt that captures your API key, Tool Pack ID, and Registered User ID. Use this when the CLI needs to act as a specific Registered User - common in CI or when scripting against test data.

$merge configure

If both modes are configured, OAuth takes precedence. To force API-key mode, unset the oauth section of ~/.merge/config.json or set the env vars (next section) explicitly.

Configuration precedence

Credentials resolve in this order, highest priority first:

  1. CLI flags - --api-key, --tool-pack-id, --registered-user-id, --base-url.
  2. Environment variables - MERGE_AH_API_KEY, MERGE_AH_TOOL_PACK_ID, MERGE_AH_REGISTERED_USER_ID, MERGE_AH_BASE_URL.
  3. Config file - ~/.merge/config.json.

Env vars are the right path for CI. The config file is the right path for local development.

~/.merge/config.json contains your API key in plain text. Don’t commit it; if it’s on a shared machine, use env vars and chmod 600 the file at minimum.

Set up your AI agent

merge setup writes the right CLI workflow instructions into your agent’s config file.

$merge setup claude-code

Appends a ## Merge CLI section to CLAUDE.md (creates the file if absent) and adds Bash(merge *) permission to .claude/settings.json. Idempotent - safe to run multiple times.

After setup, your agent will use merge search-tools and merge execute-tool for any third-party action automatically.

Commands

CommandWhat it does
merge search-tools <intent>Semantic search for tools by natural language. Returns compact schemas.
merge execute-tool <tool> <params>Execute a tool with JSON parameters.
merge list-toolsList all available tools.
merge get-tool-schema <tool>Get the full input schema for a specific tool.
merge configureInteractive credential setup (API-key mode).
merge login / merge logoutOAuth-mode auth.
merge setup <target>Generate AI agent config (claude-code, cursor, agents-md).
merge updateSelf-update to the latest version.
$merge search-tools "send a Slack message"
1{
2 "tools": [
3 {
4 "name": "slack__post_message",
5 "description": "Post a message to a Slack channel",
6 "input_schema": { "...": "..." }
7 }
8 ],
9 "total_results": 1,
10 "hint": "To execute: merge execute-tool <tool_name> '<json_params>'"
11}

Useful flags:

  • --Connector slack - narrow to one Connector. Repeatable.
  • --max-results 5 - return up to N results (default 2, max 50).
  • --schema compact|full|none - schema detail. Default is compact (descriptions stripped) to save context. Use full when you need every field’s description; none when you only need names.

Execute

$merge execute-tool slack__post_message '{"input": {"channel": "#general", "text": "Hello!"}}'
1{
2 "result": { "ok": true, "ts": "1714838531.001" },
3 "status": "success",
4 "hint": "Tool executed successfully."
5}

Parameters always go in input. Fields the tool’s schema marks optional can be omitted.

List and inspect

$merge list-tools # All tools, default compact
$merge list-tools --Connector slack # Filter to one Connector
$merge list-tools --full # Include full input schemas
$merge get-tool-schema slack__post_message

merge list-tools is useful for exploration; for everyday agent use, search-tools is faster and produces less context to wade through.

Authenticate a Connector

merge login authenticates you to Agent Handler. It does not connect the third-party accounts your tools run against. Each Connector is authenticated separately, the first time you use it, through a magic link the CLI hands back to you.

This is a working CLI path, not a dashboard-only one. An agent that concludes “the CLI can’t connect an account, only the dashboard can” is wrong, and the steps below are how it connects one without leaving the terminal.

The signal that a Connector needs authentication

A tool call against an unconnected Connector comes back unauthenticated. You’ll see one of two shapes. A validate_credential call returns success: false:

$merge execute-tool notion__validate_credential '{"input": {}}'
1{
2 "result": {
3 "success": false,
4 "message": "Notion authentication failed. Check your credentials and try again."
5 },
6 "status": "success"
7}

A normal tool call returns an error with error_type: reauth_required. Either way the fix is the same: mint a magic link.

Connect the account

Every Connector that requires authentication exposes an authenticate_<connector> tool, for example authenticate_notion. It takes no parameters, so call it with a bare {} (no input envelope) and it returns a magic link:

$merge execute-tool authenticate_notion '{}'
1{
2 "result": {
3 "message": "The user must authenticate with Notion. Share this link with the user to connect their account: https://ah-api.merge.dev/magic-link/•••••/. Once authenticated, you must refetch tools or restart your MCP connection.",
4 "magic_link_url": "https://ah-api.merge.dev/magic-link/•••••/",
5 "link_token": "ltk_•••••"
6 },
7 "status": "success"
8}

Open magic_link_url in a browser, complete OAuth (or paste an API key) at the third party, and the credential is stored against your Registered User. If you’re an agent working on someone’s behalf, hand the URL to the user verbatim. The message field is written for exactly that.

Then retry the original tool. There is no confirmation call to make and nothing to poll: once the credential exists, the authenticate_<connector> tool drops out of the catalog and the real tools work. If your client caches the tool list, refetch tools or restart the MCP connection so the new tools show up.

Finding the authenticate tool

merge search-tools "connect notion" will not surface authenticate_notion. Semantic search ranks the query against the Connector’s data tools, not the auth verb, so the auth tool stays hidden behind an intent search. This is the trap most agents fall into. Two reliable ways to reach it:

  • Call it by name. The pattern is always authenticate_<slug>, where <slug> is the lowercase Connector slug: authenticate_notion, authenticate_google-drive, authenticate_microsoft-teams. The alias <slug>__authenticate works too.
  • List the Connector’s tools. merge list-tools --connector notion shows authenticate_notion at the top, along with the tools it unlocks.

The authenticate_<connector> tool only appears while the Connector is unauthenticated for your Registered User. Once the account is connected it disappears, and you won’t see it again unless the credential is later revoked.

For the full magic link flow, including callback URLs and server-to-server code exchange, see Magic Link.

Output format

Every command returns JSON to stdout. Warnings and progress messages go to stderr - agents that pipe stdout into JSON parsers won’t choke.

Success:

1{
2 "result": { "...": "..." },
3 "status": "success",
4 "hint": "Tool executed successfully."
5}

Error:

1{
2 "result": null,
3 "status": "error",
4 "error_type": "api_error",
5 "message": "What went wrong",
6 "hint": "Suggested next step"
7}

Errors exit with code 1. Wrap CLI invocations in your scripts accordingly.

Common errors

Error typeCauseFix
config_errorNo credentials configuredmerge login or merge configure, or set MERGE_AH_* env vars
api_error (401)Invalid API key, or test key with production resourceCheck the key matches the resource’s environment
not_foundTool name doesn’t existmerge search-tools to find the right one
reauth_requiredConnector token expired or revoked, or the account was never connectedCall authenticate_<connector> to mint a magic link. See Authenticate a Connector. The dashboard Connectors page also works.
billing_limit_reachedMonthly tool-call quota hitUpgrade at Settings → Billing
network_errorConnection failedCheck internet; verify --base-url if non-default

For a fuller troubleshooting catalog, see Troubleshooting.

Next

For the full workforce rollout the CLI belongs to (SSO, SCIM, and Group-based tool access), see Agent Handler for employees.