MCP
Expose the read-only tools and the investigate, triage, explain and generate capabilities to external agents (Claude Desktop, Cursor, custom). Streamable HTTP, tokens issued per role, the same gates and audit as the UI. Since 1.9.0.
The MCP server is a resident process that starts and stops with splunkd (bin/copilot_mcp_server.py, a scripted input with interval=-1). Off by default; the switch on MCP under Settings takes effect immediately.

Switch and address
| Item | Default | Notes |
|---|---|---|
| Enabled | off | On starts the process, off stops it |
| Bind | 127.0.0.1 | Loopback, 0.0.0.0 and ::1 only. MCP speaks plain HTTP, so tokens and results are not encrypted; for other machines a TLS reverse proxy in front is required, with access control on the proxy. A non-loopback bind logs a warning at startup |
| Port | 18100 | |
| Protocol | MCP Streamable HTTP | http://<bind>:<port>/mcp. GET /health is unauthenticated |
Search account
From 2.0.4 the index tools (run_spl, list_indexes, list_sourcetypes, get_fields) run as a low-privilege Splunk account, whose index permissions splunkd enforces.
| Step | Notes |
|---|---|
| Create the account | A new Splunk user with only copilot_use and read access to the indexes you want to expose to external agents |
| Create a token | A Splunk auth token for that account (the Tokens page under Settings in Splunk Web) |
| Enter it | Account name and token in the search account section on this page, then save. The token goes to storage/passwords; write-only, never shown back |
Without a search account these four tools return forbidden and never fall back to the system session; the knowledge-base, asset and LLM tools are unaffected.
Tokens and roles
Every request carries Authorization: Bearer rsk_…. Tokens are issued on this page; the plaintext is shown once and the KV store keeps a sha256 only. Revocation is immediate. A token is bound to a role tier and an issuer cannot issue above their own:
| Tier | Tools |
|---|---|
| viewer | list_indexes, list_sourcetypes, get_fields, run_spl, search_kb, lookup_asset, threat_intel, generate_spl, explain_event |
| analyst | Above plus investigate_alert, triage_alerts |
| admin | Same as analyst, reserved |
A missing, wrong or revoked token returns 401; an insufficient tier makes the tool return {"error":"forbidden"} (MCP has no per-tool 403). Rate limiting reuses [limits] rate_per_min and burst, per token.

Tools
| Tool | Notes |
|---|---|
list_indexes() | Indexes with event counts, allow-listed only |
list_sourcetypes(index) | Sourcetypes of an index |
get_fields(index, sourcetype) | Real field names from the last 24 h with masked samples |
run_spl(spl) | Read-only SPL, up to 20 rows, masked. delete, collect, outputlookup, sendemail, script, rest and similar are refused |
search_kb(query, k) | Runbook and knowledge-base retrieval, including synced Splunk objects |
lookup_asset(entity, kind) | Asset and identity context |
threat_intel(indicator, kind) | Threat intel. Egresses only with [threat_intel] configured |
generate_spl(question, index, sourcetype) | Natural language to read-only SPL, same engine as the home page |
explain_event(event, sourcetype) | Single-event explanation |
investigate_alert(alert, context, sourcetype) | Alert investigation (timeline, MITRE, impact, false-positive verdict) |
triage_alerts(alerts[], max_clusters) | Batch triage clustering and scoring |
Resources: copilot://kb/{id}, copilot://reports/latest. Prompt template: investigate.
Security boundary
| Item | Notes |
|---|---|
| Read-only | Every Splunk-side call goes through the read-only gate: the first command must be a read-only generating command, and write, notify, shell, map, macros, dbx*, fit, rest and similar are refused in every pipeline segment and subsearch; plus [limits] agentic_index_whitelist and [masking] mode |
| Licence and roles | Same as the UI. Paid tools without a licence return license_required |
| Audit | One audit event per call (via=mcp), filterable in Audit log |
| Session | The index tools run as the search account (above); the other tools run as splunk-system-user. That user is absent under a Splunk Free licence, so MCP gets no session there |
Connecting
Claude Desktop and Cursor (mcpServers):
{
"mcpServers": {
"splunk-ai-copilot": {
"url": "http://127.0.0.1:18100/mcp",
"headers": { "Authorization": "Bearer <TOKEN>" }
}
}
}Claude Code:
claude mcp add --transport http splunk-ai-copilot http://127.0.0.1:18100/mcp \
--header "Authorization: Bearer <TOKEN>"Troubleshooting
| Symptom | Action |
|---|---|
| Enabled but shown as not responding | Check index=_internal sourcetype=copilot:mcp or copilot_mcp_server in splunkd.log. Usual causes: the port is taken or splunk-system-user does not exist |
| Everything 401 | Token revoked, or the Bearer prefix is missing |
run_spl and similar return forbidden: no MCP search account is configured | Configure the search account on this page |
Tool returns forbidden | Tier too low; use an analyst token |
license_required | Not activated or licence expired |
refused: index … not in the allowed set | [limits] agentic_index_whitelist omits that index |
License
Which features need a licence, requesting a trial, online and offline activation, what the fingerprint is made of, how the sealed detection engine unlocks, and what each status means.
Preferences
The only item in the account menu. Language, theme, default index, rows per page, remembered column sets. Passwords are changed in Splunk.