Elastic Security ACTION
Create or Update Detection Rule
Create a new Elastic Security detection rule via POST /api/detection_engine/rules, or full-replace update an existing one when
id is provided, via PUT /api/detection_engine/rules. On update, the tool first fetches the rule's current definition and merges your supplied fields into it, so you only need to pass the fields you want to change — Kibana's underlying PUT still requires the full definition, but this tool handles that for you. Run Find Detection Rules first to obtain the id for updates (it also accepts ruleId if that's all you have). name, description, riskScore, severity, and type are required when creating (no id); optionally set ruleId on create to assign a custom rule_id instead of letting Kibana generate one. For type: threshold rules, set threshold. For type: threat_match rules, set threatIndex and threatMapping. Use additionalFields as an escape hatch for any other type-specific fields (e.g. anomaly_threshold for machine_learning rules). Example: calling with name: "Suspicious PowerShell", description: "...", riskScore: 60, severity: "high", type: "query", query: "process.name: powershell.exe" returns { id: "7ac3...", rule_id: "f3bb...", name: "Suspicious PowerShell", enabled: true, ... }; calling again with that id and riskScore: 80 returns the same rule with only the risk score changed. See the create documentation and the update documentation- Action
- Writes data
- API key
- SDK
- MCP
IMPLEMENTATION
Call this tool
Connect a user's Elastic Security account once, then configure and run Create or Update Detection Rule from your backend or agent.
import { PipedreamClient } from "@pipedream/sdk"
const pd = new PipedreamClient({
projectId: process.env.PIPEDREAM_PROJECT_ID!,
clientId: process.env.PIPEDREAM_CLIENT_ID!,
clientSecret: process.env.PIPEDREAM_CLIENT_SECRET!,
projectEnvironment: "production",
})
const result = await pd.actions.run({
id: "elastic_security-create-or-update-detection-rule",
externalUserId: "{external_user_id}", // any stable ID for this user in your system
configuredProps: {
elastic_security: { authProvisionId: "apn_xxxxxxx" },
id: "Rule ID",
ruleId: "Rule ID (User-defined)",
},
})
console.log(result)curl -X POST https://api.pipedream.com/v1/connect/{project_id}/actions/run \
-H "Content-Type: application/json" \
-H "X-PD-Environment: production" \
-H "Authorization: Bearer {access_token}" \
-d '{
"external_user_id": "{external_user_id}",
"id": "elastic_security-create-or-update-detection-rule",
"configured_props": {
"elastic_security": { "authProvisionId": "apn_xxxxxxx" },
"id": "Rule ID",
"ruleId": "Rule ID (User-defined)"
}
}'// accessToken: mint a short-lived token with the Connect SDK — see the MCP guide
const transport = new StreamableHTTPClientTransport(
new URL("https://remote.mcp.pipedream.net/v3"),
{
requestInit: {
headers: {
Authorization: `Bearer ${accessToken}`,
"x-pd-project-id": "{project_id}",
"x-pd-environment": "production",
"x-pd-external-user-id": "{external_user_id}", // any stable ID for this user in your system
"x-pd-app-slug": "elastic_security",
},
},
},
)
const mcp = new Client({ name: "my-agent", version: "1.0.0" })
await mcp.connect(transport)
const { tools } = await mcp.listTools()
// listTools() hands your model this tool's input schema, so it can
// fill the arguments itself:
const result = await mcp.callTool({
name: "elastic_security-create-or-update-detection-rule",
arguments: {
id: "Rule ID",
ruleId: "Rule ID (User-defined)",
},
})SCHEMA
Inputs
Pipedream supplies the connected account. Your application provides the operation-specific values below. Dynamic inputs are resolved against that user's account.
| Property | Type | Description |
|---|---|---|
id Rule ID | string | The Kibana internal UUID of an existing rule to update (e.g. 7ac3c66d-f0b4-4f7c-a576-7bb91bf4e9ce). This is the sole trigger for update mode — omit it to create a new rule. Run Find Detection Rules first to obtain valid IDs (it accepts either id or ruleId for lookup). Optional |
ruleId Rule ID (User-defined) | string | When creating (no id): an optional custom rule_id to assign to the new rule, e.g. my-custom-rule-id — if omitted, Kibana generates one. Not used to identify a rule for update; use id for that (run Find Detection Rules with ruleId first if that's all you have, to get its id). Optional |
name Name | string | Human-readable rule name (e.g. Suspicious PowerShell Execution). Required when creating. Optional |
description Description | string | Description of what the rule detects. Required when creating. Optional |
riskScore Risk Score | integer | Risk score from 0 to 100. Required when creating. Optional |
severity Severity | string | Rule severity. One of: low, medium, high, critical. Required when creating. Optional |
type Type | string | Rule type discriminator. One of: query, eql, saved_query, threshold, threat_match, machine_learning, new_terms, esql. Required when creating. Cannot be changed on update. Optional |
query Query | string | Detection query in KQL or Lucene (required for query/saved_query/eql style rules), e.g. process.name: powershell.exe. Optional |
language Language | string | Query language: kuery or lucene. Optional |
index Index Patterns | string[] | Index patterns the rule runs against (e.g. logs-*, winlogbeat-*). Optional |
enabled Enabled | boolean | Whether the rule is enabled. Defaults to true on create. Optional |
tags Tags | string[] | Tags to apply to the rule. Run List Tags first to reuse existing tags instead of creating near-duplicates. On update, this replaces the rule's existing tag set entirely. Optional |
interval Interval | string | How often the rule runs, as date-math (e.g. 5m). Defaults to 5m on create. Optional |
from From | string | Start of the rule's lookback window as date-math (e.g. now-6m). Defaults to now-6m on create. Optional |
maxSignals Max Signals | integer | Maximum number of alerts the rule can create per run. Minimum 1, maximum 1000. Defaults to 100 on create. Optional |
threshold Threshold | object | Threshold configuration, required for type: threshold rules. Example: {"field":["host.name"],"value":5} fires when 5+ matching events share the same host.name. Optional |
threatIndex Threat Index | string[] | Index patterns containing threat intelligence indicators, required for type: threat_match rules. Example: ["logs-ti_*"]. Optional |
threatMapping Threat Mapping | object | A single threat-match group, required for type: threat_match rules. Shape: {"entries":[{"field":"source.ip","type":"mapping","value":"threat.indicator.ip"}]}, matching a local event field against a threat indicator field. For multiple match groups, use additionalFields.threat_mapping (an array of these objects) instead. Optional |
additionalFields Additional Fields | object | Additional rule fields to merge into the request body, for type-specific configuration not covered by other parameters (e.g. {"anomaly_threshold":50,"machine_learning_job_id":["job-1"]} for machine_learning rules, or threat_mapping as an array for multi-group threat_match rules, since threatMapping only supports one group). id, rule_id, and type here are always ignored — use the dedicated type parameter instead. Read-only fields (created_at, updated_at, revision, etc.) are also always ignored, even though they have no dedicated parameter of their own. Any other key here is ignored if you've also set its dedicated parameter (that value wins); otherwise it's used as given. Optional |
REFERENCE
Tool details
Behavior hints are published with the component in the Pipedream registry and surface as MCP tool annotations, so an agent can reason about a tool before it calls it.
- Registry key
- elastic_security-create-or-update-detection-rule
- Version
- 0.0.1
- App
- Elastic Security
- Authentication
- API key
- Read-only
- No
- Destructive
- No
- Open world
- Yes
- Source
- View on GitHub ↗