MCP Authentication
API keys, agent scoping, and sandbox mode for MCP
🔐 MCP Authentication
MCP agents authenticate using Bearer tokens — long-lived API keys created per agent. Each key is scoped to a specific entity (payroll company or employer) and optionally locked to sandbox mode.
API Key Format
mcp_<64 hexadecimal characters>
Example:
mcp_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
Keys are 256-bit random values, SHA-256 hashed before storage. The raw key is shown once at creation and cannot be retrieved again.
Getting Your API Key
MCP API keys are created by your Audit1 account manager or via the admin REST API. Contact [email protected] to request credentials for your agent.
You'll need to provide:
| Field | Description |
|---|---|
| Agent name | A human-readable label (e.g., "ADP Payroll Agent") |
| Entity type | payroll_company (multi-employer) or employer (single) |
| Entity ID | The Audit1 ObjectId for your payroll company or employer |
| Sandbox | true for testing (forces dry-run on all submissions) |
Save your API key immediately — it's only shown once. If you lose it, request a new key and revoke the old one.
Request Format
All MCP calls go to a single endpoint using JSON-RPC 2.0:
curl -X POST https://payroll-mcp-server-902057957000.us-central1.run.app/mcp \
-H "Authorization: Bearer mcp_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "initialize",
"id": 1
}'
Single endpoint — Unlike the REST API which has many routes, MCP uses one endpoint (POST /mcp) for all operations. Themethodfield determines the action.
Agent Scoping
Your API key determines what data you can access:
| Agent Type | Entity Type | Scope |
|---|---|---|
| Provider | payroll_company | All employers where payroll_company_ids includes your company |
| Employer | employer | Only this specific employer |
Scope is resolved fresh on every request. If an employer is unlinked from your payroll company, your agent loses access immediately — no stale permissions.
Provider Agent Example
A payroll company with 100 employer clients:
Agent → list_employer_policies(employer_id: "abc") → ✅ (employer linked)
Agent → list_employer_policies(employer_id: "xyz") → ✅ (employer linked)
Agent → list_employer_policies(employer_id: "999") → ❌ SCOPE_ERROR (not linked)
Employer Agent Example
A single-employer agent:
Agent → list_employer_policies(employer_id: "abc") → ✅ (matches agent scope)
Agent → list_employer_policies(employer_id: "xyz") → ❌ SCOPE_ERROR (wrong employer)
Sandbox Mode
Sandbox agents work identically to production agents — they can discover fields, list policies, and validate data. The only difference: submit_payroll_data automatically forces dry_run: true, so no data enters the real processing pipeline.
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "submit_payroll_data",
"arguments": {
"employer_id": "681abc123def456789012345",
"policy_id": "680def456ghi789012345678",
"rows": [{ "employee_first_name": "Test", "gross_wages": 2500 }],
"dry_run": false
}
},
"id": 5
}
Even thoughdry_run: falsewas set, a sandbox agent's submission will still be dry-run only. The response will indicate"dry_run": true.
Use sandbox mode for:
- 🧪 Development and testing
- 📋 Onboarding new agents
- ✅ Validating data formats before going live
Credential Management
Create an Agent
curl -X POST https://payroll-mcp-server-902057957000.us-central1.run.app/api/v1/agents \
-H "Content-Type: application/json" \
-d '{
"agent_name": "ADP Payroll Agent",
"entity_type": "payroll_company",
"entity_id": "68c4c0535d5a5576362a9499",
"sandbox": false,
"created_by": "[email protected]"
}'Response (201 Created):
{
"credential_id": "682abc123def456789012345",
"agent_name": "ADP Payroll Agent",
"entity_type": "payroll_company",
"entity_id": "68c4c0535d5a5576362a9499",
"sandbox": false,
"api_key": "mcp_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"api_key_prefix": "mcp_a1b2",
"message": "Store this API key securely — it cannot be retrieved again."
}List Agents
curl "https://payroll-mcp-server-902057957000.us-central1.run.app/api/v1/agents?entity_type=payroll_company&entity_id=68c4c0535d5a5576362a9499"Response (200 OK):
{
"agents": [
{
"credential_id": "682abc123def456789012345",
"agent_name": "ADP Payroll Agent",
"entity_type": "payroll_company",
"entity_id": "68c4c0535d5a5576362a9499",
"api_key_prefix": "mcp_a1b2...",
"status": "active",
"sandbox": false,
"created_at": "2026-03-15T10:30:00Z",
"last_used_at": "2026-03-31T14:22:00Z"
}
],
"count": 1
}Revoke an Agent
curl -X POST https://payroll-mcp-server-902057957000.us-central1.run.app/api/v1/agents/682abc123def456789012345/revokeResponse (200 OK):
{
"credential_id": "682abc123def456789012345",
"agent_name": "ADP Payroll Agent",
"status": "revoked"
}Key Management Best Practices
| ✅ Do | ❌ Don't |
|---|---|
| Store keys in environment variables or secret managers | Hardcode keys in source code |
| Use sandbox agents for development | Test with production agents |
| Revoke unused or compromised keys immediately | Share keys across multiple agents |
| Use one key per agent with descriptive names | Reuse keys between environments |
Log the key prefix (mcp_a1b2...) for debugging | Log the full API key |
Error Responses
| Code | Error | Meaning |
|---|---|---|
-32001 | AUTH_ERROR | Missing, invalid, or revoked API key |
-32002 | SCOPE_ERROR | Agent not authorized for this employer |
-32003 | SANDBOX_ONLY | Sandbox agent attempted real submission (auto-forced to dry-run) |
Example error:
{
"jsonrpc": "2.0",
"error": {
"code": -32001,
"message": "Invalid or revoked API key"
},
"id": 1
}📧 Need Help?
Email [email protected] to request new agent credentials or report authentication issues.
Updated 1 day ago
