Skip to main content

splunkguard-mcp

PyPI License: MIT Splunkbase #7931

A small Gemini-driven agent that drives the official Splunk MCP Server (Splunkbase App #7931) to answer natural-language questions about your Splunk data.

Ask "What CI pipelines failed last night and why?" or "Are there auth anomalies in the last 24 hours?" and get back a typed SplunkInvestigationReport with root cause, failure category, time range, affected components, and paste-ready SPL recommendations.

Extracted from the SplunkGuard hackathon project and packaged so other agents can use the same Splunk-MCP-over-Streamable-HTTP plumbing without dragging in the rest of that codebase.


Why this library exists

The Splunk MCP Server App is great but two things tripped us up when integrating it from Python:

  1. Transport mismatch. App #7931 v1.1.0 uses the modern MCP Streamable HTTP transport (per the MCP 2025-06-18 spec), not the older SSE transport. If you reach for mcp.client.sse.sse_client (the obvious one), you'll get HTTP 405 Method Not Allowed because Splunk's /services/mcp only accepts POST. You need mcp.client.streamable_http.streamablehttp_client.

  2. Self-signed cert handling. Local Splunk dev instances use self-signed TLS. The MCP SDK doesn't auto-honor an ssl.SSLContext you hand it — you need to inject a custom httpx_client_factory into the transport. We wire that for you.

This library handles both correctly out of the box.


Install

pip install splunkguard-mcp        # once published; for now:
pip install git+https://github.com/64johnlee/splunkguard-mcp

Python ≥ 3.10. Pulls google-genai, mcp, and httpx as deps.


Quick start

1. Spin up Splunk + the MCP Server App

docker run -d --name splunk \
  -p 8000:8000 -p 8088:8088 -p 8089:8089 \
  -e SPLUNK_PASSWORD=changeme \
  -e SPLUNK_GENERAL_TERMS=--accept-sgt-current-at-splunk-com \
  -e SPLUNK_START_ARGS=--accept-license \
  splunk/splunk:latest

# Install Splunkbase App #7931 (download .tgz after logging in at
# https://splunkbase.splunk.com/app/7931, then copy into the container):
docker cp splunk_mcp_server.tgz splunk:/tmp/
docker exec -u splunk splunk /opt/splunk/bin/splunk install app \
  /tmp/splunk_mcp_server.tgz -auth admin:changeme

# IMPORTANT: restart the *container*, not splunkd. `splunk restart` in
# Docker kills splunkd but never re-spawns it; `docker restart` does.
docker restart splunk

# Generate the MCP token:
curl -sk -u admin:changeme -X POST \
  "https://localhost:8089/services/mcp_token?username=admin&action=rotate"
TOKEN=$(curl -sk -u admin:changeme \
  "https://localhost:8089/services/mcp_token?username=admin&action=get" \
  | python3 -c "import json,sys;print(json.load(sys.stdin)['token'])")
echo "$TOKEN"   # use this as SPLUNK_MCP_TOKEN below

2. Investigate via the CLI

export GEMINI_API_KEY=...                # https://aistudio.google.com
export SPLUNK_MCP_TOKEN="$TOKEN"

splunkguard-mcp investigate \
  "What CI pipelines failed in the last 30 days?" \
  --earliest -30d \
  --no-verify-ssl

3. Or use the Python API

import asyncio
from splunkguard_mcp import SplunkInvestigator

agent = SplunkInvestigator(
    gemini_api_key="...",
    splunk_token="...",
    splunk_url="https://localhost:8089/services/mcp",
    verify_ssl=False,                         # local dev with self-signed cert
)
report = asyncio.run(agent.investigate(
    "What CI pipelines failed last night and why?",
    earliest="-24h",
    latest="now",
))
print(report.root_cause)
for a in report.recommended_actions:
    print(f"  - {a.action} (confidence: {a.confidence})")
    print(f"    SPL: {a.spl_query}")

4. Or just the raw MCP client (BYO LLM)

import asyncio
from splunkguard_mcp import SplunkMCPClient

async def main():
    async with SplunkMCPClient(splunk_token="...", verify_ssl=False) as c:
        tools = await c.list_tools()
        for t in tools:
            print(t.name, "—", t.description[:80])
        out = await c.call_tool(
            "splunk_run_query",
            {"query": "search index=_internal | head 5"},
        )
        print(out)

asyncio.run(main())

Benchmark

End-to-end on a local Splunk Enterprise 10.4.0 (Docker splunk/splunk:latest) + Splunkbase App #7931 v1.1.0 + Gemini 2.5 Flash (Google AI Studio, free tier):

Stage Wall-clock Notes
Investigate via MCP (agentic loop, 2 tool calls) ~38 s Gemini autonomously called get_indexes then splunk_run_query; returned structured report with 3 SPL recommendations
Investigate via direct Splunk REST API (1 Gemini call) ~8.5 s Available in the parent project as the --direct path

The MCP path is roughly 4× slower than direct REST because it gives Gemini real tool-call latency budget to iterate; the trade-off is deeper, more specific findings (specific failing-job names, is_ongoing inference, more SPL recommendations).


What's in the package

splunkguard_mcp/
├── __init__.py        — public API: SplunkInvestigator, SplunkMCPClient,
│                        SplunkInvestigationReport, RecommendedAction
├── __main__.py        — `python -m splunkguard_mcp investigate "<question>"`
├── client.py          — SplunkMCPClient: async context manager that
│                        connects via Streamable HTTP + custom httpx factory
├── agent.py           — SplunkInvestigator: Gemini tool-call loop +
│                        FunctionDeclaration translation + structured-output parsing
├── models.py          — dataclasses: SplunkInvestigationReport,
│                        RecommendedAction
└── prompts.py         — system prompt + user-turn template

Gotchas (verified the hard way)

Symptom Cause Fix
HTTP 405 Method Not Allowed from /services/mcp Used SSE transport instead of Streamable HTTP Use mcp.client.streamable_http.streamablehttp_client (this library does)
Failed to decode bearer token Used Authorization: Bearer <token> with a non-encrypted token Use Authorization: Splunk <encrypted-token> (the token returned by /services/mcp_token?action=get)
splunkd dies and never restarts after splunk install app splunk restart inside Docker kills splunkd but doesn't re-spawn it docker restart splunk instead — Docker's entrypoint script handles boot correctly
verify_ssl=False is ignored, TLS still fails The MCP SDK doesn't auto-honor a standalone ssl.SSLContext This library injects a custom httpx_client_factory — verify_ssl=False actually takes effect

License

MIT — see LICENSE.


Metadata

Release files for splunkguard-mcp 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for splunkguard-mcp 0.1.0
File Size Uploaded Provenance Actions
splunkguard_mcp-0.1.0.tar.gz 11.5 kB Without provenance Details for splunkguard_mcp-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for splunkguard-mcp 0.1.0
File Interpreter ABI Platform Actions
splunkguard_mcp-0.1.0-py3-none-any.whl Python 3 none any Details for splunkguard_mcp-0.1.0-py3-none-any.whl

Total release size: 26.5 kB

Release files / splunkguard_mcp-0.1.0.tar.gz

Download URL splunkguard_mcp-0.1.0.tar.gz
Size 11.5 kB
Tags Source
SHA-256 checksum
How to use checksums
f466f69d84fd7c040a409516ab0bec3f2b70bc279b317a8c16948e4757a5e6c6
BLAKE2b-256 checksum
How to use checksums
0fbf22e2581bc5c0edfcded5dfd518626677cc111cce12ac710491e9cf80b16d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release files / splunkguard_mcp-0.1.0-py3-none-any.whl

Download URL splunkguard_mcp-0.1.0-py3-none-any.whl
Size 15.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9b383148d51d28ccf0198655844ea674fe993426c56db98fd9ebad904118ace2
BLAKE2b-256 checksum
How to use checksums
5b0fd2e14915ff73d51284a7ea34c9f83f2ea9dfd298537da6bcd9b4814fd00f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Security for splunkguard-mcp 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page