REST API MCP Plugin
The CIB seven REST API MCP Plugin (cibseven-mcp-restapi) makes the CIB seven REST API available to Large Language Models (LLMs) through the Model Context Protocol (MCP). MCP clients such as the claude.ai connector or VS Code can then deploy processes, start process instances, complete tasks or query history by calling MCP tools.
The server is a Spring Boot auto-configured library. At startup it reads the CIB seven OpenAPI documentation and registers one MCP tool per REST operation. When an MCP client calls a tool, the server executes the corresponding request against the target API.
Besides the tool mapping, the library supports two security setups:
- Engine REST security only: the MCP endpoint itself is not protected. The caller’s
Authorizationheader (for example a CIB seven JWT) is relayed to the engine REST API, which validates it with its own authentication provider. - OAuth2-protected MCP endpoint: the MCP endpoint is an OAuth2 resource server, including the RFC 9728 discovery metadata required by MCP clients such as claude.ai. The validated caller is then either forwarded to an OAuth2-protected engine REST API (
passthrough) or translated into a CIB seven JWT (minted-jwt), so that the engine’s existing (for example LDAP-based) authorizations apply per user.
Ready-to-run server
If you do not want to embed the library into your own application, use cibseven-mcp-server: a minimal Spring Boot application hosting this library, available as a Docker image and Helm chart.
Requirements
- Java 17 or later. All current CIB seven distributions already run on Java 17+.
- Whether Spring Security is on the classpath of the host application determines the security setup.
Installation
Add the following dependency to the host application:
<dependency>
<groupId>org.cibseven.mcp</groupId>
<artifactId>cibseven-mcp-restapi</artifactId>
<version>${mcp-restapi.version}</version>
</dependency>
A minimal configuration of the host application looks as follows:
spring:
ai:
mcp:
server:
protocol: STATELESS
name: cibseven-mcp-server
version: 1.0.0
type: SYNC
instructions: "CIB seven MCP server exposing the Engine REST API as MCP tools."
streamable-http:
mcp-endpoint: /mcp
cibseven:
mcp:
restapi-mcp: true # activates the auto-configuration of the library
webclient:
engineRest:
url: http://localhost:8080
With this configuration the MCP endpoint is available under http://<host>:<port>/mcp and every tool call is sent to http://localhost:8080/engine-rest.
Configuration
| Property | Default | Description |
|---|---|---|
cibseven.mcp.restapi-mcp |
- | Set to true to activate the library. |
cibseven.openapi.url |
CIB seven openapi.json | OpenAPI document exposed as MCP tools. Can be an HTTP(S) URL or a file path. |
cibseven.webclient.engineRest.url |
http://localhost:8080 |
Base URL of the API called by the tools. |
cibseven.webclient.engineRest.path |
/engine-rest |
Path appended to the base URL. |
spring.ai.mcp.server.streamable-http.mcp-endpoint |
- | Path of the MCP endpoint, for example /mcp. Required. |
Security
A call through the MCP server crosses two hops, each of which is authenticated separately:
- Inbound (MCP client → MCP server): who is calling the MCP endpoint?
- Outbound (MCP server → engine REST): which CIB seven user does the engine REST API run the call as, so that the engine’s identity provider (for example LDAP) resolves the right groups and authorizations?
The library supports two setups. Which one is active is determined by whether Spring Security is on the classpath of the host application:
| Setup | Spring Security | Inbound | Outbound | MCP clients |
|---|---|---|---|---|
| Engine REST security only | Not on the classpath | Not protected | The caller's Authorization header is relayed unchanged |
Clients that support custom headers, such as VS Code. |
| OAuth2-protected MCP endpoint | On the classpath, issuer-uri required |
OAuth2 resource server | passthrough or minted-jwt |
All, including the claude.ai connector |
Engine REST Security Only
If Spring Security is not on the classpath of the host application, the MCP endpoint is not protected. The Authorization header of each incoming MCP request is relayed unchanged and unvalidated to the engine REST API, whatever its scheme. The engine REST API alone decides whether the credentials are valid and which user the call runs as.
A typical combination is an engine REST API with the Composite authentication provider, for example in a CIB seven Run distribution:
camunda:
bpm:
run:
auth:
enabled: true
authentication: composite # CIB seven JWT, with HTTP Basic as fallback
Unprotected Engine REST API
When using the CIB seven pseudo provider, the Authorization header is ignored. This means that every call is accepted without authentication.
Static Bearer Token
The MCP client sends the credentials for the engine REST API itself, as a static header. With the composite provider, this is a CIB seven JWT signed with the engine’s cibseven.webclient.authentication.jwtSecret:
"cibseven-mcp": {
"url": "http://localhost:8080/mcp",
"type": "http",
"headers": { "Authorization": "Bearer <CIB seven JWT>" }
}
Clients that allow setting HTTP headers directly, such as VS Code or the MCP Inspector, support this.
Not supported by claude.ai
The claude.ai connector cannot send custom headers; its UI only accepts a client id and secret. To use the MCP server with claude.ai, protect the MCP endpoint with OAuth2.
Unprotected MCP endpoint
In this setup, anyone who can reach the MCP endpoint can list the available tools, and every tool call is only as secure as the engine REST API’s own authentication. Make sure the engine REST API rejects requests without valid credentials, and only expose the MCP endpoint in trusted networks.
Only passthrough (the default of cibseven.mcp.engine-rest.auth) is supported in this setup. Setting minted-jwt makes the application fail to start, because minting a token requires a validated caller identity, which only the OAuth2 setup provides.
OAuth2-Protected MCP Endpoint
Add spring-boot-starter-oauth2-resource-server to the host application and configure spring.security.oauth2.resourceserver.jwt.issuer-uri. The library then turns the MCP endpoint into an OAuth2 resource server:
- Incoming JWT bearer tokens are validated against the authorization server.
- The standard discovery metadata is served without authentication:
/.well-known/oauth-authorization-serverand, according to RFC 9728, the Protected Resource Metadata under/.well-known/oauth-protected-resource{mcp-endpoint}(for example/.well-known/oauth-protected-resource/mcp).
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://login.microsoftonline.com/<tenant>/v2.0
cibseven:
mcp:
oauth2:
scopes-supported: "openid offline_access api://<entra-app-id>/access_as_user" # optional
| Property | Required | Description |
|---|---|---|
spring.security.oauth2.resourceserver.jwt.issuer-uri |
Yes | Issuer of the authorization server. Its presence activates the OAuth2 configuration. |
cibseven.mcp.oauth2.scopes-supported |
No | Space- or comma-separated list of scopes advertised in the Protected Resource Metadata (scopes_supported). |
issuer-uri is required
If Spring Security is on the classpath but issuer-uri is not set, the application fails to start. This prevents Spring Boot from silently falling back to its default HTTP Basic login with a generated password. If you do not want to protect the MCP endpoint, remove Spring Security from the classpath instead, see Engine REST Security Only.
issuer-uri vs. jwk-set-uri
Use issuer-uri. jwk-set-uri only tells Spring Security where to fetch the signing keys, whereas issuer-uri also enables the issuer metadata discovery that the library relies on to build the OAuth2 discovery documents for MCP clients.
Advertising Scopes
Some MCP clients, such as the claude.ai connector, have no scope input of their own and rely on the Protected Resource Metadata to know which scope to request. Without cibseven.mcp.oauth2.scopes-supported they send an /authorize request without any scope, which some authorization servers reject before the login. Microsoft Entra ID, for example, responds with:
AADSTS900144: The request body must contain the following parameter: 'scope'
Engine REST Authentication
Once the MCP server has validated the caller, it still has to tell the engine REST API who the call is for. This is handled by the pluggable EngineRestAuthProvider strategy (package org.cibseven.mcp.auth), which is selected per deployment:
| Property | Default | Description |
|---|---|---|
cibseven.mcp.engine-rest.auth |
passthrough |
passthrough or minted-jwt, see below. |
cibseven.mcp.engine-rest.minted-jwt.resolver |
claim |
claim, graph or static. Only used in minted-jwt mode. |
cibseven.mcp.engine-rest.minted-jwt.user-id-claim |
preferred_username |
Token claim read by the claim resolver. |
cibseven.mcp.engine-rest.minted-jwt.static.user-id |
- | Fixed user id used by the static resolver (development and testing only). |
cibseven.mcp.engine-rest.minted-jwt.ttl-seconds |
60 |
Lifetime of the minted CIB seven JWT in seconds. |
cibseven.webclient.authentication.jwtSecret |
- | Base64-encoded HMAC secret shared with the engine REST API. Required in minted-jwt mode. |
| Mode | Use when | Engine REST API |
|---|---|---|
passthrough (default) |
The engine REST API is an OAuth2 resource server for the same issuer as the MCP endpoint. | Validates the forwarded OAuth2 token. |
minted-jwt |
The user id in the inbound token cannot be matched to the user id stored in the engine. | Validates a CIB seven JWT, for example with the Composite authentication provider. |
File Uploads (Multipart Operations)
Operations with a multipart/form-data request body, such as creating a deployment, accept a data (or content) argument with the file content and an optional filename argument that names the uploaded part. The filename argument is accepted even though it is not declared in the OpenAPI schema.
If no filename is given, the file extension is guessed from the content (BPMN, DMN and CMMN namespaces). For other content the part is named after the field (data or content) without an extension, which downstream tools may not be able to open. For example, a BPMN file deployed without the .bpmn extension cannot be opened in Cockpit or the Modeler.
MCP clients should therefore always send a filename with the correct extension:
| Tool | Binary field | Example filename |
|---|---|---|
createDeployment |
data |
process.bpmn, decision.dmn, case.cmmn, myform.form |
addAttachment |
content |
invoice.pdf, photo.png |
setBinaryTaskVariable, setBinaryTaskLocalVariable |
data |
report.xlsx |
setProcessInstanceVariableBinary, setLocalExecutionVariableBinary |
data |
payload.json |
Example arguments for deploying a BPMN file:
{
"deployment-name": "my-deployment",
"deployment-source": "process application",
"enable-duplicate-filtering": false,
"filename": "invoice.bpmn",
"data": "<?xml version=\"1.0\" ...>"
}
The library repository contains a SKILL.md file with this guidance, which can be installed as a skill in MCP clients that support skills, so that the LLM sends the filename argument automatically.
Known Limitations
- The OpenAPI document is fetched eagerly at startup. If
cibseven.openapi.urlis not reachable, the application fails to start. This is intentional: an MCP server without tools would otherwise appear healthy. - Tool output schemas are not exposed yet; only input schemas are provided.
- Only local references (
#/components/schemas/...) are supported in the OpenAPI document; external$refs are rejected.