splunk-mcp-guard
Provides a security proxy for Splunk MCP servers, enforcing least-privilege policies on AI assistant access: checks account capabilities, inspects SPL searches, blocks destructive commands, requires human approval for write actions, and logs all decisions.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@splunk-mcp-guardsearch for failed login attempts in the last hour"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
splunk-mcp-guard
A security proxy between AI assistants and Splunk. It sits in front of any Splunk MCP server and decides, for every call, whether the assistant may run it.
Not affiliated with Splunk LLC or Cisco. It adds a layer on top of Splunk RBAC; it does not replace it.
The problem
Splunk MCP servers connect with a single Splunk account. Whatever that account can do, the AI assistant can do, and so can everyone who uses the assistant. One search tool that accepts raw SPL is enough to run | delete, | collect or | sendemail.
The guard stops three things that go wrong in practice:
Situation | What the guard does |
The service account has more rights than it should | Checks the account at startup and refuses to run if it holds |
The model makes a mistake or is manipulated by text in the logs | Inspects every search and blocks destructive commands; write actions need a human to approve them |
A user asks for data outside their scope | Maps each person to a role with its own tools and indexes; the request is denied, logged, and repeated attempts raise an alert |
Related MCP server: Splunk MCP for SOC Operations
How it works
Each call passes four checks: identity → role, tool class, SPL inspection and human approval. If any check fails, the client gets an error and nothing reaches Splunk. Calls that pass go to the real MCP server. Results come back as untrusted data, pass through the output guard, and every decision goes to the audit log.
Quick start
Requirements: Python 3.10+, a working Splunk MCP server (tested with deslicer/mcp-for-splunk), and an MCP client such as Claude Desktop.
1. Install
git clone https://github.com/mehmetkadir-crk/splunk-mcp-guard.git
cd splunk-mcp-guard
python -m venv .venv
source .venv/bin/activate # Windows: .\.venv\Scripts\Activate.ps1
pip install -e .2. Create a least-privilege Splunk account
In Splunk Web:
Settings → Roles → New Role: name it
mcp_reader, inherit onlyuser, add no capabilities.Settings → Users → New User: name it
mcp_svcand assign onlymcp_reader.
Use this account for both the MCP server and the guard. With an admin account the guard refuses to start. That refusal is intended.
3. Run the setup
splunk-mcp-guard initIt asks a few questions (profile, Splunk address, service account, how your MCP server is started, which indexes to allow), then:
checks the Splunk account and stops if it is over-privileged,
creates
~/.splunk-mcp-guard/with your own copy of the policy, the audit log and the approval folder,finds the Claude Desktop config (including the Microsoft Store build), backs it up and adds the guard,
offers to remove any Splunk MCP server in the same config that would let the model bypass the guard.
You do not type any file paths except the one that starts your MCP server. For other MCP clients, run splunk-mcp-guard init --print and paste the block it prints. To configure everything by hand instead, see the configuration reference.
4. Verify
Fully quit and reopen Claude Desktop, then ask it to list your Splunk indexes. The result should carry a _guard notice, and ~/.splunk-mcp-guard/guard-audit.jsonl should show a preflight line with ok: true. Then ask it to run index=main | delete. The guard should reject it.
To change which tools or indexes are allowed later, edit the policy file that init printed and restart the client.
Example: tested on a live Splunk
Real screenshots from a fresh install (cloned from this repository, set up with splunk-mcp-guard init, strict profile). The client is Claude Desktop, the backend is deslicer/mcp-for-splunk, and Splunk Enterprise uses the least-privilege mcp_svc account.
1. Listing indexes is allowed. The call goes through, and the result comes back tagged as untrusted data.

The list also shows internal index names such as
_internal, because the model asked for them (include_internal: true). The names are visible, but searching those indexes is blocked by the role's index scope.
2. index=main | delete is blocked. The model asked for confirmation first and was told to go ahead. The guard still refused, and Splunk's own parser refused as well. Nothing in main was touched.

3. Every decision is in the audit log. From top to bottom: startup check passed with mcp_svc (role mcp_reader, no forbidden capabilities), list_indexes allowed, delete denied with both reasons.

{"kind": "decision", "principal": "kadir", "role": "analyst", "tool": "run_splunk_search",
"decision": "inspect-deny",
"reason": "splunk parser rejected the query: Error in 'delete' command: You have insufficient privileges to delete events.; denied command(s): delete",
"args": {"earliest_time": "-24h", "latest_time": "now", "query": "search index=main | delete"},
"result_sha256": null}result_sha256: null means Splunk returned nothing: the search never ran. More tests are listed in docs/verification.md.
Try it yourself
After setup with the strict profile, ask your assistant to run these searches, for example "Run this Splunk search exactly: index=main | delete". The model may hesitate or ask for confirmation first; tell it to go ahead. Every row in the first table should come back as a [guard] search rejected error and appear in the audit log as inspect-deny.
Should be blocked
Search | Why it is dangerous | Guard's reason |
| Makes events unsearchable, cannot be undone |
|
| Writes data into another index |
|
| Overwrites a lookup table |
|
| Writes results to disk on the Splunk server |
|
| Sends data out of Splunk |
|
| Runs a hidden search for every result |
|
| Reads users and configuration through the REST API |
|
| Runs a script on the Splunk server |
|
| Hides a write inside a subsearch |
|
| Searches every index at once |
|
| Index outside the role's scope |
|
| Reaches further back than the policy allows (30 days) |
|
Should work
Search | Note |
| Normal read-only search |
| Failed logons per user |
| A search term at the start is not mistaken for a command |
|
|
Tools that should not be available in strict: ask the assistant to create an alert, create or delete a saved search, or manage apps. These tools are hidden, so the assistant will say it has no tool for that. With the engineer profile, creating an alert waits for your approval instead (see Approving write actions).
These cases are also automated tests (tests/test_readme_examples.py), so this list stays accurate.
Policy profiles
Profile | Use it for | Searches | Write actions | Delete actions |
Seeing what an existing setup actually does | allowed, logged | allowed, logged | allowed, logged | |
Analysts | inspected, command allowlist | blocked | blocked | |
Engineers who build searches and alerts | inspected | human approval | blocked |
If you already have an assistant connected to Splunk, start with audit-only, review the log, then switch to strict or engineer.
Approving write actions
When a tool needs approval, the guard first asks through the MCP client. Many clients, Claude Desktop included, cannot show that prompt yet. In that case the guard waits up to 120 seconds for approval from a terminal:
splunk-mcp-guard pending # list what is waiting, with its id
splunk-mcp-guard approve <id> # or: reject <id>If nobody approves in time, the answer is no. Keep the approval directory where the assistant's own tools cannot write.
Limitations
It cannot see inside a saved search, so running saved searches is blocked in
strictand needs approval inengineer.Secret redaction and prompt-injection detection use patterns. They make cheap attacks harder but are not a guarantee.
In HTTP mode the guard does not authenticate users itself. Put an authenticating proxy in front of it.
Documentation
Configuration reference: policy format, SPL rules, approval modes, audit format, environment variables, CLI
Live verification: what was tested against a real Splunk instance and the results
Security policy: how to report a vulnerability
How it works: the reasoning behind each check, with FAQ · Flow diagram
Development
pip install -e ".[dev]"
pytestLicense
This server cannot be deployed
Maintenance
Related MCP Connectors
Security gateway for AI agents: policy, approval, and audited execution, no secrets shared.
Pre-spend firewall for AI agents. Approves, blocks, flags transactions against policy rules.
Supervised API-write gateway for AI agents with policy, human approval and execution receipts.
Runtime permission, approval, and audit layer for AI agent tool execution.
Related MCP Servers
- AlicenseBqualityAmaintenanceEnables AI agents to interact seamlessly with Splunk environments through 20+ tools for search, analytics, data discovery, administration, and health monitoring. Features AI-powered troubleshooting workflows and supports multiple Splunk instances with production-ready security.5727Apache 2.0
- AlicenseBqualityDmaintenanceEnables AI-driven SOC investigations by providing automated Splunk querying, threat intelligence enrichment, and response actions through natural language. Includes tools for IP pivoting, lateral movement detection, and label harvesting.311Apache 2.0
- AlicenseNot gradedqualityDmaintenanceA safety layer and monitoring copilot for AI agents using Splunk MCP, recording tool calls, enforcing policies, and blocking risky actions.MIT
- AlicenseNot gradedqualityCmaintenanceEnforces safety and governance for SQL queries executed by AI agents, providing read-only enforcement, cost estimation, and audit trails.Apache 2.0