Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/new-agent/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ Tools can also be **sub-processes** for multi-step async patterns:
- Use this for send+wait, request+callback, or any tool needing async interaction
- See the "Sub-flow Tool Pattern" section in camunda-dev-guide.md

For non-REST connectors as tools, look up their task type and input targets via the Camunda Docs MCP tool.
For non-REST connectors as tools, look up their **element template JSON** from `https://github.com/camunda/connectors/tree/main/connectors/` for exact input target names. Do NOT add `zeebe:modelerTemplate` attributes or `elementTemplateId` headers — these cause errors in Web Modeler. The user applies templates from the Modeler UI after upload.

Save to resources/. Deploy with c8ctl.
11 changes: 10 additions & 1 deletion .claude/skills/new-process/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ argument-hint: "[process description]"

Generate a deployable Camunda 8 BPMN file. Find and read `camunda-dev-guide.md` for Zeebe-specific patterns. For agentic processes with AI agents and ad-hoc sub-processes, use `/new-agent` instead.

If the process uses non-REST connectors (Slack, Kafka, SendGrid, etc.), look up their task type and input targets via the Camunda Docs MCP tool or at https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/
If the process uses non-REST connectors (Slack, Kafka, SendGrid, etc.), look up their **element template JSON** from `https://github.com/camunda/connectors/tree/main/connectors/` to get the exact input target names, required fields, and conditional properties. Fall back to Camunda Docs MCP or https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/

## Element Templates — IMPORTANT

Do NOT manually add `zeebe:modelerTemplate` attributes or `elementTemplateId`/`elementTemplateVersion` task headers in generated BPMN XML. These cause "Template Not found" errors in Web Modeler.

Instead:
- Generate BPMN with correct `zeebe:taskDefinition`, `zeebe:ioMapping`, and `zeebe:taskHeaders` matching the template's property bindings
- Use the official element template JSON to determine correct input target names (they differ per connector — some use flat names, others use `data.*` or `authentication.*` prefixes)
- After uploading to Web Modeler, the user applies the connector template from the Modeler UI

$ARGUMENTS

Expand Down
67 changes: 63 additions & 4 deletions docs/camunda-dev-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,13 @@ All outbound connectors (REST, Slack, Kafka, SendGrid, OpenAI, AWS, etc.) use th
```

### To configure any specific connector:
1. Look up the connector in Camunda docs (use the Docs MCP tool or https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/)
2. Find the **task type** (e.g., `io.camunda:http-json:1`, `io.camunda:slack:1`, `io.camunda:kafka:1`)
3. Find the **required input target names** and expected values
4. Apply them to the pattern above
1. **Fetch the element template JSON** from `https://github.com/camunda/connectors/tree/main/connectors/<name>/element-templates/` — this is the authoritative source for input target names
2. Find the **task type** in the template (property with `"binding": {"property": "type", "type": "zeebe:taskDefinition"}`)
3. Find all **input bindings** (properties with `"binding": {"name": "...", "type": "zeebe:input"}`) — the `name` field is the exact `target` value for `<zeebe:input>`
4. Note **conditional properties** — some inputs are only required when another property has a specific value (e.g., `data.text` only when `method` = `chat.postMessage`)
5. Apply them to the universal pattern above

Fall back to Camunda Docs MCP or https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/ if the template JSON is unavailable.

Secrets (API keys, tokens) are referenced as `{{secrets.MY_SECRET}}` in input values.

Expand All @@ -140,6 +143,7 @@ Secrets (API keys, tokens) are referenced as `{{secrets.MY_SECRET}}` in input va
- Outputs (result extraction) go in `<zeebe:taskHeaders>` as `<zeebe:header>` — NOT in ioMapping
- Response shape for REST: `response.status`, `response.headers`, `response.body`
- `retryBackoff` is a reserved header key handled by the connector runtime
- **Input target naming is connector-specific**: REST uses flat names (`method`, `url`, `body`) + `authentication.*`; Slack uses `data.*` prefix for method-specific fields. Always check the element template — do NOT guess target names.

### REST connector example (most common, `io.camunda:http-json:1`):
```xml
Expand All @@ -161,6 +165,61 @@ Secrets (API keys, tokens) are referenced as `{{secrets.MY_SECRET}}` in input va
### REST connector input targets (must be exact):
`method`, `url`, `body`, `headers`, `queryParameters`, `authentication.type`, `authentication.token`, `authentication.username`, `authentication.password`, `connectionTimeoutInSeconds`, `readTimeoutInSeconds`

### Slack connector (`io.camunda:slack:1`):

Input targets vary by method. Root-level: `token`, `method`. Method-specific fields use `data.*` prefix.

**chat.postMessage:**
```xml
<zeebe:input source="{{secrets.SLACK_BOT_TOKEN}}" target="token"/>
<zeebe:input source="chat.postMessage" target="method"/>
<zeebe:input source="plainText" target="data.messageType"/>
<zeebe:input source="=slackChannel" target="data.channel"/>
<zeebe:input source="=slackMessage" target="data.text"/>
```
`data.messageType` is required (`plainText` or `messageBlock`). Channel accepts channel name, user ID (for DMs), or email.

**conversations.create:**
```xml
<zeebe:input source="conversations.create" target="method"/>
<zeebe:input source="=channelName" target="data.newChannelName"/>
<zeebe:input source="PUBLIC" target="data.visibility"/>
```
Note: field is `data.newChannelName` (not `data.name`), `data.visibility` is `PUBLIC`/`PRIVATE` (not boolean).

**conversations.invite:**
```xml
<zeebe:input source="conversations.invite" target="method"/>
<zeebe:input source="=channelId" target="data.channelId"/>
<zeebe:input source="=userIds" target="data.users"/>
```

Other methods: `reactions.add`, `pins.add`, `pins.remove`. Look up the element template JSON for full bindings.

### Element Templates — do NOT set manually in BPMN XML

Element templates are JSON files that define the connector's properties, UI groups, and validation rules for Web Modeler. Each connector has one in the `camunda/connectors` repo.

**When generating BPMN programmatically or with AI:**

Do NOT add `zeebe:modelerTemplate` / `zeebe:modelerTemplateVersion` attributes on service tasks, and do NOT add `elementTemplateId` / `elementTemplateVersion` task headers. These cause "Template Not found" errors in Web Modeler because the template must be resolved from the Modeler's internal catalog — raw XML references don't link to it.

Instead:
1. Generate BPMN with correct `zeebe:taskDefinition`, `zeebe:ioMapping`, and `zeebe:taskHeaders` that match the template's property bindings
2. The user applies the connector template from the Web Modeler UI after upload (right-click task → "Apply template" or use the properties panel)
3. Web Modeler will recognize the existing inputs and map them to the template fields

**Reading element template JSON — how to extract input targets:**

Each template property has a `binding` object:
- `"type": "zeebe:input"` with `"name": "..."` → the `name` is the exact `target` for `<zeebe:input>`
- `"type": "zeebe:taskDefinition"` with `"property": "type"` → the task type
- `"type": "zeebe:taskHeader"` with `"key": "..."` → the `key` for `<zeebe:header>`
- Properties with `"condition"` are only required when the condition matches (e.g., `body` only for POST/PUT/PATCH)
- Properties with `"value"` have defaults — include them if they're required (`constraints.notEmpty`)

Template JSON location: `https://github.com/camunda/connectors/tree/main/connectors/<name>/element-templates/`

---

## Agentic BPMN (AI Agents)
Expand Down