MCP Tools Reference

All 6 MCP tools with schemas, examples, and error codes

📖 MCP Tools Reference

Complete reference for all MCP tools available on the Audit1 Payroll MCP Server.

Endpoint: POST /mcp Protocol: JSON-RPC 2.0 Version: 2025-03-26


JSON-RPC 2.0 Format

Every MCP request follows the same structure:

{
  "jsonrpc": "2.0",
  "method": "<method_name>",
  "params": { ... },
  "id": 1
}

Every response:

{
  "jsonrpc": "2.0",
  "result": { ... },
  "id": 1
}

Protocol Methods

These are the top-level JSON-RPC methods (not tools):

MethodPurpose
initializeHandshake — returns protocol version and server info
tools/listDiscover all available tools and their input schemas
tools/callExecute a tool (see tool sections below)
pingHealth check

Initialize

curl -X POST https://payroll-mcp-server-902057957000.us-central1.run.app/mcp \
  -H "Authorization: Bearer mcp_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","id":1}'
{
  "jsonrpc": "2.0",
  "result": {
    "protocolVersion": "2025-03-26",
    "capabilities": { "tools": { "listChanged": false } },
    "serverInfo": { "name": "audit1-payroll-mcp", "version": "1.0.0" }
  },
  "id": 1
}

Tools/List

curl -X POST https://payroll-mcp-server-902057957000.us-central1.run.app/mcp \
  -H "Authorization: Bearer mcp_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":2}'

Returns all 6 tools with their names, descriptions, and inputSchema.


Tool Call Format

All tools are invoked via tools/call:

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "<tool_name>",
    "arguments": { ... }
  },
  "id": 3
}

list_employer_policies

Discover active policies for an employer. Use this to find which policies to report payroll against before submitting data.

Input Schema

FieldTypeRequiredDescription
employer_idstringYesThe employer ObjectId
include_expiredbooleanNoInclude expired policies (default: false)

Example

curl -X POST https://payroll-mcp-server-902057957000.us-central1.run.app/mcp \
  -H "Authorization: Bearer mcp_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "name": "list_employer_policies",
      "arguments": {
        "employer_id": "681abc123def456789012345"
      }
    },
    "id": 3
  }'

Response

{
  "jsonrpc": "2.0",
  "result": {
    "content": [{
      "type": "text",
      "text": "{\"employer_id\":\"681abc123def456789012345\",\"policy_count\":2,\"policies\":[{\"policy_id\":\"680def456ghi789012345678\",\"policy_number\":\"WC1025561\",\"carrier_name\":\"CopperPoint\",\"status\":\"active\",\"effective_date\":\"2025-07-01\",\"expiration_date\":\"2026-07-01\",\"fee_count\":3},{\"policy_id\":\"680abc789xyz123456789012\",\"policy_number\":\"WC2038412\",\"carrier_name\":\"CopperPoint\",\"status\":\"active\",\"effective_date\":\"2025-10-01\",\"expiration_date\":\"2026-10-01\",\"fee_count\":5}]}"
    }]
  },
  "id": 3
}
📘

All tool responses are wrapped in content[].text as JSON strings (MCP standard format). Parse the text field to get the structured data.


get_expected_fields

Discover what fields Audit1 expects for a given employer's policy. Returns required and optional fields, valid class codes, valid states, and payroll frequency.

Input Schema

FieldTypeRequiredDescription
employer_idstringYesThe employer ObjectId
policy_idstringNoSpecific policy. If omitted, returns info for all active policies.

Example

curl -X POST https://payroll-mcp-server-902057957000.us-central1.run.app/mcp \
  -H "Authorization: Bearer mcp_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "name": "get_expected_fields",
      "arguments": {
        "employer_id": "681abc123def456789012345",
        "policy_id": "680def456ghi789012345678"
      }
    },
    "id": 4
  }'

Response (parsed text)

{
  "employer_id": "681abc123def456789012345",
  "employer_name": "Smith Industries LLC",
  "policies": [
    {
      "policy_id": "680def456ghi789012345678",
      "policy_number": "WC1025561",
      "carrier": "CopperPoint",
      "status": "active",
      "effective_date": "2025-07-01",
      "expiration_date": "2026-07-01",
      "class_codes": ["8810", "8742"],
      "states": ["CA", "NY"],
      "locations": [
        { "id": "683aaa111bbb222333444555", "state": "CA" },
        { "id": "683bbb222ccc333444555666", "state": "NY" }
      ],
      "payroll_frequency": "BIWEEKLY",
      "fields": {
        "required": [
          { "name": "gross_wages", "type": "number", "description": "Gross wages for the pay period in dollars. Alternative: provide hours + rate." }
        ],
        "optional": [
          { "name": "class_code", "type": "string", "description": "WC class code. Policy has 2 codes.", "valid_values": ["8810", "8742"] },
          { "name": "state", "type": "string", "description": "2-letter state. Policy has 2 states.", "valid_values": ["CA", "NY"] },
          { "name": "employee_first_name", "type": "string", "description": "Employee first name" },
          { "name": "employee_last_name", "type": "string", "description": "Employee last name" },
          { "name": "overtime", "type": "number", "description": "Overtime wages in dollars" },
          { "name": "hours", "type": "number", "description": "Hours worked (alternative to gross_wages)" },
          { "name": "rate", "type": "number", "description": "Hourly rate (used with hours)" },
          { "name": "check_date", "type": "string", "description": "Pay date YYYY-MM-DD" },
          { "name": "pay_period_start", "type": "string", "description": "Period start YYYY-MM-DD" },
          { "name": "pay_period_end", "type": "string", "description": "Period end YYYY-MM-DD" }
        ]
      }
    }
  ]
}
📘

Auto-inference: If a policy has exactly 1 class code or 1 state, those fields become optional — the system auto-assigns the value. If a policy has multiple, you must specify.


validate_payroll_submission

Pre-validate payroll data before submitting. Returns field-level feedback on each row without persisting anything. Always runs in dry-run mode.

Input Schema

FieldTypeRequiredDescription
employer_idstringYesThe employer ObjectId
policy_idstringYesThe policy ObjectId
rowsarrayYesPayroll data rows (see Row Fields below)

Example

curl -X POST https://payroll-mcp-server-902057957000.us-central1.run.app/mcp \
  -H "Authorization: Bearer mcp_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "name": "validate_payroll_submission",
      "arguments": {
        "employer_id": "681abc123def456789012345",
        "policy_id": "680def456ghi789012345678",
        "rows": [
          {
            "employee_first_name": "Jane",
            "employee_last_name": "Smith",
            "class_code": "8810",
            "state": "CA",
            "gross_wages": 2500.00,
            "check_date": "2026-03-15"
          },
          {
            "employee_first_name": "Bob",
            "employee_last_name": "Jones",
            "class_code": "9999",
            "state": "ZZ",
            "gross_wages": 3000.00
          }
        ]
      }
    },
    "id": 5
  }'

Response (parsed text)

{
  "submission_id": "682xyz789abc123456789012",
  "status": "dry_run_complete",
  "dry_run": true,
  "row_count": 2,
  "validation": {
    "valid": false,
    "error_count": 2,
    "warning_count": 0,
    "errors": [
      { "row": 2, "field": "class_code", "message": "Class code '9999' not found in policy fees" },
      { "row": 2, "field": "state", "message": "State 'ZZ' is not a valid US state" }
    ],
    "warnings": []
  }
}

submit_payroll_data

Submit payroll data rows for an employer. Creates a file in Audit1's processing pipeline (Files-creator → Auditor validation → wage calculation → premium calculation). Set dry_run: true to validate without persisting.

Input Schema

FieldTypeRequiredDescription
employer_idstringYesThe employer ObjectId
policy_idstringYesThe policy ObjectId
rowsarrayYesPayroll data rows (see Row Fields below)
dry_runbooleanNoIf true, validate only (default: false)

Example (Real Submission)

curl -X POST https://payroll-mcp-server-902057957000.us-central1.run.app/mcp \
  -H "Authorization: Bearer mcp_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "name": "submit_payroll_data",
      "arguments": {
        "employer_id": "681abc123def456789012345",
        "policy_id": "680def456ghi789012345678",
        "rows": [
          {
            "employee_first_name": "Jane",
            "employee_last_name": "Smith",
            "class_code": "8810",
            "state": "CA",
            "gross_wages": 2500.00,
            "overtime": 375.00,
            "check_date": "2026-03-15",
            "pay_period_start": "2026-03-01",
            "pay_period_end": "2026-03-15"
          }
        ],
        "dry_run": false
      }
    },
    "id": 6
  }'

Response (Real Submission)

{
  "jsonrpc": "2.0",
  "result": {
    "content": [{
      "type": "text",
      "text": "{\"submission_id\":\"682abc123def456789012345\",\"file_id\":\"683def456ghi789012345678\",\"status\":\"submitted_and_validated\",\"row_count\":1,\"message\":\"Payroll data submitted successfully. File created and validation triggered.\"}"
    }]
  },
  "id": 6
}

Response (Dry Run)

{
  "submission_id": "682xyz789abc123456789012",
  "status": "dry_run_complete",
  "dry_run": true,
  "row_count": 1,
  "validation": {
    "valid": true,
    "error_count": 0,
    "warning_count": 0,
    "errors": [],
    "warnings": []
  }
}

Submission Statuses

StatusMeaning
dry_run_completeValidation-only run completed
submitted_and_validatedData submitted and validation triggered successfully
submitted_validation_pendingData submitted, validation still running
submission_failedSubmission failed (check error details)

get_submission_status

Check the processing status of a previously submitted file. Returns Phase 1 (validation), Phase 2 (wage calculation), and Phase 3 (premium calculation) results.

Input Schema

FieldTypeRequiredDescription
submission_idstringNo*The submission ID from submit_payroll_data
file_idstringNo*The file ObjectId

*At least one of submission_id or file_id is required.

Example

curl -X POST https://payroll-mcp-server-902057957000.us-central1.run.app/mcp \
  -H "Authorization: Bearer mcp_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "name": "get_submission_status",
      "arguments": {
        "submission_id": "682abc123def456789012345"
      }
    },
    "id": 7
  }'

Response (parsed text)

{
  "submission_id": "682abc123def456789012345",
  "file_id": "683def456ghi789012345678",
  "file_status": "validated",
  "phase_1": {
    "total_rows": 10,
    "green_rows": 9,
    "red_rows": 1,
    "status": "complete"
  },
  "phase_2": {
    "total_auditable_wages_cents": 2500000,
    "rows_processed": 9,
    "status": "complete"
  },
  "phase_3": {
    "total_premium_cents": 78122,
    "rows_processed": 9,
    "status": "complete"
  },
  "row_breakdown": {
    "green": 9,
    "red": 1
  }
}
📘

Monetary values are in cents. 2500000 = $25,000.00. 78122 = $781.22.

File Statuses

Files progress through: pendinguploadedidentifiednormalizedvalidatedcompleted


get_validation_errors

Get detailed validation errors for a submitted file. Returns RED rows with reasons (invalid class code, missing state, etc.) and suggested corrections.

Input Schema

FieldTypeRequiredDescription
file_idstringNo*The file ObjectId
submission_idstringNo*The MCP submission ID

*At least one of file_id or submission_id is required.

Example

curl -X POST https://payroll-mcp-server-902057957000.us-central1.run.app/mcp \
  -H "Authorization: Bearer mcp_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "name": "get_validation_errors",
      "arguments": {
        "file_id": "683def456ghi789012345678"
      }
    },
    "id": 8
  }'

Response (parsed text)

{
  "file_id": "683def456ghi789012345678",
  "total_rows": 10,
  "green_rows": 9,
  "red_rows": 1,
  "errors": [
    {
      "row_id": "684aaa111bbb222333444555",
      "row_number": 7,
      "employee_name": "Bob Jones",
      "reasons": [
        {
          "field": "class_code",
          "message": "Class code '9999' not found in policy fees",
          "suggestion": "Valid class codes for this policy: 8810, 8742"
        }
      ]
    }
  ],
  "has_more": false
}
📘

Results are capped at 100 rows. If has_more: true, there are additional errors beyond the returned set.


Row Fields

These fields apply to the rows array in submit_payroll_data and validate_payroll_submission:

FieldTypeDescription
employee_first_namestringEmployee first name
employee_last_namestringEmployee last name
class_codestringWC class code (e.g., "8810")
statestring2-letter state abbreviation (e.g., "CA")
gross_wagesnumberGross wages for the period in dollars
overtimenumberOvertime wages in dollars
hoursnumberHours worked (alternative to gross_wages)
ratenumberHourly rate (used with hours)
check_datestringPay date YYYY-MM-DD
pay_period_startstringPeriod start YYYY-MM-DD
pay_period_endstringPeriod end YYYY-MM-DD
ssnstringSocial Security Number (optional)

Wage input options (provide one):

  1. gross_wages — Direct dollar amount (most common)
  2. hours + rate — Computed as hours x rate
  3. Annual salary fields — Divided by payroll frequency

Error Codes

JSON-RPC Standard Errors

CodeNameMeaning
-32700Parse ErrorInvalid JSON in request body
-32600Invalid RequestMalformed JSON-RPC structure
-32601Method Not FoundUnknown RPC method (typo in method field)
-32602Invalid ParamsMissing or invalid tool arguments
-32603Internal ErrorServer error during tool execution

MCP Custom Errors

CodeNameMeaning
-32001Auth ErrorMissing, invalid, or revoked API key
-32002Scope ErrorAgent not authorized for this employer/payroll company
-32003Sandbox OnlySandbox agent attempted non-dry-run (auto-forced to dry-run)

Error Response Format

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32602,
    "message": "Invalid params: employer_id is required",
    "data": { "field": "employer_id" }
  },
  "id": 4
}

Full Workflow Example

Python

import requests
import json

MCP_URL = "https://payroll-mcp-server-902057957000.us-central1.run.app/mcp"
API_KEY = "mcp_your_api_key_here"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

def mcp_call(method, params=None, call_id=1):
    body = {"jsonrpc": "2.0", "method": method, "id": call_id}
    if params:
        body["params"] = params
    resp = requests.post(MCP_URL, headers=HEADERS, json=body)
    result = resp.json()
    if "error" in result:
        raise Exception(f"MCP Error {result['error']['code']}: {result['error']['message']}")
    return result["result"]

def tool_call(name, arguments, call_id=1):
    result = mcp_call("tools/call", {"name": name, "arguments": arguments}, call_id)
    return json.loads(result["content"][0]["text"])

# Step 1: Initialize
server_info = mcp_call("initialize")
print(f"Connected to {server_info['serverInfo']['name']} v{server_info['serverInfo']['version']}")

# Step 2: Discover policies
policies = tool_call("list_employer_policies", {
    "employer_id": "681abc123def456789012345"
}, call_id=2)
policy_id = policies["policies"][0]["policy_id"]
print(f"Using policy: {policies['policies'][0]['policy_number']}")

# Step 3: Get expected fields
fields = tool_call("get_expected_fields", {
    "employer_id": "681abc123def456789012345",
    "policy_id": policy_id
}, call_id=3)
print(f"Valid class codes: {fields['policies'][0]['class_codes']}")

# Step 4: Validate
validation = tool_call("validate_payroll_submission", {
    "employer_id": "681abc123def456789012345",
    "policy_id": policy_id,
    "rows": [
        {
            "employee_first_name": "Jane",
            "employee_last_name": "Smith",
            "class_code": "8810",
            "state": "CA",
            "gross_wages": 2500.00,
            "check_date": "2026-03-15"
        }
    ]
}, call_id=4)

if not validation["validation"]["valid"]:
    print(f"Errors: {validation['validation']['errors']}")
    exit(1)

# Step 5: Submit for real
result = tool_call("submit_payroll_data", {
    "employer_id": "681abc123def456789012345",
    "policy_id": policy_id,
    "rows": [
        {
            "employee_first_name": "Jane",
            "employee_last_name": "Smith",
            "class_code": "8810",
            "state": "CA",
            "gross_wages": 2500.00,
            "check_date": "2026-03-15"
        }
    ],
    "dry_run": False
}, call_id=5)
print(f"Submitted! File ID: {result['file_id']}")

# Step 6: Check status
import time
time.sleep(5)
status = tool_call("get_submission_status", {
    "submission_id": result["submission_id"]
}, call_id=6)
print(f"Phase 1: {status['phase_1']['green_rows']} green, {status['phase_1']['red_rows']} red")
print(f"Phase 3: ${status['phase_3']['total_premium_cents'] / 100:.2f} premium")

JavaScript (Node.js)

const MCP_URL = "https://payroll-mcp-server-902057957000.us-central1.run.app/mcp";
const API_KEY = "mcp_your_api_key_here";

async function mcpCall(method, params, id = 1) {
  const body = { jsonrpc: "2.0", method, id };
  if (params) body.params = params;

  const resp = await fetch(MCP_URL, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(body),
  });

  const result = await resp.json();
  if (result.error) throw new Error(`MCP Error ${result.error.code}: ${result.error.message}`);
  return result.result;
}

async function toolCall(name, arguments_, id = 1) {
  const result = await mcpCall("tools/call", { name, arguments: arguments_ }, id);
  return JSON.parse(result.content[0].text);
}

// Usage
const policies = await toolCall("list_employer_policies", {
  employer_id: "681abc123def456789012345",
});

const result = await toolCall("submit_payroll_data", {
  employer_id: "681abc123def456789012345",
  policy_id: policies.policies[0].policy_id,
  rows: [{
    employee_first_name: "Jane",
    employee_last_name: "Smith",
    class_code: "8810",
    state: "CA",
    gross_wages: 2500.00,
    check_date: "2026-03-15",
  }],
  dry_run: false,
});

console.log(`Submitted! File ID: ${result.file_id}`);

📧 Need Help?

Email [email protected] with:

  • Your agent name and API key prefix (first 12 characters)
  • The full JSON-RPC request and response
  • The tool name and arguments used