MCP Server Guide
Overview
Section titled “Overview”The @humanauth/mcp package is an MCP (Model Context Protocol) server that exposes three HARP tools to any MCP-compatible agent. No code changes required — just add 3 lines to your MCP client config.
- human_authorize — Request binary authorization (approve/deny). Blocks until the human responds or the request expires.
- human_collect — Request structured data input via a bounded form. Blocks until the human submits or the request expires.
- human_inform — Send a fire-and-forget notification. Returns immediately without waiting for a response.
Prerequisites
Section titled “Prerequisites”- A HARP pairing already created (see Getting Started)
- An MCP-compatible agent (Claude Code, Cursor, Windsurf, or any MCP client)
Claude Code
Section titled “Claude Code”Edit ~/.claude/settings.json:
{ "mcpServers": { "harp": { "command": "npx", "args": ["@humanauth/mcp"] } }}Cursor
Section titled “Cursor”Edit .cursor/mcp.json in your project root:
{ "mcpServers": { "harp": { "command": "npx", "args": ["@humanauth/mcp"] } }}Custom MCP Client
Section titled “Custom MCP Client”Any MCP client that supports the stdio transport can use the HARP server:
npx @humanauth/mcpThe server communicates via stdin/stdout using the MCP JSON-RPC protocol.
human_authorize
Section titled “human_authorize”Request binary authorization from a human. The call blocks until the human approves, denies, or the TTL expires.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
pair_id | string | Yes | — | Pairing ID for the human to ask |
action | string | Yes | — | Action name (e.g., deploy_production) |
description | string | Yes | — | Human-readable description of the action |
severity | "low" | "medium" | "high" | "critical" | No | "medium" | How dangerous is this action |
parameters | object | No | — | Action parameters for context |
reasoning | string | No | — | Your reasoning for requesting this |
ttl | number | No | 300 | Timeout in seconds (1–86400) |
Example Tool Call
Section titled “Example Tool Call”{ "name": "human_authorize", "arguments": { "pair_id": "pair_a1b2c3d4e5f6", "action": "deploy_production", "description": "Deploy v2.4.1 to the production environment", "severity": "high", "parameters": { "version": "v2.4.1", "environment": "production", "region": "us-east-1" }, "reasoning": "All staging checks passed. Release window is now open.", "ttl": 300 }}Example Responses
Section titled “Example Responses”On authorization:
{ "content": [ { "type": "text", "text": "APPROVED: Human approved the action 'deploy_production'." } ]}On denial:
{ "content": [ { "type": "text", "text": "DENIED: Human denied the action 'deploy_production'. Reason: Wait for the on-call engineer to be online before deploying." } ], "isError": true}human_collect
Section titled “human_collect”Request structured data input from a human. The call blocks until the human submits the form or the TTL expires. All fields use bounded inputs — no free text — to keep responses predictable and safe.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
pair_id | string | Yes | — | Pairing ID |
action | string | Yes | — | Action name |
description | string | Yes | — | What data you need and why |
schema | object | Yes | — | Form schema with a fields array (max 20 fields) |
severity | "low" | "medium" | "high" | "critical" | No | "medium" | How sensitive is this data |
reasoning | string | No | — | Why you need this data |
ttl | number | No | 600 | Timeout in seconds |
Field Types
Section titled “Field Types”Each entry in schema.fields must have a type from the following list:
| Type | Description | options Required |
|---|---|---|
select | Single-selection dropdown | Yes |
multiselect | Multiple-selection list | Yes |
checkbox | Boolean toggle | No |
number | Numeric input with optional min/max | No |
datetime | Date/time picker | No |
Example Tool Call
Section titled “Example Tool Call”{ "name": "human_collect", "arguments": { "pair_id": "pair_a1b2c3d4e5f6", "action": "configure_deployment", "description": "Please confirm the deployment configuration before I proceed.", "severity": "high", "reasoning": "I need the target environment and replica count to proceed with the rollout.", "ttl": 600, "schema": { "fields": [ { "id": "environment", "label": "Target Environment", "type": "select", "options": ["staging", "production", "canary"], "required": true }, { "id": "replica_count", "label": "Replica Count", "type": "number", "min": 1, "max": 20, "required": true }, { "id": "notify_team", "label": "Notify team on Slack after deploy", "type": "checkbox", "required": false } ] } }}Example Response
Section titled “Example Response”{ "content": [ { "type": "text", "text": "SUBMITTED: Human provided data for 'configure_deployment'." } ], "form_data": { "environment": "production", "replica_count": 3, "notify_team": true }}human_inform
Section titled “human_inform”Send a notification to a human. Returns immediately without waiting for a response (fire-and-forget).
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
pair_id | string | Yes | — | Pairing ID |
action | string | Yes | — | Action name or context identifier |
description | string | Yes | — | The notification message |
severity | "low" | "medium" | "high" | "critical" | No | "low" | Notification urgency |
category | "escalation" | "result" | "status" | "error" | "general" | No | "general" | Notification type |
Category Descriptions
Section titled “Category Descriptions”| Category | When to Use |
|---|---|
escalation | Something requires human attention but not an authorization gate |
result | Reporting the outcome of a completed action |
status | Progress update mid-task |
error | Reporting an error or failure |
general | Everything else |
Example Tool Call
Section titled “Example Tool Call”{ "name": "human_inform", "arguments": { "pair_id": "pair_a1b2c3d4e5f6", "action": "deploy_complete", "description": "Deployment of v2.4.1 to production completed successfully. All health checks passed.", "severity": "low", "category": "result" }}Example Response
Section titled “Example Response”{ "content": [ { "type": "text", "text": "NOTIFIED: Notification 'deploy_complete' sent successfully." } ], "ok": true}Severity Levels
Section titled “Severity Levels”| Level | Description | When to Use |
|---|---|---|
low | Routine, low-risk | Read-only operations, status checks, informational notifications |
medium | Standard operations | Most actions; the default when severity is not specified |
high | Potentially dangerous | Production changes, data modifications, configuration updates |
critical | Irreversible, high-impact | Deletions, financial transactions, security-sensitive actions |
Environment Variables
Section titled “Environment Variables”| Variable | Default | Description |
|---|---|---|
HARP_PAIRINGS_DIR | ~/.harp/pairings | Directory containing pairing JSON files |
How It Works
Section titled “How It Works”- Agent calls one of the three HARP tools with the required parameters
- The MCP server loads the pairing file for the given
pair_id - Encrypts the request context with XChaCha20-Poly1305
- Sends the encrypted envelope to the relay
- For
human_authorizeandhuman_collect: blocks until the human responds or the TTL expires, then returns the result to the agent - For
human_inform: delivers the notification and returns immediately without waiting
The MCP server is stateless — it reads pairings from disk on each call. No background processes, no persistent connections.
Multiple Pairings
Section titled “Multiple Pairings”If you have multiple pairings (e.g., personal and work), the agent selects which pair_id to use. You can guide this by naming pairings descriptively:
humanauth pair --name "personal-deploy-approver"humanauth pair --name "work-infra-approver"The MCP server discovers all pairings in ~/.harp/pairings/ automatically.
Troubleshooting
Section titled “Troubleshooting””Pairing not found” error
Section titled “”Pairing not found” error”Verify the pairing exists:
humanauth listEnsure the pair_id in the tool call matches a saved pairing file.
”Request expired” error
Section titled “”Request expired” error”The human did not respond within the TTL. This only applies to human_authorize and human_collect. Consider:
- Increasing the
ttlparameter - Verifying push notifications are enabled on the HARP app
- Checking that the phone has network connectivity
Server not recognized by MCP client
Section titled “Server not recognized by MCP client”Verify the MCP config path is correct for your client. Run the server manually to test:
npx @humanauth/mcpIf it starts without errors, the issue is in the client configuration.
Tool name not found
Section titled “Tool name not found”The tool names in HARP v1 are human_authorize, human_collect, and human_inform. If your agent config or prompts reference the old authorize tool name, update them to use the new names.