Claude Code Plugins

Community-maintained marketplace

Feedback

adapter-assistant

@refractionPOINT/lc-ai
1
0

Complete adapter lifecycle assistant for LimaCharlie. Supports External Adapters (cloud-managed), Cloud Sensors (SaaS/cloud integrations), and On-prem USP adapters. Dynamically researches adapter types from local docs and GitHub usp-adapters repo. Creates, validates, deploys, and troubleshoots adapter configurations. Handles parsing rules (Grok, regex), field mappings, credential setup, and multi-adapter configs. Use when setting up new data sources (Okta, S3, Azure Event Hub, syslog, webhook, etc.), troubleshooting ingestion issues, or managing adapter deployments.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name adapter-assistant
description Complete adapter lifecycle assistant for LimaCharlie. Supports External Adapters (cloud-managed), Cloud Sensors (SaaS/cloud integrations), and On-prem USP adapters. Dynamically researches adapter types from local docs and GitHub usp-adapters repo. Creates, validates, deploys, and troubleshoots adapter configurations. Handles parsing rules (Grok, regex), field mappings, credential setup, and multi-adapter configs. Use when setting up new data sources (Okta, S3, Azure Event Hub, syslog, webhook, etc.), troubleshooting ingestion issues, or managing adapter deployments.
allowed-tools Task, Read, Bash, WebFetch, WebSearch, Glob, Grep, AskUserQuestion, Skill

Adapter Assistant

IMPORTANT: Never call mcp__plugin_lc-essentials_limacharlie__lc_call_tool directly. Always use the Task tool with subagent_type="lc-essentials:limacharlie-api-executor".

CRITICAL - LCQL Queries: NEVER write LCQL queries manually. ALWAYS use generate_lcql_query first, then run_lcql_query. See Critical Requirements for all mandatory workflows.

A comprehensive, dynamic assistant for LimaCharlie adapter lifecycle management. This skill researches adapter configurations from multiple sources and helps you create, validate, deploy, and troubleshoot adapters for any data source.

When to Use

Use this skill when:

  • Setting up new data sources: Connect syslog, webhooks, cloud services, or any external data to LimaCharlie
  • Configuring SaaS integrations: Okta, CrowdStrike, Microsoft Defender, Office 365, AWS, Azure, etc.
  • Troubleshooting adapters: Data not flowing, parsing issues, credential problems
  • Modifying existing adapters: Update parsing rules, change credentials, add field mappings
  • Auditing adapters: List and review adapters across organizations
  • Connecting unknown products: Research how to integrate any product that sends logs or webhooks

Common scenarios:

  • "I want to ingest Okta system logs"
  • "Set up a syslog adapter for our firewall"
  • "My Azure Event Hub adapter isn't receiving data"
  • "How do I connect this product that sends webhooks?"
  • "Create a webhook to receive alerts from our monitoring system"
  • "List all adapters across my organizations"
  • "Help me parse these custom log formats"

What This Skill Does

This skill is truly dynamic - it researches adapter configurations from multiple sources in real-time:

  1. Local LimaCharlie documentation - Adapter types, configuration options, examples
  2. GitHub usp-adapters repository - Source code for 50+ adapter implementations
  3. External product documentation - API docs, webhook formats, authentication requirements

The skill then guides you through creating, validating, and deploying adapter configurations with proper parsing rules and credential management.

Supported Adapter Categories

Category Description Examples
External Adapter Cloud-managed syslog, webhook, or API receivers syslog, webhook, custom API
Cloud Sensor Cloud-to-cloud SaaS integrations Okta, CrowdStrike, O365, AWS S3, Azure Event Hub
On-prem/USP Adapter Binary deployments with local configuration file, syslog receiver, Kubernetes pods

Dynamic Research Strategy

This is the key capability - the skill researches ANY data source dynamically, not just predefined ones.

For ANY Data Source Request:

Step 1: Check for Native LimaCharlie Adapter

Search local documentation:

Glob("./docs/limacharlie/doc/Sensors/Adapters/Adapter_Types/*{keyword}*.md")

Check GitHub usp-adapters repository (use API at root - adapters are NOT in a subdirectory):

WebFetch(
  url="https://api.github.com/repos/refractionPOINT/usp-adapters/contents",
  prompt="List all available adapter directories from the JSON response"
)

Step 2: Read LimaCharlie Adapter Documentation

If a native adapter exists:

Read("./docs/limacharlie/doc/Sensors/Adapters/Adapter_Types/adapter-types-{name}.md")

For advanced configuration options, first list files in the adapter directory, then fetch the main source:

# Step 1: List files to find the main config file
WebFetch(
  url="https://api.github.com/repos/refractionPOINT/usp-adapters/contents/{adapter}",
  prompt="List all .go files in this adapter directory"
)

# Step 2: Fetch the config (usually client.go, but some adapters differ - e.g., sentinelone uses s1.go)
WebFetch(
  url="https://raw.githubusercontent.com/refractionPOINT/usp-adapters/master/{adapter}/client.go",
  prompt="Extract all configuration fields from the Config struct"
)

Step 3: Research the External Product

ALWAYS research the external product to understand its capabilities:

WebSearch("{product name} API documentation")
WebSearch("{product name} webhook integration")
WebSearch("{product name} audit logs export")

Extract:

  • Authentication method (API key, OAuth, service account, etc.)
  • Available event types or log categories
  • Webhook payload format (if applicable)
  • Rate limits and API best practices
  • Required scopes or permissions

Step 4: Build Comprehensive Integration Plan

If NO native adapter exists, determine how to connect:

  • Can it send webhooks? → LimaCharlie webhook adapter
  • Does it write to S3/GCS/Azure Blob? → Cloud storage adapters
  • Does it push to Kafka/Pub/Sub/SQS? → Queue adapters
  • Can we pull via API? → May need polling or custom integration

Then map out:

  • External product configuration requirements
  • Matching LimaCharlie adapter configuration
  • Parsing requirements for the data format
  • Sample data format for validation

Workflow Phases

Phase 0: Requirements Gathering

Use AskUserQuestion to understand the user's needs:

  1. Operation type: Create new adapter, modify existing, troubleshoot, or audit
  2. Data source: What product/system are they connecting?
  3. Adapter category preference: Cloud-managed or on-prem deployment

Phase 1: Dynamic Research

Execute the dynamic research strategy above to gather all relevant information about:

  • LimaCharlie adapter capabilities
  • External product API/webhook specifications
  • Configuration requirements on both sides

Phase 2: Organization and Configuration Discovery

Get organizations:

Task(
  subagent_type="lc-essentials:limacharlie-api-executor",
  model="haiku",
  prompt="Execute LimaCharlie API call:
    - Function: list_user_orgs
    - Parameters: {}
    - Return: RAW"
)

List existing External Adapters:

Task(
  subagent_type="lc-essentials:limacharlie-api-executor",
  model="haiku",
  prompt="Execute LimaCharlie API call:
    - Function: list_external_adapters
    - Parameters: {\"oid\": \"<org-id>\"}
    - Return: RAW"
)

List existing Cloud Sensors:

Task(
  subagent_type="lc-essentials:limacharlie-api-executor",
  model="haiku",
  prompt="Execute LimaCharlie API call:
    - Function: list_cloud_sensors
    - Parameters: {\"oid\": \"<org-id>\"}
    - Return: RAW"
)

Get existing configuration (if modifying):

Task(
  subagent_type="lc-essentials:limacharlie-api-executor",
  model="haiku",
  prompt="Execute LimaCharlie API call:
    - Function: get_external_adapter  # or get_cloud_sensor
    - Parameters: {\"oid\": \"<org-id>\", \"adapter_name\": \"<adapter-name>\"}  # use sensor_name for get_cloud_sensor
    - Return: RAW"
)

Phase 3: Configuration Generation

Build the configuration based on research:

Core client_options (required for all adapters):

client_options:
  identity:
    oid: "<organization-id>"
    installation_key: "<installation-key>"  # or use hive://secret/...
  platform: "text|json|carbon_black|gcp|..."
  sensor_seed_key: "<unique-identifier>"
  hostname: "<adapter-hostname>"
  mapping:
    parsing_grok:
      message: '%{PATTERN:field} ...'  # For text platform
    event_type_path: "field/path"
    event_time_path: "timestamp/path"
    sensor_hostname_path: "host/path"

Credential references (recommended):

Use Hive secrets for sensitive values:

apikey: "hive://secret/okta-api-key"
client_secret: "hive://secret/azure-client-secret"

Check existing secrets:

Task(
  subagent_type="lc-essentials:limacharlie-api-executor",
  model="haiku",
  prompt="Execute LimaCharlie API call:
    - Function: list_secrets
    - Parameters: {\"oid\": \"<org-id>\"}
    - Return: RAW"
)

Indexing configuration (optional):

indexing:
  - events_included: ["*"]
    path: "src_ip"
    index_type: "ip"
  - events_included: ["*"]
    path: "user/email"
    index_type: "user"

Supported index types: file_hash, file_path, file_name, domain, ip, user, service_name, package_name

Phase 4: Validation and Testing

Validate parsing rules before deployment:

Task(
  subagent_type="lc-essentials:limacharlie-api-executor",
  model="haiku",
  prompt="Execute LimaCharlie API call:
    - Function: validate_usp_mapping
    - Parameters: {
        \"oid\": \"<org-id>\",
        \"platform\": \"text\",
        \"mapping\": {
          \"parsing_grok\": {
            \"message\": \"%{TIMESTAMP_ISO8601:timestamp} %{WORD:action} ...\"
          },
          \"event_type_path\": \"action\",
          \"event_time_path\": \"timestamp\"
        },
        \"text_input\": \"<sample-log-lines>\"
      }
    - Return: RAW"
)

Review validation results:

  • Verify all expected fields are extracted
  • Check timestamp parsing
  • Confirm event type assignment
  • Iterate on pattern if validation fails

For complex parsing, invoke the parsing-helper skill:

Skill("parsing-helper")

For local testing before production deployment:

Skill("test-limacharlie-adapter")

Phase 5: Deployment

Deploy External Adapter:

Task(
  subagent_type="lc-essentials:limacharlie-api-executor",
  model="haiku",
  prompt="Execute LimaCharlie API call:
    - Function: set_external_adapter
    - Parameters: {
        \"oid\": \"<org-id>\",
        \"adapter_name\": \"<adapter-name>\",
        \"adapter_config\": {<full-configuration-including-adapter_type>}
      }
    - Return: RAW"
)

Deploy Cloud Sensor:

Task(
  subagent_type="lc-essentials:limacharlie-api-executor",
  model="haiku",
  prompt="Execute LimaCharlie API call:
    - Function: set_cloud_sensor
    - Parameters: {
        \"oid\": \"<org-id>\",
        \"sensor_name\": \"<sensor-name>\",
        \"sensor_config\": {<full-configuration>}
      }
    - Return: RAW"
)

For On-prem Adapters, generate deployment artifacts:

YAML Configuration:

syslog:
  client_options:
    identity:
      installation_key: "<IID>"
      oid: "<OID>"
    platform: text
    sensor_seed_key: "<unique-key>"
    hostname: "<hostname>"
    mapping:
      parsing_grok:
        message: '%{PATTERN:field} ...'
      event_type_path: "..."
  port: 514
  is_udp: true

CLI Command:

./lc_adapter syslog \
  client_options.identity.installation_key=<IID> \
  client_options.identity.oid=<OID> \
  client_options.platform=text \
  client_options.sensor_seed_key=<key> \
  "client_options.mapping.parsing_grok.message=%{PATTERN:field} ..." \
  port=514 \
  is_udp=true

Docker Command:

docker run -d --rm -p 514:514/udp refractionpoint/lc-adapter syslog \
  client_options.identity.installation_key=<IID> \
  client_options.identity.oid=<OID> \
  client_options.platform=text \
  client_options.sensor_seed_key=<key> \
  port=514 \
  is_udp=true

Verify deployment:

Task(
  subagent_type="lc-essentials:limacharlie-api-executor",
  model="haiku",
  prompt="Execute LimaCharlie API call:
    - Function: list_sensors
    - Parameters: {\"oid\": \"<org-id>\", \"selector\": \"iid == `<installation-key-iid>`\"}
    - Return: RAW"
)

Phase 6: Post-Deployment

Troubleshoot if data not appearing:

  1. Check adapter last_error field:
Task(
  subagent_type="lc-essentials:limacharlie-api-executor",
  model="haiku",
  prompt="Execute LimaCharlie API call:
    - Function: get_external_adapter
    - Parameters: {\"oid\": \"<org-id>\", \"adapter_name\": \"<adapter-name>\"}
    - Return: RAW"
)
  1. Verify sensor exists in sensor list

  2. Query for recent events:

# First calculate timestamps dynamically
start=$(date -d '1 hour ago' +%s) && end=$(date +%s)

Task(
  subagent_type="lc-essentials:limacharlie-api-executor",
  model="haiku",
  prompt="Execute LimaCharlie API call:
    - Function: get_historic_events
    - Parameters: {\"oid\": \"<org-id>\", \"sid\": \"<sensor-id>\", \"start\": <start-epoch>, \"end\": <end-epoch>, \"limit\": 10}
    - Return: RAW"
)
  1. Check for unparsed events (event_type: "unknown_event" with only text field)

Offer D&R rule creation:

Skill("detection-engineering")

Multi-Organization Adapter Audit

For auditing adapters across multiple organizations, spawn parallel sub-agents:

Task(
  subagent_type="lc-essentials:multi-org-adapter-auditor",
  model="haiku",
  prompt="Audit adapters for organization: {org_name} ({oid})

    Return:
    - List of external adapters with status
    - List of cloud sensors with status
    - Any adapters with errors
    - Configuration issues detected"
)

Adapter Type Quick Reference

Adapter Type Platform Deployment Key Configuration
syslog text External/On-prem port, is_udp, parsing_grok
webhook json Cloud Sensor secret, client_options
okta json Cloud Sensor apikey, url
s3 varies Cloud Sensor/On-prem bucket_name, access_key, secret_key, prefix
azure_event_hub varies Cloud Sensor/On-prem connection_string
office365 json Cloud Sensor tenant_id, client_id, client_secret
crowdstrike / falconcloud json Cloud Sensor/On-prem client_id, client_secret
google_cloud_pubsub varies Cloud Sensor/On-prem project_id, subscription_id
file varies On-prem file_path, backfill

Example Usage

Example 1: Set Up Okta System Log Adapter

User: "I want to ingest Okta system logs into LimaCharlie"

Workflow:

  1. Research Phase:

    • Read local docs: ./docs/limacharlie/doc/Sensors/Adapters/Adapter_Types/adapter-types-okta.md
    • WebSearch: "Okta System Log API documentation 2024"
    • Extract: API key requirements, URL format, event types
  2. Configuration:

    sensor_type: "okta"
    okta:
      apikey: "hive://secret/okta-api-key"
      url: "https://your-company.okta.com"
      client_options:
        identity:
          oid: "<oid>"
          installation_key: "<iid>"
        hostname: "okta-system-logs"
        platform: "json"
        sensor_seed_key: "okta-logs-sensor"
        mapping:
          sensor_hostname_path: "client/device"
          event_type_path: "eventType"
          event_time_path: "published"
    
  3. External Setup Instructions:

    • Create API token in Okta Admin Console
    • Store token in LimaCharlie secrets: set_secret with name "okta-api-key"
  4. Deploy: Use set_cloud_sensor

Example 2: Syslog Adapter with Custom Grok Parsing

User: "Set up a syslog adapter for our firewall. Sample log: <134>Nov 15 12:30:45 fw01 ACCEPT TCP 192.168.1.100:54321 10.0.0.5:443"

Workflow:

  1. Analyze log format: Priority, syslog timestamp, hostname, action, protocol, src:port dst:port

  2. Generate Grok pattern:

    parsing_grok:
      message: '<%{INT:priority}>%{SYSLOGTIMESTAMP:timestamp} %{HOSTNAME:host} %{WORD:action} %{WORD:protocol} %{IP:src_ip}:%{NUMBER:src_port} %{IP:dst_ip}:%{NUMBER:dst_port}'
    
  3. Validate with validate_usp_mapping using the sample log

  4. Deploy as External Adapter:

    Task(
      subagent_type="lc-essentials:limacharlie-api-executor",
      model="haiku",
      prompt="Execute LimaCharlie API call:
        - Function: set_external_adapter
        - Parameters: {
            \"oid\": \"<oid>\",
            \"adapter_name\": \"firewall-syslog\",
            \"adapter_config\": {
              \"adapter_type\": \"syslog\",
              \"port\": 514,
              \"is_udp\": true,
              \"client_options\": {
                \"identity\": {\"oid\": \"<oid>\", \"installation_key\": \"<iid>\"},
                \"platform\": \"text\",
                \"sensor_seed_key\": \"firewall-logs\",
                \"hostname\": \"firewall-syslog\",
                \"mapping\": {
                  \"parsing_grok\": {
                    \"message\": \"<%{INT:priority}>%{SYSLOGTIMESTAMP:timestamp} %{HOSTNAME:host} %{WORD:action} %{WORD:protocol} %{IP:src_ip}:%{NUMBER:src_port} %{IP:dst_ip}:%{NUMBER:dst_port}\"
                  },
                  \"event_type_path\": \"action\",
                  \"event_time_path\": \"timestamp\",
                  \"sensor_hostname_path\": \"host\"
                }
              }
            }
          }
        - Return: RAW"
    )
    

Example 3: Connect Unknown Product via Webhook

User: "I want to connect this monitoring tool that sends webhooks, I don't know if LimaCharlie supports it"

Workflow:

  1. Ask clarifying questions:

    • What's the product name?
    • Do you have sample webhook payload?
  2. Research the product:

    WebSearch("{product name} webhook documentation")
    WebSearch("{product name} webhook payload format")
    
  3. Read LimaCharlie webhook adapter docs:

    Read("./docs/limacharlie/doc/Sensors/Adapters/Adapter_Types/adapter-types-webhook.md")
    
  4. Build integration plan:

    • LimaCharlie webhook adapter configuration
    • Grok/JSON parsing for the webhook payload
    • Field mappings for proper event normalization
  5. Deploy and provide webhook URL to user

Example 4: Troubleshoot Adapter Not Receiving Data

User: "My Azure Event Hub adapter isn't receiving data"

Workflow:

  1. Get current configuration:

    Task(
      subagent_type="lc-essentials:limacharlie-api-executor",
      model="haiku",
      prompt="Execute LimaCharlie API call:
        - Function: get_cloud_sensor
        - Parameters: {\"oid\": \"<oid>\", \"sensor_name\": \"azure-event-hub\"}
        - Return: RAW"
    )
    
  2. Check for errors in last_error field of sys_mtd

  3. Common issues:

    • Connection string missing EntityPath
    • Consumer group not created
    • Credentials expired
    • Diagnostic settings not configured in Azure
  4. Research Azure-side setup:

    WebSearch("Azure Event Hub diagnostic settings configuration")
    
  5. Provide fix guidance based on error analysis

Common Pitfalls

  1. Installation Key vs IID: For adapters, use the IID (UUID format like e9a3bcdf-efa2-47ae-b6df-579a02f3a54d), not the full base64 installation key

  2. DATESTAMP vs TIMESTAMP_ISO8601:

    • YYYY-MM-DD HH:MM:SS → Use %{TIMESTAMP_ISO8601}
    • MM-DD-YY HH:MM:SS → Use %{DATESTAMP}
    • Jan 15 12:30:45 → Use %{SYSLOGTIMESTAMP}
  3. Grok field name: Always use message as the key in parsing_grok for text platform:

    parsing_grok:
      message: '%{PATTERN:field}'  # Correct
    
  4. Azure Event Hub connection string: Must include EntityPath=<event-hub-name> for consumer applications

  5. Credential storage: Always use hive://secret/<secret-name> for sensitive values in production

  6. Unparsed events: If you see event_type: "unknown_event" with only a text field, parsing is not configured

  7. Timestamp calculations: Always use Bash to calculate epoch timestamps dynamically:

    start=$(date -d '1 hour ago' +%s) && end=$(date +%s)
    

Related Skills

  • parsing-helper - For complex Grok pattern generation and validation
  • lookup-lc-doc - For general LimaCharlie documentation lookup
  • limacharlie-call - For direct API operations
  • test-limacharlie-adapter - For local testing before production deployment
  • detection-engineering - For creating D&R rules on adapter data

Reference

For more details:

  • Adapter usage: ./docs/limacharlie/doc/Sensors/Adapters/adapter-usage.md
  • Adapter deployment: ./docs/limacharlie/doc/Sensors/Adapters/adapter-deployment.md
  • Adapter types: ./docs/limacharlie/doc/Sensors/Adapters/Adapter_Types/
  • GitHub source: https://github.com/refractionPOINT/usp-adapters