Use secopsctl as a Model Context Protocol server to give AI agents — Claude Code, Claude Desktop, Cursor, Windsurf, or any MCP client — direct access to your Google SecOps (Chronicle SIEM + Siemplify SOAR) tenant.
The server uses dynamic tool loading: instead of exposing all 360+ commands upfront, it starts with 5 meta-tools and loads group-specific typed tools on demand. This keeps the agent's context window small while covering every command.
go install danny.vn/secops/cmd/secopsctl@latestOr download a pre-built binary from the releases page.
The MCP server reads the same config as the CLI. Run the interactive wizard:
secopsctl configThis writes ~/.secopsctl/instance.yaml (0600, git-ignored). You need up to
four identifiers — project ID, region, customer ID, and SOAR URL — plus
credentials for each plane:
- SIEM — Google ADC (minted in-process, nothing on disk)
- SOAR — a long-lived AppKey
SIEM alone gives a clean doctor — add SOAR whenever you need it. See
Configure & auth for the full walkthrough.
Verify connectivity:
secopsctl doctorFrom your project directory:
secopsctl mcp installThis writes an entry to .mcp.json in the current directory. Restart Claude
Code to pick up the new server.
Add to your claude_desktop_config.json:
{
"mcpServers": {
"secopsctl": {
"command": "secopsctl",
"args": ["mcp", "serve"]
}
}
}Ensure ~/.secopsctl/instance.yaml exists (from secopsctl config), or set
SECOPS_* environment variables in an env block.
Point your client at the stdio command:
secopsctl mcp serve
Ensure credentials are configured via ~/.secopsctl/instance.yaml or
environment variables.
The server exposes:
- Meta-tools —
help,run,focus,unfocus,usage(always loaded) - Group tools — loaded on demand via
focus(e.g.focus group="cases") - Resources — embedded craft guides (
tips://{name})
- Call
helpto discover available command groups - Call
help group="cases"to list subcommands in a group - Call
focus group="cases"to load typed tools (cases_list,cases_get, …) - Use the typed tools with full parameter schemas
- Call
unfocus group="cases"when done to free context - Use
runanytime for quick one-off commands without focusing - Use
usage command="search udm"to preview a schema and auto-load it
run— escape hatch for one-off commands. No schema validation. Use shell-style quoting for values with spaces:--filter 'event.type = "LOGIN"'.focus— the preferred path. Loads typed tools with validated parameters, descriptions, and enum hints. Prefer this for commands with filter expressions — typed parameters avoid quoting issues.usage— preview one command's schema and auto-load it as a callable tool, without loading the whole group.
You: How many open cases do we have?
The agent calls
run command="cases list --limit 0 --status OPEN"and returns the count.
You: Show me the latest 5 detection alerts.
The agent calls
focus group="alerts", thenalerts_listwithlimit=5.
You: Search for login events in the last 24 hours.
The agent calls
focus group="search", thensearch_udmwithargs="metadata.event_type = \"USER_LOGIN\""andhours=24.
All tool output is JSON. Mutations are dry-run by default — the agent must
pass yes=true to apply, same as the CLI.
MCP clients cap how big a tool result may be; an over-limit inline result is rejected wholesale and the data is lost. To avoid that, results larger than 64 KiB are written to a temporary file instead, and the tool returns a small JSON pointer:
{
"spilled": true,
"file": "/tmp/secopsctl-mcp/secopsctl-mcp-1234.json",
"bytes": 1048576,
"head": "…first 1 KiB preview…",
"message": "Output exceeded the 65536-byte inline limit; …"
}The agent reads or filters the file (e.g. with jq), or re-runs the command
with --limit / narrower filters. Spill files live under
$TMPDIR/secopsctl-mcp/ (mode 0600, directory 0700) and are swept after
24 hours. Set SECOPS_MCP_SPILL_BYTES to tune the inline threshold for
clients with different result caps.
- Two-plane auth. SIEM uses Google ADC (org-scoped OAuth); SOAR uses an AppKey. The MCP server inherits whatever credentials are configured.
- Dry-run by default. All mutations require
yes=true— the agent cannot accidentally modify your environment without explicit confirmation. - Read-only mode. Set
SECOPS_READONLY=1or pass--read-onlyto block all mutations at the transport level. - Local stdio only. No network listener is opened.
- Security flags enforced.
--read-only,--non-interactive, and--no-progressare forwarded unconditionally to subprocesses — callers cannot override them.