Skip to main content

Work MCP Server

2026.1.0+

Introduction

The Work MCP server lets AI assistants and other Model Context Protocol (MCP) clients work with the Flowable Work runtime. Through it, an assistant can browse work (process and case) definitions, read and act on running work instances and tasks, look up users, groups and master data, discover and invoke service-backed form fields, and discover and invoke action definitions using natural language, instead of working in the Flowable Work user interface.

Working through the MCP server is equivalent to working in Flowable Work itself: every tool enforces the same permissions and tenant scoping as the Work REST API. A user can only do through the MCP server what they are allowed to do in Flowable Work.

The read and action tools return the same representations the Flowable Work REST API returns, so the data an assistant sees matches what the UI and the REST API show.

Opt-in feature

The Work MCP server is disabled by default and must be explicitly enabled per deployment. It also requires a valid AI Connector license. See Enabling the server below.

Enabling the server

The server is gated behind a single property and is off by default:

PropertyDescriptionDefault
flowable.platform.mcp.server.enabledEnables the Work MCP server.false
flowable.platform.mcp.server.pathPath the MCP endpoint is exposed at, relative to the Work platform REST API (/platform-api)./mcp

Set flowable.platform.mcp.server.enabled=true to turn the server on. The endpoint is mounted into the Flowable Work platform REST dispatcher, relative to the Work platform REST API base path. With the default path the full URL is:

<your-work-base-path>/mcp

where <your-work-base-path> is the base URL of your Flowable Work platform REST API, including the context path (for example https://your-host/flowable-work/platform-api). If you change flowable.platform.mcp.server.path, replace /mcp accordingly.

In addition to being enabled, the server requires a valid AI Connector license. Tool calls are gated behind a shared license check: if no AI Connector license is present, calls fail with a structured error rather than executing.

These properties are also listed under the Work properties reference.

Connecting a client

The Work MCP server is a remote MCP server that uses a stateless Streamable HTTP transport. Once it is enabled, point your MCP client at the endpoint URL (<your-work-base-path>/mcp) and authenticate as described below. The server exposes the tools listed further down; your client decides when to call them.

Authentication

The MCP endpoint is protected in exactly the same way as the rest of the Flowable Work platform REST API. You authenticate your MCP client the same way you would authenticate any call to the Work REST API, and the permissions of the authenticated user apply: a user with read-only access cannot start instances, complete tasks or invoke actions through the MCP server.

Two common options are:

  • Bearer token: send a Flowable Work access token in an Authorization: Bearer <token> header. This is the recommended option for AI assistants and automation. See Flowable Access Tokens for how to create one.
  • HTTP Basic authentication: send Work credentials in an Authorization: Basic <base64 of user:password> header, for example using a dedicated technical user.

For the authentication mechanisms Flowable Work supports (HTTP Basic, OAuth2 / SSO and access tokens), see the Flowable security documentation.

Configuring your MCP client

Most MCP clients are configured with a small JSON file listing the servers to connect to. Add the Work MCP server as an HTTP server with the endpoint URL, and pass your credentials in a header. Replace the URL and credentials in the examples below with your own values.

The examples below use an access token (Bearer <your-work-access-token>). To use HTTP Basic authentication instead, replace the header value with Basic <base64 of user:password>.

Claude Code: add an .mcp.json file to your project root (or run the command below):

{
"mcpServers": {
"flowable-work": {
"type": "http",
"url": "<your-work-base-path>/mcp",
"headers": {
"Authorization": "Bearer <your-work-access-token>"
}
}
}
}
claude mcp add --transport http flowable-work <your-work-base-path>/mcp \
--header "Authorization: Bearer <your-work-access-token>"

Cursor: .cursor/mcp.json in your project, or ~/.cursor/mcp.json for all projects:

{
"mcpServers": {
"flowable-work": {
"url": "<your-work-base-path>/mcp",
"headers": {
"Authorization": "Bearer <your-work-access-token>"
}
}
}
}

VS Code (GitHub Copilot): .vscode/mcp.json in your project:

{
"servers": {
"flowable-work": {
"type": "http",
"url": "<your-work-base-path>/mcp",
"headers": {
"Authorization": "Bearer <your-work-access-token>"
}
}
}
}

Codex CLI: MCP servers are configured in ~/.codex/config.toml. For a remote server, Codex reads the bearer token from an environment variable:

[mcp_servers.flowable-work]
url = "<your-work-base-path>/mcp"
bearer_token_env_var = "FLOWABLE_WORK_TOKEN"

Set the token in your environment before starting Codex, for example export FLOWABLE_WORK_TOKEN=<your-work-access-token>.

Claude Desktop: Claude Desktop connects to a remote server through a local bridge. In claude_desktop_config.json:

{
"mcpServers": {
"flowable-work": {
"command": "npx",
"args": [
"mcp-remote",
"<your-work-base-path>/mcp",
"--header",
"Authorization: Bearer <your-work-access-token>"
]
}
}
}

Tools and operations

The server provides ten tools. For each tool, a single operation argument selects what the tool does, and the other arguments depend on that choice. List operations support paging.

Read tools are advertised to the client as read-only; the action and invoke tools are advertised as non-read-only (state-changing).

ToolOperations
work_definition_readlist, get, get_start_form, list_deployments
work_instance_readlist, list_historic, get, variables, identity_links (optional linkType), candidate_users, comments
task_readlist, get, form, variables, identity_links (optional linkType), candidate_users, comments
work_instance_actionstart, add_comment, update_status, assign, change_due_date
task_actioncomplete, save_form, claim, add_comment
idm_readlist_users, get_user, list_groups, get_group, user_groups, group_members
master_data_readlist, get, get_by_key
action_readscoped (actions available on an object), get_form (an action's form model)
service_invokeinvoke a service-backed form field across seven scopes
action_invokeexecute an action definition by key, or execute an active action instance by id

Work definitions and instances

A work definition is a process (bpmn) or case (cmmn) definition; a work instance is a running or historic process or case. Where a tool needs to know which engine a definition or instance belongs to, it takes a type argument with the value bpmn or cmmn. The work-instance representation keeps this engine scope type on its output so it matches the tool input vocabulary.

Resources are addressed by their natural identifiers:

  • work_definition_read get resolves a definition by its key.
  • work_instance_read and work_instance_action operations address a running or historic instance by its instanceId.
  • task_read and task_action operations address a task by its taskId.

Permission-checked access

Every tool enforces the same permissions and tenant scoping as the Work REST API. A caller can only read or do through the MCP server what they are allowed to read or do in Flowable Work.

Read tools are permission-filtered: task_read list returns only the tasks the caller may see, idm_read returns only the users the caller may access, and action_read scoped returns only the actions the caller may execute on an object. The action and invoke tools enforce the same access checks before changing anything, including the form-field access check when an action runs in a form context.

Discovering and invoking actions

Actions are the runtime behind a Form Engine Action button (workAction). The action_read and action_invoke tools mirror how the Flowable Work frontend drives them:

  • action_read scoped discovers the active actions available on a scoped object — the actions that can currently be executed with action_invoke. The list is flat and mixes action definitions and active action instances (instance-backed entries carry an actionInstanceId). It takes a scopeType (such as bpmn, cmmn or user) and the object's scopeId, and supports optional filters: key, nameLike, supportsChannels and global.
  • action_read get_form returns the form model an action expects. Provide exactly one of actionDefinitionKey (the action's input form) or actionInstanceId (an active instance's form).
  • action_invoke executes an action. Provide exactly one of actionDefinitionKey (execute a definition) or actionInstanceId (execute an active action instance). An action instance can only be executed once. When the action lives on a form, supply the formId and the formFieldId of the action button; the action's form-field access is then verified.

service_invoke scopes

service_invoke invokes a service-backed form field (Service Select, Service Data Table or Service Button) within a Work form context. The scope argument selects the form context and determines how scopeId is interpreted. It must be one of:

task, process_instance, case_instance, process_definition, case_definition, case_page, page.

For a Service Select or Service Data Table, pass an operationType of search or lookup; omit it for a Service Button (a plain invoke). The input argument carries the field's service input parameters as a name → value map.

Error handling

Tool calls return structured errors instead of raw stack traces. Flowable engine exceptions are mapped to a small set of error codes carried in the error text:

CodeMeaning
NOT_FOUNDThe referenced definition, instance, task, user, group or master data could not be found (or is not accessible).
FORBIDDENThe caller is not allowed to perform the operation.
INVALID_ARGUMENTA required argument is missing or has an invalid value (for example an unknown operation, scope or type).
CONFLICTThe operation conflicts with the current state of the resource.
ENGINE_ERRORAn unexpected engine error occurred.

An unknown or missing operation yields a coaching INVALID_ARGUMENT error that lists the operations the tool supports.

Examples

The examples below show the arguments passed to each tool. In practice your AI assistant builds these calls for you from your natural-language requests; the arguments are shown here to illustrate what each tool does.

Reading definitions

Get a work definition by its key:

{
"name": "work_definition_read",
"arguments": {
"operation": "get",
"key": "oneTaskProcess"
}
}

Starting a work instance

Start a process (bpmn) or case (cmmn) instance from a definition key:

{
"name": "work_instance_action",
"arguments": {
"operation": "start",
"definitionKey": "oneTaskProcess",
"type": "bpmn"
}
}

Other work_instance_action operations act on a running instance by instanceId, for example:

{
"name": "work_instance_action",
"arguments": {
"operation": "assign",
"instanceId": "<instance id>",
"userId": "admin"
}
}
{
"name": "work_instance_action",
"arguments": {
"operation": "change_due_date",
"instanceId": "<instance id>",
"dueDate": "2026-07-01T00:00:00Z"
}
}

Working on a task

Claim a task, add a comment and complete it with an outcome:

{
"name": "task_action",
"arguments": {
"operation": "claim",
"taskId": "<task id>"
}
}
{
"name": "task_action",
"arguments": {
"operation": "complete",
"taskId": "<task id>",
"outcome": "approve"
}
}

Reading master data

List master data instances of a given type, then resolve one by its key:

{
"name": "master_data_read",
"arguments": {
"operation": "list",
"definitionKey": "md-country",
"search": "Atlan"
}
}
{
"name": "master_data_read",
"arguments": {
"operation": "get_by_key",
"definitionKey": "md-country",
"key": "ATL"
}
}

Looking up users and groups

{
"name": "idm_read",
"arguments": {
"operation": "group_members",
"groupKey": "<group key>"
}
}

Invoking a service-backed form field

Invoke a Service Select / Data Table field within a case instance form context:

{
"name": "service_invoke",
"arguments": {
"scope": "case_instance",
"scopeId": "<case instance id>",
"fieldId": "<form field id>",
"input": {
"personInput": { "name": "Homer", "age": 1 },
"dateInput": "2026-01-19"
}
}
}

Discovering actions on an object

List the actions available on a running process (bpmn) instance:

{
"name": "action_read",
"arguments": {
"operation": "scoped",
"scopeType": "bpmn",
"scopeId": "<instance id>"
}
}

Read the form an action expects:

{
"name": "action_read",
"arguments": {
"operation": "get_form",
"actionDefinitionKey": "form-action"
}
}

Invoking an action

Execute an action definition by its key, passing a payload:

{
"name": "action_invoke",
"arguments": {
"actionDefinitionKey": "start-one-task-process",
"payload": {
"customer": "Kermit the Frog"
}
}
}

When an action is invoked in a form context, supply the formId and the formFieldId of the action button.

Alternatively, execute an active action instance by its id:

{
"name": "action_invoke",
"arguments": {
"actionInstanceId": "<action instance id>"
}
}