An independent, open-source bridge that exposes a Splunk Enterprise or Splunk Cloud REST endpoint as a Model Context Protocol (MCP) stdio server, with built-in SPL safety guardrails.
spl-bridge is not affiliated with, endorsed by, sponsored by, or certified by Splunk LLC or Cisco Systems, Inc. See Trademarks and independence below.
A small Python server that:
- Speaks the Model Context Protocol over stdio (JSON-RPC framed on stdout, logs on stderr).
- Calls the publicly documented Splunk management REST API (typically TCP 8089) using either a bearer token or, in lab-only password mode, a username/password.
- Enforces a project-curated SPL command allowlist, recursive subsearch validation through Splunk's own parser, row caps, and per-tool sliding-window rate limits.
The tool catalogue exposed to MCP clients wraps a small set of public Splunk REST endpoints (/services/server/info, /services/data/indexes, /services/authentication/users, /services/server/introspection/kvstore/collectionstats, /servicesNS/-/-/saved/searches, etc.) plus the SPL | metadata and | savedsearch generating commands. See spl_bridge/data/PROVENANCE.md for per-tool source-of-record citations.
The CLI exposes three subcommands: setup (interactive wizard), doctor (one-shot connectivity check), and serve (the stdio server, also the default).
Mac is the predominant developer target. Three commands take you from zero to a running setup wizard. Paste the whole block at once, or step through line by line — both work, and the wizard takes over interactively at the end.
brew install uv
uv tool install 'spl-bridge[keyring] @ git+https://github.com/jagalliers/spl-bridge.git'
spl-bridge setupWhat each command does:
brew install uv— installs the uv Python package manager from Homebrew. Pulls in any Python it needs as a transitive dependency; uv can also fetch its own managed Python on demand. Lands at/opt/homebrew/bin/uv, on the PATH that Cursor and Claude Desktop see at MCP-server spawn time (matters if you ever hand-roll auvx-based MCP config).uv tool install 'spl-bridge[keyring] @ git+...'— installsspl-bridgewith macOS Keychain support, isolated in its own uv-managed venv. Lands at~/.local/bin/spl-bridge. The same install pattern recommended by every official Python MCP server README (mcp-server-git, mcp-server-fetch, etc.).spl-bridge setup— runs the interactive wizard. It walks you through Splunk creds, secret storage (macOS Keychain by default), and MCP-host wiring (Cursor, Claude Desktop, or Claude CLI). Nothing is written to disk until the wizard's step 4.
After the wizard finishes, restart your MCP host (Cursor / Claude Desktop) so it picks up the new server.
- Don't have Homebrew? Either install it from brew.sh (recommended), or use the Astral installer:
curl -LsSf https://astral.sh/uv/install.sh | sh, then reopen your terminal. - Prefer
pipx?pipx install 'spl-bridge[keyring] @ git+https://github.com/jagalliers/spl-bridge.git'works the same way and is the PyPA-canonical alternative for installing Python CLI tools. - Already in an Anaconda env or a project venv? Plain
pip install 'spl-bridge[keyring] @ git+...'(oruv pip install ...) works there too — see Install for the long form, the why-this-URL explanation, and the dev install. spl-bridge: command not foundafter the install? Runuv tool update-shell, then open a new terminal. (uv typically prints this advice itself when needed, but the message can scroll past during the install.)
Requires Python 3.10 or newer. Confirm with
python3 --version. The macOS-bundled/usr/bin/python3is older than this; the Quick start (macOS) above usesuv, which can fetch a managed Python interpreter on demand (and otherwise re-uses Homebrew Python if present). Other options for getting a modern Python without uv:pyenv,pipx(via Homebrew Python), orbrew install pythondirectly.
For the fastest path on macOS, see Quick start (macOS) above. The rest of this section covers the why and the long-form options.
The minimum install is one line:
pip install 'spl-bridge @ git+https://github.com/jagalliers/spl-bridge.git'That gives you the server, the doctor connectivity check, and the setup wizard. By itself, secrets land in a 0600 dotfile under ~/Library/Application Support/spl-bridge/ (macOS), %LOCALAPPDATA%\spl-bridge\ (Windows), or ~/.config/spl-bridge/ (Linux). The dotfile is protected by filesystem permissions only — it is not encrypted at rest.
For OS-keychain storage instead — macOS Keychain, Windows Credential Manager, Linux Secret Service / KWallet — install with the optional keyring add-on:
pip install 'spl-bridge[keyring] @ git+https://github.com/jagalliers/spl-bridge.git'What's with the
git+https://..., the[keyring], and the quotes?
git+https://github.com/jagalliers/spl-bridge.gitis the URL form becausespl-bridgeis not yet published to PyPI. Until it is, pip has to fetch the wheel directly from this repository. Thename @ urlsyntax is standard PEP 508 — it tells pip "install the package calledspl-bridgefrom this URL" and is supported by every pip released since 2019. Once we publish to PyPI, the URL fragment goes away and these commands shorten topip install spl-bridgeandpip install 'spl-bridge[keyring]'.[keyring]is pip's syntax for an optional dependency group (declared in ourpyproject.toml). It tells pip "installspl-bridgeplus the Pythonkeyringlibrary, which is the standard cross-platform shim that talks to your OS credential store." The bracket form is purely additive — both commands install the samespl-bridgepackage and CLI; the second one just installs more.- The single quotes around the whole
'spl-bridge[keyring] @ git+...'argument are required because (a) zsh (the macOS default shell) otherwise treats[and]as filename glob characters and fails withzsh: no matches found, and (b) the@and the://in the URL are also shell-significant in some setups. In bash, fish, and PowerShell the quotes are harmless, so the fully-quoted form is the safe copy-paste regardless of platform.- It's re-runnable. You can add OS-keychain support to an existing install at any time by re-running
pip install 'spl-bridge[keyring] @ git+https://github.com/jagalliers/spl-bridge.git'; pip will only install what's missing.
For development against a local checkout (after git clone), the URL goes away — . is the current directory and [dev,keyring] selects two extras at once:
pip install -e '.[dev,keyring]'Where credentials actually end up at runtime — and the four-source resolution order — is documented in full at Where credentials live.
There are two ways to wire spl-bridge to your MCP host. The wizard is recommended for first-time setup on a developer workstation; manual configuration is fully supported and is the right choice for CI runners, Docker/Kubernetes, multi-environment deployments, or any host the wizard doesn't yet target.
The two paths are not exclusive — credentials stored by the wizard work fine when the same spl-bridge is launched manually, and vice-versa, because both go through the same four-source resolver described in Where credentials live.
spl-bridge setupThe wizard runs five steps and persists nothing until step 4:
- Prereqs — Python version,
mcp/requests/platformdirsimportable, OS keychain backend usability. - Splunk — host, port, scheme, TLS verification, auth mode (token or username+password), with hard-stops for unsafe combinations (refuses password over plain HTTP; requires explicit
y/Nconfirmation — defaulting to no — to disable TLS verification and again to send a password to an unverified TLS endpoint). - Probe — live
GET /services/server/infoagainst the credentials you just entered, before persisting anything. If the probe fails, the wizard offers up to 3 edit-and-retry attempts (previous answers pre-filled as defaults — press Enter to keep, type to override; secrets are always re-prompted, never recalled). After the budget is exhausted the menu degrades to the historical save-anyway / quit prompt and points you atspl-bridge doctorfor iterative testing without re-running setup. - Credstore — secrets stored in your OS keychain (preferred) or a 0600 dotfile (fallback). See Where credentials live for paths and at-rest protection.
- MCP host — writes a launch entry into your MCP host's JSON config (Cursor, Claude Desktop, or via
claude mcp add), with a timestamped backup of any prior config. Falls back to printing a snippet for hosts the wizard doesn't directly target.
What ends up where:
- OS keychain or 0600 dotfile:
SPLUNK_TOKEN(orSPLUNK_USERNAME+SPLUNK_PASSWORD). - MCP host JSON config (e.g.
~/.cursor/mcp.json): only the launch command and the connection metadata (SPLUNK_HOST,SPLUNK_PORT,SPLUNK_SCHEME, optionalSPLUNK_VERIFY_SSL). No token, no password.
The wizard refuses to run if stdin is not a TTY, and never echoes a secret to stdout/stderr.
Sample run (sanitized, abbreviated):
spl-bridge setup wizard
Walks you through Splunk creds, secure storage, and MCP host wiring.
== Prerequisites ==
✓ Python version: running 3.13.0 (need >= 3.10)
✓ mcp library: importable
✓ requests library: importable
✓ platformdirs: importable
✓ OS keychain (keyring): backend = keyring.backends.macOS.Keyring
== Splunk connection ==
Splunk host (FQDN or IP) [localhost]: splunk.example.com
Splunk REST management port [8089]:
Connection scheme:
1) https (recommended)
2) http (lab only)
Choice [1]:
TLS verification:
1) Verify with system CA bundle
2) Verify with a custom CA bundle path
3) DISABLE verification (lab only)
Choice [1]:
== Authentication ==
· Token mode is recommended for production.
Auth mode:
1) Splunk auth token (recommended)
2) Username + password (lab only)
Choice [1]:
Splunk auth token: ********
== Live connectivity test ==
· GET https://splunk.example.com:8089/services/server/info (token auth)
✓ Connected to splunk-sh-01 (version 9.4.2)
== Credential storage ==
· Backend: keyring (keyring.backends.macOS.Keyring)
✓ Stored SPLUNK_TOKEN
MCP server name [splunk]:
== MCP host integration ==
Where should we register spl-bridge?
1) Cursor
2) Claude Desktop
3) Claude CLI
4) Print snippet only
Choice [1]:
✓ Cursor -> /Users/you/.cursor/mcp.json
· Backup of previous config at /Users/you/.cursor/mcp.json.bak.20260428T220115
== Summary ==
✓ Splunk: https://splunk.example.com:8089 (auth = token)
✓ Credential store: keyring (keyring.backends.macOS.Keyring)
✓ MCP host: Cursor
· Restart your MCP host for the new server to appear.
To rotate a credential or change the connection, re-run spl-bridge setup and pick the same MCP server name. The wizard overwrites the keychain entry and updates the JSON config in place, with a fresh timestamped backup.
Why the wizard writes an absolute
commandpath. MCP hosts launched from launchd / Finder — notably Claude Desktop on macOS — inherit a stripped-downPATHthat omits common Python install prefixes (Homebrew Python user-sites under~/Library/Python/3.x/bin, pipx venvs,uv toolvenvs, project venvs). A bare"command": "spl-bridge"works in your interactive shell but fails at MCP-host spawn time withFailed to spawn process: No such file or directory. The wizard resolvesspl-bridgeviacommand -v spl-bridge(withsys.argv[0]as a fallback) and writes the absolute path, so the host can always find the binary regardless of its launch-timePATH. If you ever see the spawn error in Claude Desktop's~/Library/Logs/Claude/mcp.log, check that thecommandvalue in~/Library/Application Support/Claude/claude_desktop_config.jsonmatches whatcommand -v spl-bridgeprints in your shell — re-runningspl-bridge setupwith the same MCP server name will repair it in place.
Use this path when you're scripting deployment, running in Docker / Kubernetes, integrating with an MCP host the wizard doesn't write for, or simply prefer hand-rolled config.
pip install 'spl-bridge @ git+https://github.com/jagalliers/spl-bridge.git'
export SPLUNK_HOST=splunk.example.com
export SPLUNK_TOKEN=your-splunk-token
spl-bridge doctor # one-shot Splunk connectivity check
spl-bridge doctor --hosts # audit MCP host configs (Cursor, Claude Desktop)
# for stale bare-command spl-bridge entries
spl-bridge serve # run the MCP stdio server (or `python -m spl_bridge`)
doctor --hosts— inspects~/.cursor/mcp.jsonand the per-OS Claude Desktop config for anyspl-bridgeentry whosecommandis a bare basename (e.g."command": "spl-bridge") rather than an absolute path. Bare-command entries fail to launch from PATH-stripped GUI hosts (notably Claude Desktop on macOS, where launchd hands the host a minimal PATH that omits pipx /uv tool/ Homebrew Python user-sites and project venvs). Setup wizards ≥this release always write the resolved absolute path; the--hostsaudit is for users with pre-fix configs who want to self-diagnose without trawling host logs. The Splunk REST endpoint is not touched in--hostsmode, so it works even when Splunk is unreachable.
WARNING — Lab-only password mode. Combining
SPLUNK_USERNAME/SPLUNK_PASSWORDwithSPLUNK_VERIFY_SSL=falseis only safe inside a fully isolated lab network. The password is sent in the body of an HTTPS POST to/services/auth/login; if TLS verification is disabled an on-path attacker can transparently MITM the connection and capture both the password and the returned session key. Never use this combination against shared, staging, or production Splunk instances.
# Lab-only password mode (DO NOT use outside an isolated network)
export SPLUNK_HOST=splunk.lab.local
export SPLUNK_USERNAME=admin
export SPLUNK_PASSWORD=changeme
export SPLUNK_VERIFY_SSL=falseThe most common pattern puts the token directly in the host's env block:
{
"mcpServers": {
"splunk": {
"command": "python",
"args": ["-m", "spl_bridge"],
"env": {
"SPLUNK_HOST": "splunk.example.com",
"SPLUNK_TOKEN": "your-splunk-token"
}
}
}
}This works, but it places the token in plaintext on disk in your home directory and the MCP host re-reads it on every restart. The wizard's keychain-backed flow (path A) avoids this.
For lab environments with self-signed certs:
{
"mcpServers": {
"splunk": {
"command": "python",
"args": ["-m", "spl_bridge"],
"env": {
"SPLUNK_HOST": "splunk.lab.local",
"SPLUNK_USERNAME": "admin",
"SPLUNK_PASSWORD": "changeme",
"SPLUNK_VERIFY_SSL": "false"
}
}
}
}For Docker / Kubernetes where the secret is mounted as a file:
{
"mcpServers": {
"splunk": {
"command": "spl-bridge",
"env": {
"SPLUNK_HOST": "splunk.example.com",
"SPLUNK_TOKEN_FILE": "/run/secrets/splunk_token"
}
}
}
}spl-bridge resolves each credential (SPLUNK_TOKEN, SPLUNK_USERNAME, SPLUNK_PASSWORD) by trying four sources in order. The first non-empty value wins; later sources are not consulted.
| Order | Source | Where | At-rest protection |
|---|---|---|---|
| 1 | $SPLUNK_TOKEN (or _USERNAME / _PASSWORD) |
Process environment | None. Visible in /proc/<pid>/environ, in shell history if exported interactively, and inherited by any child process. Appropriate for CI runners that scrub env on completion. |
| 2 | $SPLUNK_TOKEN_FILE (or _USERNAME_FILE / _PASSWORD_FILE) |
Path read at startup | Whatever the file's filesystem ACLs are. Docker/K8s typically mount these mode 0400; spl-bridge reads whatever path you point at. |
| 3 | OS keychain, service spl-bridge |
macOS Keychain / Windows Credential Manager / Linux Secret Service or KWallet | Encrypted by the OS under the user's login (macOS Keychain, Windows DPAPI). Linux Secret Service depends on the backend (gnome-keyring is encrypted; some KWallet configurations are not). Requires the [keyring] extra and an active backend. |
| 4 | 0600 dotfile | platformdirs.user_config_dir("spl-bridge") / credentials — typically ~/Library/Application Support/spl-bridge/credentials (macOS), %LOCALAPPDATA%\spl-bridge\credentials (Windows), ~/.config/spl-bridge/credentials (Linux/XDG) |
Filesystem ACLs only (mode 0600 on POSIX). The file is not encrypted. spl-bridge refuses to read a dotfile whose mode isn't exactly 0600, refuses to follow symlinks (O_NOFOLLOW), and refuses files larger than 64 KiB. Writes are atomic via mkstemp + os.replace. |
The wizard writes to source #3 if a keychain backend is available, otherwise to source #4. It never writes to source #1 or #2; those are yours to manage.
Connection metadata (SPLUNK_HOST, SPLUNK_PORT, SPLUNK_SCHEME, SPLUNK_VERIFY_SSL, SPLUNK_APP) is not stored in the credstore — it lives in the MCP host's JSON config so you can flip environments without touching the keychain.
To inspect what the wizard stored:
# macOS Keychain
security find-generic-password -s spl-bridge -a SPLUNK_TOKEN -w
# Linux (Secret Service via secret-tool)
secret-tool lookup service spl-bridge username SPLUNK_TOKEN
# Windows
cmdkey /list:spl-bridge
# Dotfile fallback (any platform)
cat "$(python3 -c 'import platformdirs; print(platformdirs.user_config_dir("spl-bridge"))')/credentials"To remove a credential, delete the keychain entry with the equivalent OS tool (security delete-generic-password, secret-tool clear, cmdkey /delete) or remove the line from the dotfile. There is no spl-bridge unsetup — the wizard is idempotent, so re-running it with new values overwrites in place.
These can be set directly in the shell, in the MCP host's env block, or via _FILE companions. The wizard sets the connection variables for you and leaves the secrets to the credstore.
| Variable | Default | Description |
|---|---|---|
SPLUNK_HOST |
(required) | Splunk hostname (e.g. splunk.example.com or mystack.splunkcloud.com) |
SPLUNK_PORT |
8089 |
Management REST port |
SPLUNK_SCHEME |
https |
http or https |
SPLUNK_VERIFY_SSL |
true |
TLS certificate verification. Accepts true/false, or a path to a CA bundle (.pem) for self-signed/internal CA setups, e.g. SPLUNK_VERIFY_SSL=/etc/ssl/certs/my-corp-ca.pem |
SPLUNK_TOKEN |
— | Splunk auth/bearer token (preferred). Resolved via the four-source order in Where credentials live. |
SPLUNK_USERNAME |
— | Username for password auth (lab) |
SPLUNK_PASSWORD |
— | Password for password auth (lab) |
SPLUNK_APP |
— | Default app context for searches |
SPLUNK_TOKEN_FILE |
— | Path to a file containing the token (Docker / K8s secret pattern) |
SPLUNK_USERNAME_FILE |
— | Path to a file containing the username |
SPLUNK_PASSWORD_FILE |
— | Path to a file containing the password |
MCP_TIMEOUT |
45.0 |
HTTP request timeout in seconds. Deliberately below the common 60s MCP client request budget so the bridge can return an actionable timeout error (with remediation hints) before the client gives up with an opaque -32001. Raise it if your deployment legitimately runs 45–60s searches |
MCP_MAX_ROW_LIMIT |
1000 |
Maximum rows any tool can return |
MCP_DEFAULT_ROW_LIMIT |
100 |
Default row limit when not specified |
MCP_DEFAULT_EARLIEST_TIME |
-24h |
Default earliest_time applied to splunk_run_query only, when the caller omits both time parameters. The applied window is disclosed in the response's time_window field. Set to 0 (or empty) to disable and restore unbounded All-Time searches. Does not affect splunk_run_saved_search (omitted means "run the saved search unmodified") or splunk_get_metadata (discovery over wide ranges is cheap and is the point of that tool) |
MCP_REQUIRE_CAPABILITIES |
false |
When true, verify the Splunk principal has the search capability before serving any tool |
MCP_RATE_LIMITS |
— | JSON map of per-tool 60s rate limits, e.g. {"global":600,"splunk_run_query":120}. Per-key values are bounded to [0, 1_000_000]; 0 means always-deny |
MCP_MAX_RESPONSE_BYTES |
67108864 (64 MiB) |
Hard cap on a single Splunk REST response body. Over-cap responses are converted to a synthetic HTTP 502 and the body is dropped before reaching the tool layer. Raise only if your environment legitimately returns >64 MiB single-call payloads (very unusual; per-call streaming and head row limits are the right fix) |
SPLUNK_ALLOW_PLAINTEXT |
0 |
Required when SPLUNK_SCHEME=http and a token is configured. Set to 1 to opt-in to sending the bearer token over plain HTTP (lab only). The server always logs a WARNING when the scheme is HTTP, regardless of this flag |
Auth precedence: If both SPLUNK_TOKEN and SPLUNK_USERNAME/SPLUNK_PASSWORD are set, token mode wins. For each credential variable the direct value wins over its _FILE companion, and both env-side options win over the keychain and dotfile (see the four-source order above).
HTTP scheme. The server refuses to send a Splunk token over plain HTTP unless SPLUNK_ALLOW_PLAINTEXT=1 is also set. This catches the common misconfiguration where SPLUNK_SCHEME=http is left in place after a copy-paste from a lab .env. Username/password mode over http was already rejected and remains so. Scheme is HTTP -> always logs a WARNING, regardless of the opt-in flag, so the misconfiguration is visible in operational logs.
The MCP tool names below use splunk_* as a descriptive prefix (nominative use, indicating which upstream system the tool calls). They are MCP tool identifiers exposed to clients, not Splunk product names.
| MCP tool name | Description | Splunk REST source |
|---|---|---|
splunk_get_info |
Splunk instance info (version, hardware, license) | /services/server/info |
splunk_get_indexes |
List indexes with size and event counts | /services/data/indexes |
splunk_get_index_info |
Detailed info for a specific index | /services/data/indexes |
splunk_get_user_list |
List Splunk users | /services/authentication/users |
splunk_get_user_info |
Current authenticated user details | /services/authentication/current-context |
splunk_run_query |
Execute an ad-hoc, allowlisted SPL query. Applies a default -24h time window when both time parameters are omitted (see MCP_DEFAULT_EARLIEST_TIME), disclosed in the response as time_window |
/services/search/jobs/export |
splunk_get_metadata |
Hosts, sources, or sourcetypes metadata | SPL ` |
splunk_get_kv_store_collections |
KV Store collection statistics (raw bytes) | /services/server/introspection/kvstore/collectionstats |
splunk_get_knowledge_objects |
Knowledge objects by type (saved searches, macros, lookups, etc.) | /servicesNS/-/-/... family |
splunk_run_saved_search |
Execute a saved search by name, with optional earliest_time/latest_time overrides for the run |
SPL ` |
- Where credentials are stored, in what order they're resolved, and which sources are encrypted at rest is documented in full at Where credentials live.
- The server itself never writes a credential to disk; it only reads from the four sources above. Persistent storage (keychain entry, 0600 dotfile) is performed once by the setup wizard and re-read at every server start.
- Secrets are redacted from structured logs by
MCPJsonFormatter(matches againsttoken,password,session_key,authorization,api_key,secret,bearerextras). You should still treat tokens, passwords, and session keys as "must never appear in any record". - Passwords are exchanged for in-memory session keys via
/services/auth/login. After a successful login the password reference on the in-process config is cleared as a defence-in-depth measure (Python cannot guarantee zeroisation; see Known limitations). - Upstream Splunk error response bodies are not surfaced to MCP clients — clients only see a stable, generic message of the form
"Splunk API error (HTTP 500; request_id=abcdef123456)". Full diagnostic detail is written to the structured stderr log under that samerequest_id. - Token mode is preferred for production; password mode is a lab convenience.
- Credentials are never accepted as MCP tool arguments.
WARNING: Never combine
SPLUNK_USERNAME/SPLUNK_PASSWORDwithSPLUNK_VERIFY_SSL=falseoutside a fully isolated lab. See Setup → Manual.
- Command allowlist sourced from this project's curated list of 143 SPL commands in
spl_bridge/data/safe_spl.json. Selection criteria are documented inspl_bridge/data/PROVENANCE.md.rest,script,sendemail,outputcsv,outputlookup,collect, anddeleteare deliberately not on the list. - Recursive subsearch validation via Splunk's parser API.
- Row limits enforced with
| headappended to queries. - A short list of admin-style tools (
splunk_get_info,splunk_get_indexes,splunk_get_user_list,splunk_run_saved_search, etc.) bypasses the SPL allowlist because their behaviour is governed either by non-SPL REST paths or by Splunk's own authorization boundary (saved searches run under their owner's permissions).
The Splunk user/token needs at minimum:
searchcapability (for running queries)rest_properties_get/rest_properties_setas needed by specific| resttools- Admin-level tools (
get_user_list,get_info) require appropriate admin capabilities
- Global: 600 requests per 60-second window by default; override with
MCP_RATE_LIMITS. - Per-tool limits configurable via the same env var, e.g.
MCP_RATE_LIMITS='{"global":600,"splunk_run_query":120}'. - Per-tool denials do not consume the global budget.
- Message payload capped at 128 KB with max JSON depth of 32.
- Limits are enforced per process. Multi-worker deployments enforce the configured limits per worker, not globally across the deployment.
- Subsearch bracket extraction in the SPL safety pre-check uses a bracket
scanner; deeply nested or string-literal-quoted
]characters inside subsearches may yield over- or under-matched extractions. As defence-in-depth, every extracted segment is independently revalidated through the Splunk parser API, so a malformed extraction cannot bypass the allowlist. - Python cannot guarantee that a former password byte-string is zeroed in memory after dereference. The server drops its reference immediately after a successful login, but a memory-dump attacker with local code execution could still recover the value before garbage collection.
pip install -e '.[dev,keyring]'
pytest tests/ -vSee CONTRIBUTING.md for ground rules, DCO sign-off, the optional opt-in test suites (PTY wizard scenarios, Docker, Python matrix), and notes for AI coding assistants.
- Use your stack hostname:
https://<stack>.splunkcloud.com:8089 - Some admin REST endpoints may be restricted by
sc_adminrole limitations - Prefer bearer tokens over password auth
- Test with
spl-bridge doctorto verify endpoint accessibility
MCP client (Cursor, etc.)
↕ stdio (JSON-RPC)
spl-bridge server
↕ HTTPS (REST API)
Splunk Enterprise / Cloud (port 8089)
The server loads tool definitions from spl_bridge/data/builtin_tools.json, validates SPL against the curated safety corpus, and executes searches via search/jobs/export with NDJSON response parsing.
spl-bridge is an independent open-source project. It is not affiliated with, endorsed by, sponsored by, or certified by Splunk LLC (a Cisco company) or Cisco Systems, Inc.
- "Splunk", "Splunk Enterprise", "Splunk Cloud", and "Splunkbase" are trademarks or registered trademarks of Splunk LLC. References to these marks in this documentation are made under nominative fair use solely to identify the upstream system this bridge interoperates with, in accordance with the Splunk Trademark Usage Guidelines.
- "Cisco" is a trademark or registered trademark of Cisco Systems, Inc. and/or its affiliates.
- "Model Context Protocol" and "MCP" identify the open protocol specification published at modelcontextprotocol.io.
This project does not redistribute, fork, or port any portion of:
- the Splunk MCP Server app published on Splunkbase by Splunk LLC (Splunkbase app id 7931, governed by the Splunk General Terms); or
- the Splunk-MCP-Server-official source repository published by Cisco at CiscoDevNet/Splunk-MCP-Server-official under the Cisco Sample Code License v1.1.
The MCP tool catalogue, SPL command allowlist, and any SPL templates in this project are independently authored against the public Splunk REST API Reference and the public Splunk Search Reference. See spl_bridge/data/PROVENANCE.md for source-of-record citations.
Splunk LLC publishes its own MCP server for the Splunk platform at Splunkbase app 7931.