Send tasks (commands) to EDR sensors to gather data or take action. Handles offline agents via reliable-tasking, collects responses via LCQL queries, and creates D&R rules for automated response handling. Use for live response, data collection, forensic acquisition, or fleet-wide operations like "get OS version from all Windows servers" or "isolate all hosts with tag X".
Sends commands to EDR sensors to gather data or take action, handling offline agents and response collection.
/plugin marketplace add refractionPOINT/lc-ai/plugin install refractionpoint-lc-essentials-marketplace-plugins-lc-essentials@refractionPOINT/lc-aiThis skill is limited to using the following tools:
This skill orchestrates sending tasks (commands) to EDR sensors and handling responses. It solves two key challenges of sensor tasking:
Prerequisites: Run
/init-lcto initialize LimaCharlie context.
All LimaCharlie API calls go through the limacharlie-api-executor sub-agent:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: <function-name>
- Parameters: {<params>}
- Return: RAW | <extraction instructions>
- Script path: {skill_base_directory}/../../scripts/analyze-lc-result.sh"
)
| Rule | Wrong | Right |
|---|---|---|
| MCP Access | Call mcp__* directly | Use limacharlie-api-executor sub-agent |
| LCQL Queries | Write query syntax manually | Use generate_lcql_query() first |
| Timestamps | Calculate epoch values | Use date +%s or date -d '7 days ago' +%s |
| OID | Use org name | Use UUID (call list_user_orgs if needed) |
Use this skill when the user wants to:
Example requests:
Direct tasking (get_processes, dir_list, etc.) only works for online sensors. If a sensor is offline, the task fails immediately.
Reliable tasking queues tasks for delivery when sensors come online. Tasks persist for a configurable TTL (default: 1 week).
| Approach | Use When | Pros | Cons |
|---|---|---|---|
| Direct Task | ≤5 online sensors, need immediate response | Fast, response inline | Fails if offline |
| Reliable Task | >5 sensors, offline sensors, or can wait | Guaranteed delivery | Response via telemetry |
| Method | Use When | How It Works |
|---|---|---|
| Inline Response | Direct tasking small numbers | Response returned directly from API |
| LCQL Query | Need to collect reliable task responses | Query for routing/investigation_id containing your context |
| D&R Rule | Need automated action on responses | Create rule matching investigation_id, with response actions |
START: User wants to task sensors
|
v
Are all targets online AND ≤5 sensors?
|
|--YES--> Use Direct Tasking (inline response, parallel execution)
|
|--NO--> Use Reliable Tasking (>5 sensors OR any offline)
|
v
Do you need the response data?
|
|--NO (action-only like isolate)--> Create Reliable Task, done
|
|--YES--> Do you need automated handling?
|
|--NO--> Create Reliable Task, wait 2+ min, then LCQL query
|
|--YES--> 1. Create D&R rule with TTL FIRST
2. THEN create Reliable Task
(rule must exist before task to avoid missing responses)
Parse the user's request to determine:
If you don't have the OID, get it first:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: list_user_orgs
- Parameters: {}
- Return: RAW"
)
Check sensor status if targeting specific sensors:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: is_online
- Parameters: {\"oid\": \"[oid]\", \"sid\": \"[sid]\"}
- Return: RAW"
)
CRITICAL: Filter to Taskable EDR Sensors
Before spawning executor agents or tasking sensors, you MUST verify sensors are EDR agents (not adapters or cloud sensors). Non-EDR sensors will fail with
UNSUPPORTED_FOR_PLATFORM.Taskable sensors require BOTH:
- Platform:
windows,linux,macos, orchrome- Architecture: NOT
usp_adapter(code 9)A sensor running on Linux platform but with
arch=usp_adapteris an adapter (USP), not an EDR agent. These adapters forward logs but cannot execute commands.Use combined selector when listing sensors:
Task( subagent_type="lc-essentials:limacharlie-api-executor", model="haiku", prompt="Execute LimaCharlie API call: - Function: list_sensors - Parameters: { \"oid\": \"[oid]\", \"selector\": \"(plat==windows or plat==linux or plat==macos) and arch!=usp_adapter\", \"online_only\": true } - Return: List of SIDs with hostnames and platforms" )Or check sensor info before tasking - verify both
platformis in["windows", "linux", "macos", "chrome"]ANDarchis not9/usp_adapter.
For immediate data collection from a small number of online sensors (up to 5), use direct tasking functions with parallel execution.
Available Direct Task Functions (return response inline):
| Function | Description | Common Use |
|---|---|---|
get_processes | Running processes | Process investigation |
get_process_modules | Loaded modules | Malware analysis |
get_network_connections | Active connections | C2 hunting |
get_os_version | OS details | Asset inventory |
get_users | System users | Account enumeration |
get_services | Windows services | Persistence check |
get_drivers | Loaded drivers | Rootkit detection |
get_autoruns | Persistence mechanisms | Malware persistence |
get_packages | Installed packages | Software inventory |
get_registry_keys | Registry values | Config/persistence |
dir_list | Directory listing | File investigation |
find_strings | String search | Memory forensics |
yara_scan_process | YARA scan process | Malware detection |
yara_scan_file | YARA scan file | File analysis |
yara_scan_directory | YARA scan directory | Bulk scanning |
yara_scan_memory | YARA scan memory | Memory malware |
Example - Get processes from a sensor:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: get_processes
- Parameters: {\"oid\": \"[oid]\", \"sid\": \"[sid]\"}
- Return: RAW"
)
For more than 5 sensors, offline sensors, or fleet-wide operations, use reliable tasking.
IMPORTANT: Order of Operations
If you need automated response handling via D&R rules, you MUST create the D&R rule FIRST, before creating the reliable task. This ensures no responses are missed between task creation and rule deployment.
Order: D&R Rule → Reliable Task (not the other way around)
Read the function documentation first:
Read: plugins/lc-essentials/skills/limacharlie-call/functions/reliable-tasking.md
Create a reliable task:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: reliable_tasking
- Parameters: {
\"oid\": \"[oid]\",
\"task\": \"os_version\",
\"selector\": \"plat==windows\",
\"context\": \"fleet-inventory-2024-01\",
\"ttl\": 86400
}
- Return: RAW"
)
Key Parameters:
task: The command to execute (e.g., os_version, mem_map --pid 4, run --shell-command whoami)selector: Sensor selector expression (e.g., plat==windows, production in tags, sid=='abc-123')context: Identifier that appears in routing/investigation_id of responses (for collection)ttl: Time-to-live in seconds (default: 604800 = 1 week)Available Task Commands:
Any sensor command can be used as a task. Common ones:
| Task Command | Description |
|---|---|
os_version | Get OS details |
mem_map --pid [pid] | Memory map of process |
mem_strings --pid [pid] | Strings from process memory |
file_get [path] | Get file contents |
dir_list [path] | List directory |
netstat | Network connections |
run --shell-command [cmd] | Execute shell command |
deny_tree -p [process] | Kill process tree |
isolate_network | Network isolation |
rejoin_network | End network isolation |
After reliable tasking, wait at least 2 minutes for responses to arrive, then query:
First, generate the LCQL query:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: generate_lcql_query
- Parameters: {
\"oid\": \"[oid]\",
\"query\": \"Find all events in the last 2 hours where investigation_id contains 'fleet-inventory-2024-01'\"
}
- Return: RAW"
)
Then run the query:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: run_lcql_query
- Parameters: {
\"oid\": \"[oid]\",
\"query\": \"[generated_query]\",
\"limit\": 1000
}
- Return: RAW"
)
For automated response handling, create a D&R rule that matches the investigation_id.
CRITICAL: Create the D&R rule BEFORE creating the reliable task. Online sensors may respond within milliseconds - if the rule doesn't exist yet, those responses will be missed.
Step 1: Generate the detection:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: generate_dr_rule_detection
- Parameters: {
\"oid\": \"[oid]\",
\"description\": \"Match events where investigation_id contains 'fleet-inventory-2024-01'\"
}
- Return: RAW"
)
Step 2: Generate the response:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: generate_dr_rule_respond
- Parameters: {
\"oid\": \"[oid]\",
\"description\": \"Report to output 'siem' and add detection 'FLEET_INVENTORY_RESPONSE'\"
}
- Return: RAW"
)
Step 3: Validate the rule:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: validate_dr_rule_components
- Parameters: {
\"oid\": \"[oid]\",
\"detection\": [detection_yaml],
\"response\": [response_yaml]
}
- Return: RAW"
)
Step 4: Deploy with expiry:
Calculate expiry timestamp (e.g., 7 days from now):
date -d '+7 days' +%s
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: set_dr_general_rule
- Parameters: {
\"oid\": \"[oid]\",
\"name\": \"temp-fleet-inventory-handler\",
\"detection\": [detection_yaml],
\"response\": [response_yaml],
\"is_enabled\": true,
\"ttl\": [expiry_timestamp]
}
- Return: RAW"
)
Step 5: NOW create the reliable task
Only after the D&R rule is deployed, create the reliable task (see Step 3B above). The rule will catch all responses as sensors execute the task.
List pending tasks:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: list_reliable_tasks
- Parameters: {\"oid\": \"[oid]\"}
- Return: RAW"
)
Delete/cancel a task:
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: delete_reliable_task
- Parameters: {
\"oid\": \"[oid]\",
\"task_id\": \"[task_id]\"
}
- Return: RAW"
)
User: "Get running processes from sensor abc-123"
# Check if online
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: is_online
- Parameters: {\"oid\": \"c7e8f940-...\", \"sid\": \"abc-123\"}
- Return: RAW"
)
# If online, get processes directly
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: get_processes
- Parameters: {\"oid\": \"c7e8f940-...\", \"sid\": \"abc-123\"}
- Return: RAW"
)
User: "Get OS version from all Windows servers when they come online"
# Create reliable task with context for later collection
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: reliable_tasking
- Parameters: {
\"oid\": \"c7e8f940-...\",
\"task\": \"os_version\",
\"selector\": \"plat==windows\",
\"context\": \"os-inventory-20240120\"
}
- Return: RAW"
)
Response to user: "Created reliable task to collect OS version from all Windows sensors.
User: "Run memory collection on all hosts tagged 'incident-response', I need the data sent to our SIEM"
# Step 1: Create D&R rule FIRST to forward responses to SIEM
# (Use detection-engineering skill or manual D&R creation)
# Rule should match: routing/investigation_id contains "ir-memcollect-001"
# Response should: report to SIEM output
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: set_dr_general_rule
- Parameters: {
\"oid\": \"c7e8f940-...\",
\"name\": \"temp-ir-memcollect-handler\",
\"detection\": {\"op\": \"contains\", \"path\": \"routing/investigation_id\", \"value\": \"ir-memcollect-001\"},
\"response\": [{\"action\": \"report\", \"name\": \"IR_MEMCOLLECT_RESPONSE\", \"to\": \"siem\"}],
\"is_enabled\": true,
\"ttl\": 172800
}
- Return: RAW"
)
# Step 2: THEN create reliable task (rule is now in place to catch responses)
Task(
subagent_type="lc-essentials:limacharlie-api-executor",
model="haiku",
prompt="Execute LimaCharlie API call:
- Function: reliable_tasking
- Parameters: {
\"oid\": \"c7e8f940-...\",
\"task\": \"mem_map --pid 4\",
\"selector\": \"incident-response in tags\",
\"context\": \"ir-memcollect-001\",
\"ttl\": 172800
}
- Return: RAW"
)
User: "What's the OS version on all 5 of our production Linux servers?"
If sensors are online and small in number, parallel direct tasking is faster:
# Spawn parallel tasks for each sensor
Task(subagent_type="lc-essentials:limacharlie-api-executor", prompt="get_os_version for sid1...")
Task(subagent_type="lc-essentials:limacharlie-api-executor", prompt="get_os_version for sid2...")
Task(subagent_type="lc-essentials:limacharlie-api-executor", prompt="get_os_version for sid3...")
Task(subagent_type="lc-essentials:limacharlie-api-executor", prompt="get_os_version for sid4...")
Task(subagent_type="lc-essentials:limacharlie-api-executor", prompt="get_os_version for sid5...")
WARNING: Sensor tasking only works for EDR agents (real endpoint agents). Cloud sensors, adapters, and USP log sources cannot receive tasks.
Taskable sensors require BOTH conditions:
usp_adapter (code 9)Platforms that support tasking:
| Platform | Platform ID (hex) | Platform ID (decimal) | Selector |
|---|---|---|---|
| Windows | 0x10000000 | 268435456 | plat==windows |
| Linux | 0x20000000 | 536870912 | plat==linux |
| macOS | 0x30000000 | 805306368 | plat==macos |
| Chrome | Architecture 0x00000006 | 6 | arch==chromium |
Non-taskable sensors include:
ext-* sensors like ext-zeek, ext-strelka)arch=usp_adapter (architecture code 9) - even if platform is Linux/macOSThese sensors will return UNSUPPORTED_FOR_PLATFORM errors when tasked.
Recommendation: When tasking a fleet, filter by both platform AND architecture:
(plat==windows or plat==linux or plat==macos) and arch!=usp_adapterplatform and arch fields before direct taskingReliable tasking requires the ext-reliable-tasking extension to be subscribed in the organization. If you get a 403 error, the extension may not be enabled.
Selectors use bexpr syntax:
plat==windows - Windows sensorsplat==linux - Linux sensorsproduction in tags - Sensors with 'production' taghostname matches '^web-' - Hostname starts with 'web-'sid=='abc-123-def-456' - Specific sensor* - All sensorsThe context parameter in reliable tasking:
routing/investigation_id of response eventsWhen setting TTL or expiry:
date -d '+7 days' +%slimacharlie-call - For function documentation and direct API operationsdetection-engineering - For creating D&R rules to handle responsessensor-health - For checking sensor online status across fleetsensor-coverage - For understanding fleet coverage before taskingThis skill should be used when the user asks about libraries, frameworks, API references, or needs code examples. Activates for setup questions, code generation involving libraries, or mentions of specific frameworks like React, Vue, Next.js, Prisma, Supabase, etc.