Skip to main content

Design MCP Server

2026.1.0+

Introduction

The Design MCP server lets AI assistants and other Model Context Protocol (MCP) clients work with Flowable Design. Through it, an assistant can browse workspaces and packages, read and edit models, validate them, and publish them using natural language, instead of working in the Design user interface.

Working through the MCP server is equivalent to working in Design itself: the same permissions, validation and versioning apply. A user can only do through the MCP server what they are allowed to do in Design.

All tools use the same keys you see in Design (workspaceKey, modelKey, and, where relevant, packageType + packageKey) rather than internal identifiers, so requests stay readable.

Opt-in feature

The Design MCP server is disabled by default and must be explicitly enabled per deployment. See Enabling the server below.

Enabling the server

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

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

Set flowable.design.mcp.server.enabled=true to turn the server on. The endpoint is exposed under the Flowable Design API, so with the default path the full URL is:

https://<your-design-host>/design-api/mcp

If you change flowable.design.mcp.server.path, replace /mcp in the URL accordingly.

These properties are also listed under the Design properties reference.

Connecting a client

The Design MCP server is a remote MCP server that uses the Streamable HTTP transport. Once it is enabled, point your MCP client at the endpoint URL (for example https://your-host/design-api/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 Design REST API. You authenticate your MCP client the same way you would authenticate any call to the Design REST API, and the permissions of the authenticated user apply: a user with read-only access cannot create or change models through the MCP server.

Two common options are:

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

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

Configuring your MCP client

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

To use HTTP Basic authentication instead of a token, 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-design": {
"type": "http",
"url": "https://your-host/design-api/mcp",
"headers": {
"Authorization": "Bearer <your-design-access-token>"
}
}
}
}
claude mcp add --transport http flowable-design https://your-host/design-api/mcp \
--header "Authorization: Bearer <your-design-access-token>"

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

{
"mcpServers": {
"flowable-design": {
"url": "https://your-host/design-api/mcp",
"headers": {
"Authorization": "Bearer <your-design-access-token>"
}
}
}
}

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

{
"servers": {
"flowable-design": {
"type": "http",
"url": "https://your-host/design-api/mcp",
"headers": {
"Authorization": "Bearer <your-design-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-design]
url = "https://your-host/design-api/mcp"
bearer_token_env_var = "FLOWABLE_DESIGN_TOKEN"

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

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

{
"mcpServers": {
"flowable-design": {
"command": "npx",
"args": [
"mcp-remote",
"https://your-host/design-api/mcp",
"--header",
"Authorization: Bearer <your-design-access-token>"
]
}
}
}

Tools and operations

The server provides ten tools. For most tools, a single operation argument (or, for validate_model, a mode argument) selects what the tool does, and the other arguments depend on that choice. List operations support paging through start (default 0), size (default 50), sort and order (asc / desc).

ToolOperations
workspace_readlist, get, palette_categories
workspace_writecreate, update, delete
package_readlist, get, palette_definitions, translations, list_revisions, get_revision
package_writecreate, update, delete, duplicate, lock, unlock, create_revision
model_readlist, get, content, data_model, palette, palette_translations, relations, outline, history
model_writecreate, update_content, update_key, update_metadata, delete, duplicate, lock, unlock, restore_version
model_editincremental structural edits; action vocabulary depends on the model type (see below)
validate_modelstored, inline (selected via mode)
publish_readtargets, requests, request, request_comments
publish_writepublish, create_request, resolve_request, comment_request

Identifying models and packages

Tools address resources by natural key:

  • workspaceKey: the workspace the resource lives in.
  • modelKey: the model's key (unique within its scope).
  • packageType (app or plugin) together with packageKey: used when a model or operation is scoped to a specific package.

Where a tool needs to know the kind of model, it takes a modelType argument. The shared model-type vocabulary includes bpmn, cmmn, dmn, form, page, app, agent, channel, event, dataObject, dataDictionary, service, decisionService, knowledgeBase, and others.

Creating and updating models

When creating models with model_write create, note:

  • paletteDefinitionKey is required for bpmn, cmmn, form, page, agent, channel and decisionService models.
  • For package_write create, paletteDefinitionCategory is required and must match a category configured for the tenant. Use workspace_read palette_categories and package_read palette_definitions to discover valid values.

The model_write content argument (raw model JSON) is rejected for bpmn, cmmn, dmn, form and page models. For those types, content must be changed with model_edit. Other model types still accept update_content.

Incremental editing with model_edit

model_edit applies a list of small, ordered, layout-free structural edits to a model. It takes workspaceKey, modelType, modelKey (plus optional packageType / packageKey) and an edits array, where each entry has a type selecting the action and action-specific parameters.

The available action vocabulary depends on the model type:

Model type(s)Actions
bpmn, cmmn (canvas)addNode, addEdge, updateNodeParameters, removeNode, removeEdge, changeParentNode
dmnaddColumn, removeColumn, moveColumn (each with kind = input | output), addRuleRow, removeRuleRow, moveRuleRow
form, pageaddFormField, removeFormField, updateFormFieldParameters, resizeFormField, moveFormField
dataObjectaddProperty, removeProperty, updateProperty
eventaddEventPayloadItem, removeEventPayloadItem, updateEventPayloadItem
dataDictionaryaddType, removeType, updateType
serviceaddOperation, removeOperation, updateOperation
agentaddOperation, removeOperation, updateOperation

For bpmn, cmmn, dmn, form and page, model_edit is the only way to change model content; model_write update_content is rejected for these types. The remaining model_edit-capable types additionally still accept update_content.

Automatic layout

Diagram layout is handled automatically. Actions reference elements by id only; you never supply coordinates. When you add or remove nodes and edges, the diagram is laid out for you.

The applied / warnings contract

model_edit reports what it did honestly. The response distinguishes:

  • applied: the edits that actually changed the model.
  • warnings: edits that were dropped or were no-ops, with the reason. For example, an edit referencing an unknown element id, or removing an element that does not exist, is reported in warnings and excluded from applied; it is not silently echoed back as if it succeeded.

Always inspect warnings after an edit to confirm every intended change landed.

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.

Discovering ids and valid stencils

Before editing a model, an assistant typically reads the model's structure to learn the element ids it can reference, and reads the palette to learn which stencils are valid for that model. This "discovery loop" avoids guessing ids or stencil types.

Read the outline to discover element ids:

{
"name": "model_read",
"arguments": {
"operation": "outline",
"workspaceKey": "claims_workspace",
"modelKey": "claim_intake_process"
}
}

Read the palette to discover the valid stencils for the model type:

{
"name": "model_read",
"arguments": {
"operation": "palette",
"workspaceKey": "claims_workspace",
"modelKey": "claim_intake_process"
}
}

Editing a BPMN model

With the ids and stencils known, apply incremental edits. The example adds a user task and wires it after an existing task. No coordinates are supplied; the layout is computed automatically:

{
"name": "model_edit",
"arguments": {
"workspaceKey": "claims_workspace",
"modelType": "bpmn",
"modelKey": "claim_intake_process",
"edits": [
{
"type": "addNode",
"id": "reviewTask",
"stencilId": "UserTask",
"name": "Review claim"
},
{
"type": "addEdge",
"id": "flowToReview",
"source": "registerTask",
"target": "reviewTask"
}
]
}
}

The response reports the edits under applied, and any dropped or no-op edits (for example, an addEdge whose source id does not exist) under warnings.

Validating a model

Validate a stored model with the model validator:

{
"name": "validate_model",
"arguments": {
"mode": "stored",
"workspaceKey": "claims_workspace",
"modelType": "bpmn",
"modelKey": "claim_intake_process"
}
}

Use "mode": "inline" with a content argument to validate a draft model definition that has not been stored yet. The response returns the list of validation issues.

Publishing

List the available deployment targets for an app, then publish:

{
"name": "publish_read",
"arguments": {
"operation": "targets",
"workspaceKey": "claims_workspace",
"appKey": "claims_app"
}
}
{
"name": "publish_write",
"arguments": {
"operation": "publish",
"workspaceKey": "claims_workspace",
"packageType": "app",
"packageKey": "claims_app",
"targetEndpointId": "production"
}
}

Where deployments go through an approval workflow, an assistant can instead create a publish request, and an approver can resolve it. Resolving a request with APPROVED triggers the deployment automatically:

{
"name": "publish_write",
"arguments": {
"operation": "create_request",
"workspaceKey": "claims_workspace",
"appKey": "claims_app",
"title": "Publish claim intake updates",
"deploymentTarget": "production"
}
}
{
"name": "publish_write",
"arguments": {
"operation": "resolve_request",
"workspaceKey": "claims_workspace",
"publishRequestId": "<id from publish_read requests>",
"resolution": "APPROVED",
"resolutionMessage": "Looks good."
}
}

Use publish_read with requests, request and request_comments to inspect the publish request inbox, a single request, and its comments.