MCP
Stateway exposes a Model Context Protocol (MCP) server that lets LLMs and AI agents interact with the BPMN engine through native tool calling. Instead of crafting raw HTTP requests, agents discover and invoke typed tools — the MCP server translates each call into the appropriate Stateway API operation.
Why MCP?
- Native tool discovery — the LLM sees available tools with schemas and descriptions automatically
- No HTTP boilerplate — the MCP server handles authentication, routing, and error handling
- Type-safe parameters — every tool has a Zod-validated schema; invalid inputs are rejected before reaching the API
- Streaming over SSE — long-lived connections via Server-Sent Events keep the agent responsive
Architecture
┌─────────────┐ SSE / MCP ┌─────────────────┐ REST ┌───────── ─────┐
│ AI Agent │ ◄────────────────► │ Stateway MCP │ ◄──────────► │ Stateway │
│ (Claude, │ tools/list │ Server │ X-API-Key │ API │
│ Cursor…) │ tools/call │ :3001 │ │ :3000 │
└─────────────┘ └─────────────────┘ └──────────────┘
Connecting an MCP Client
The Stateway MCP server is available at:
| Environment | URL |
|---|---|
| Local (Docker Compose) | http://localhost:3001/mcp/sse |
| Production | https://mcp.stateway.io/mcp/sse |
All connections require a valid Stateway API key in the X-API-Key header. Register a tenant and create a key via the API Reference or the landing page before connecting.
Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"stateway": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/sdk@latest",
"client",
"sse",
"http://localhost:3001/mcp/sse"
],
"env": {
"X_API_KEY": "sw_live_xxxxxxxx"
}
}
}
}
Cursor
In Cursor Settings → MCP, add a new server:
- Name:
stateway - Type:
SSE - URL:
http://localhost:3001/mcp/sse - Headers:
X-API-Key: sw_live_xxxxxxxx
Generic SSE Client
Any MCP client that supports SSE can connect to:
GET /mcp/sse
Host: mcp.stateway.io
X-API-Key: sw_live_xxxxxxxx
The server validates the API key, then streams the MCP session. Tool calls are sent as POST requests to /mcp/messages?sessionId=<id>.
Available Tools
The Stateway MCP server exposes 13 tools organized by domain. Each tool maps to a REST API endpoint; see the API Reference for full endpoint documentation.
Definitions
list_definitions
List all process definitions for the authenticated tenant.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Maximum items to return (1–100, default: system default) |
offset | number | No | Pagination offset |
Example call:
{
"name": "list_definitions",
"arguments": {
"limit": 10,
"offset": 0
}
}
Example response:
{
"definitions": [
{
"key": "expense-approval",
"name": "Expense Approval",
"version": 3,
"status": "active"
}
],
"total": 1
}
get_definition
Retrieve a single process definition by its key.
| Parameter | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Definition key (e.g., expense-approval) |
Example call:
{
"name": "get_definition",
"arguments": {
"key": "expense-approval"
}
}
Instances
start_process
Start a new process instance from a definition.
| Parameter | Type | Required | Description |
|---|---|---|---|
definition_key | string | Yes | Process definition key |
definition_version | number | No | Specific version (omit for latest active) |
correlation_id | string | No | External correlation ID for tracing |
variables | object | No | Initial process variables |
metadata | object | No | Instance metadata |
Example call:
{
"name": "start_process",
"arguments": {
"definition_key": "expense-approval",
"variables": {
"amount": 1500.00,
"requester": "john@acme.com",
"description": "Conference flight tickets"
}
}
}
Example response:
{
"id": "inst-a1b2c3d4",
"definition_key": "expense-approval",
"definition_version": 3,
"status": "running",
"variables": {
"amount": 1500.00,
"requester": "john@acme.com",
"description": "Conference flight tickets"
},
"created_at": "2026-04-26T12:00:00.000Z"
}
get_instance
Get the current state, variables, and status of a process instance.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Instance ID |
Example call:
{
"name": "get_instance",
"arguments": {
"id": "inst-a1b2c3d4"
}
}
Example response:
{
"id": "inst-a1b2c3d4",
"definition_key": "expense-approval",
"status": "running",
"variables": {
"amount": 1500.00,
"requester": "john@acme.com"
},
"tokens": [
{
"id": "tok-001",
"element_id": "review-expense",
"element_type": "userTask",
"status": "waiting"
}
],
"created_at": "2026-04-26T12:00:00.000Z"
}
get_instance_tokens
Retrieve active execution tokens for a process instance. Tokens show where the process is currently waiting (user tasks, timers, gateways).
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Instance ID |
Example call:
{
"name": "get_instance_tokens",
"arguments": {
"id": "inst-a1b2c3d4"
}
}
Events
send_event
Send an external event (message, signal, or callback) to a running process instance.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Instance ID |
event_type | enum | Yes | One of: message, signal, callback |
event_name | string | Yes | Event name defined in the BPMN model |
payload | object | No | Event payload data |
Example call:
{
"name": "send_event",
"arguments": {
"id": "inst-a1b2c3d4",
"event_type": "message",
"event_name": "payment-received",
"payload": {
"paymentId": "pay-001",
"amount": 1500,
"method": "credit_card"
}
}
}
Tasks
list_tasks
List human tasks with optional filters.
| Parameter | Type | Required | Description |
|---|---|---|---|
status | enum | No | Filter by: pending, claimed, completed, cancelled |
assignee | string | No | Filter by assignee |
instance_id | string (UUID) | No | Filter by process instance |
limit | number | No | Maximum items (1–100) |
offset | number | No | Pagination offset |
Example call:
{
"name": "list_tasks",
"arguments": {
"status": "pending",
"limit": 10
}
}
Example response:
{
"tasks": [
{
"id": "task-xyz789",
"name": "Review Expense",
"status": "pending",
"process_instance_id": "inst-a1b2c3d4",
"definition_key": "expense-approval",
"variables": {
"amount": 1500.00,
"requester": "john@acme.com"
}
}
],
"total": 1
}
get_task
Get details of a specific human task.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Task ID |
Example call:
{
"name": "get_task",
"arguments": {
"id": "task-xyz789"
}
}
claim_task
Claim a human task for the current user (or agent).
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Task ID |
Example call:
{
"name": "claim_task",
"arguments": {
"id": "task-xyz789"
}
}
complete_task
Complete a human task, providing output variables that merge into the process instance.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Task ID |
variables | object | No | Output variables to merge |
Example call:
{
"name": "complete_task",
"arguments": {
"id": "task-xyz789",
"variables": {
"approved": true,
"approvedAmount": 1500,
"reviewedBy": "ai-agent-001",
"comments": "Auto-approved: amount within policy limits"
}
}
}
Example response:
{
"id": "task-xyz789",
"status": "completed",
"variables": {
"amount": 1500,
"requester": "john@acme.com",
"approved": true,
"approvedAmount": 1500,
"reviewedBy": "ai-agent-001",
"comments": "Auto-approved: amount within policy limits"
},
"completed_at": "2026-04-26T12:05:00.000Z"
}
Decisions
evaluate_decision
Evaluate a DMM (Decision Model) directly without creating a process instance.
| Parameter | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Decision definition key |
version | number | No | Specific version (omit for latest active) |
inputs | object | Yes | Input values for the decision |
Example call:
{
"name": "evaluate_decision",
"arguments": {
"key": "discount-calculator",
"inputs": {
"customerType": "premium",
"orderTotal": 1500
}
}
}
Example response:
{
"decision": "discount-calculator",
"hitPolicy": "FIRST",
"result": {
"discountPercent": 15
},
"matchedRules": ["rule-1"]
}
list_decisions
List all decision definitions for the tenant.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Maximum items (1–100) |
offset | number | No | Pagination offset |
Example call:
{
"name": "list_decisions",
"arguments": {
"limit": 10
}
}
Health
get_health
Check if the Stateway platform is healthy and ready to accept requests.
Example call:
{
"name": "get_health",
"arguments": {}
}
Example response:
{
"status": "ok"
}
Common Agent Workflows
Workflow 1: Auto-Approval Agent
An agent that polls pending tasks and auto-approves low-risk requests:
1. list_tasks → filter status=pending
2. get_task → read variables (amount, risk_score)
3. complete_task → submit approval decision
4. get_instance → verify process advanced
Workflow 2: Process Monitor
An agent that starts a process and tracks its progress:
1. start_process → create instance with initial variables
2. get_instance → check status and tokens
3. get_instance_tokens→ see where process is waiting
4. send_event → trigger continuation when external condition met
Workflow 3: Decision Assistant
An agent that uses decision models for business logic:
1. list_decisions → discover available models
2. evaluate_decision→ compute result without side effects
3. start_process → use the decision result to start a workflow
Tool-to-API Mapping
| MCP Tool | API Endpoint | Method |
|---|---|---|
list_definitions | /v1/definitions | GET |
get_definition | /v1/definitions/:key | GET |
start_process | /v1/instances | POST |
get_instance | /v1/instances/:id | GET |
get_instance_tokens | /v1/instances/:id/tokens | GET |
send_event | /v1/instances/:id/events | POST |
list_tasks | /v1/tasks | GET |
get_task | /v1/tasks/:id | GET |
claim_task | /v1/tasks/:id/claim | POST |
complete_task | /v1/tasks/:id/complete | POST |
evaluate_decision | /v1/decisions/:key/evaluate | POST |
list_decisions | /v1/decisions | GET |
get_health | /health/ready | GET |
For full request/response schemas, authentication details, and error codes, see the Stateway API Reference.
Best Practices for AI Agent Integration
- Use descriptive variable names — makes it easier for the agent to reason about process state
- Poll instance state after completing tasks — verify the process advanced as expected
- Handle task conflicts — tasks may be claimed or completed by another agent between listing and acting
- Include agent metadata in variables — e.g.,
reviewedBy: "ai-agent-001"for audit trails - Use decision models for business logic — keeps rules external and versioned, rather than hard-coded in the agent
- Validate API key before connecting — the MCP server rejects invalid keys at connection time with a 401 response