Skip to main content
Glama
glatinone

Secops Toolkit MCP

by glatinone

SecOps Toolkit MCP

CI Release License: MIT

A small, dependency-light Model Context Protocol server that gives an AI assistant a set of defensive security helpers for working with logs, threat-intel notes, and network data — all running locally, with no API keys and no outbound network calls.

Built with FastMCP.

Tools

Tool

What it does

extract_iocs

Pull IPs, URLs, domains, MD5/SHA1/SHA256 hashes, and CVE IDs out of free-form text. Handles defanged input (1.2.3[.]4, hxxp://).

defang_ioc

Make an indicator safe to paste: 1.2.3.41.2.3[.]4.

refang_ioc

Reverse a defanged indicator back to its real form.

hash_text

Hash a string with md5 / sha1 / sha256 / sha512.

password_entropy

Estimate password strength in bits of entropy.

cidr_info

Describe a CIDR network: netmask, host range, size, privacy.

ip_in_cidr

Check whether an IP falls inside a CIDR range.

scan_repo_root

Check a repo's top-level directory for files that shadow common dev command names (git.exe, node.exe, etc.), and the whole tree for symlinks that resolve outside the repo, before you open it in an agentic coding tool.

assess_shell_command

Assess a shell command for constructs (quote fragmentation, command substitution, IFS tricks, encoded pipelines, setuid grants, env-var poisoning via export/typeset/declare) that look benign to naive string matching but execute something else once a shell expands them.

These are defensive / analysis utilities — parsing, hashing, and network math. They don't scan, attack, or reach out to any host.

Related MCP server: depguard

Quickstart

Requires Python 3.11+ and uv.

git clone https://github.com/glatinone/secops-toolkit-mcp.git
cd secops-toolkit-mcp
uv sync
uv run secops-toolkit-mcp   # starts the server over stdio

That's it, the server is now running and waiting for an MCP client to connect over stdio. Wire it into a client (below), or call the underlying functions directly in Python (see Examples).

Use it from an MCP client

Add this to your client's MCP config (e.g. Claude Desktop's claude_desktop_config.json). Point --directory at where you cloned the repo:

{
  "mcpServers": {
    "secops-toolkit": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/secops-toolkit-mcp", "secops-toolkit-mcp"]
    }
  }
}

Then ask your assistant things like "extract the IOCs from this alert" or "is 10.0.4.20 inside 10.0.0.0/16?" and it will call these tools.

Standalone CLI: secops-scan-repo

scan_repo_root is also available outside an MCP client, as its own console script, for the exact moment it matters most: right after you clone or download a repo and before you open it in an agentic coding tool.

uv run secops-scan-repo /path/to/a/freshly-cloned-repo
# secops-scan-repo: /path/to/a/freshly-cloned-repo (4 top-level file(s), 1 symlink(s) scanned)
#
#   [CRITICAL] git.exe shadows the 'git' command
#   [CRITICAL] vendor_link is a symlink resolving outside the repo root, to /home/dev/.ssh/authorized_keys

Exits 0 on a clean directory, 1 if a finding is at or above --min-severity (default medium, i.e. any finding), 2 on a bad path. -f/--format json gives the same structure scan_repo_root returns, for scripting. This makes it a one-liner in a pre-clone git hook:

#!/bin/sh
# .git/hooks/post-checkout (or a wrapper your clone script calls)
secops-scan-repo "$(git rev-parse --show-toplevel)" || {
  echo "secops-scan-repo: refusing to continue, see findings above" >&2
  exit 1
}

If installed system-wide (uv tool install . or pip install .), drop the uv run prefix and call secops-scan-repo directly.

Examples

The tools are plain functions in core.py, so you can call them directly (e.g. in a REPL or a script) without going through an MCP client:

from secops_toolkit_mcp.core import extract_iocs, defang_ioc, hash_text, password_entropy, cidr_info, ip_in_cidr, assess_shell_command

extract_iocs("Reached out to 1.2.3[.]4 and hxxp://evil.example.com, hash 5d41402abc4b2a76b9719d911017c592, see CVE-2024-1234")
# {'md5': ['5d41402abc4b2a76b9719d911017c592'], 'ipv4': ['1.2.3.4'],
#  'url': ['http://evil.example.com'], 'domain': ['evil.example.com'],
#  'cve': ['CVE-2024-1234']}

defang_ioc("http://1.2.3.4/payload")
# 'hxxp[://]1[.]2[.]3[.]4/payload'

hash_text("hello world")
# {'algorithm': 'sha256', 'hex_digest': 'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'}

password_entropy("Tr0ub4dor&3")
# {'length': 11, 'charset_size': 94, 'entropy_bits': 72.1, 'strength': 'strong'}

cidr_info("10.0.0.0/24")
# {'network': '10.0.0.0', 'netmask': '255.255.255.0', 'prefix_length': 24,
#  'version': 4, 'num_addresses': 256, 'is_private': True,
#  'first_host': '10.0.0.1', 'last_host': '10.0.0.254', 'broadcast': '10.0.0.255'}

ip_in_cidr("10.0.0.5", "10.0.0.0/24")
# True

scan_repo_root("/path/to/a/freshly-cloned-repo")
# {'path': '/path/to/a/freshly-cloned-repo', 'entries_scanned': 4,
#  'symlinks_scanned': 1, 'clean': False, 'findings': [
#    {'kind': 'shadowed_name', 'filename': 'git.exe', 'shadows': 'git',
#     'severity': 'critical'},
#    {'kind': 'symlink_escape', 'path': 'vendor_link',
#     'resolves_to': '/home/dev/.ssh/authorized_keys', 'severity': 'critical'}
#  ]}

assess_shell_command("r'm' -rf /")
# {'command': "r'm' -rf /", 'risk': 'dangerous', 'logical_commands': [
#    {'raw_segment': "r'm' -rf /", 'tokens': ['rm', '-rf', '/'],
#     'effective_command': 'rm -rf /',
#     'findings': ['bypassed_raw_pattern_match', 'denylisted_pattern'],
#     'raw_denylist_hits': [], 'normalized_denylist_hits': ['recursive_root_delete'],
#     'risk': 'dangerous'}
#  ], 'substitutions': [], 'pipe_findings': [], 'bypassed_raw_pattern_match': True}
# Note raw_denylist_hits is empty: a filter matching the raw text "r'm' -rf /"
# finds nothing. normalized_denylist_hits catches it because the tokens are
# what a real shell would actually run.

assess_shell_command("echo cm0gLXJmIC8= | base64 -d | sh")
# {'command': 'echo cm0gLXJmIC8= | base64 -d | sh', 'risk': 'dangerous',
#  'logical_commands': [
#    {'raw_segment': 'echo cm0gLXJmIC8=', 'tokens': ['echo', 'cm0gLXJmIC8='],
#     'effective_command': 'echo cm0gLXJmIC8=', 'findings': [], 'risk': 'safe', ...},
#    {'raw_segment': 'base64 -d', 'tokens': ['base64', '-d'],
#     'effective_command': 'base64 -d',
#     'findings': ['pipe_decoded_content_to_interpreter'], 'risk': 'dangerous', ...},
#    {'raw_segment': 'sh', 'tokens': ['sh'], 'effective_command': 'sh',
#     'findings': ['pipe_decoded_content_to_interpreter'], 'risk': 'dangerous', ...}
#  ],
#  'pipe_findings': [{'type': 'pipe_decoded_content_to_interpreter',
#                      'segments': ['base64 -d', 'sh']}], ...}
# The base64 blob decodes to "rm -rf /" -- decoding it is what turns opaque
# text into an executable payload, the same "danger only visible after a
# transform the filter doesn't model" shape as piping a fetch into a shell.

assess_shell_command("cd ~/.ssh && cat authorized_keys")
# {'command': 'cd ~/.ssh && cat authorized_keys', 'risk': 'dangerous',
#  'logical_commands': [
#    {'raw_segment': 'cd ~/.ssh', 'tokens': ['cd', '~/.ssh'],
#     'findings': ['cd_into_sensitive_directory'], 'risk': 'dangerous', ...},
#    {'raw_segment': 'cat authorized_keys', 'tokens': ['cat', 'authorized_keys'],
#     'findings': [], 'risk': 'safe', ...}
#  ], 'cd_findings': [{'type': 'cd_into_sensitive_directory',
#                       'segments': ['cd ~/.ssh', 'cat authorized_keys']}], ...}
# A bare "cd ~/.ssh" alone would be safe -- nothing acts on it yet. Chained
# with a further command, the second segment's own relative-path filename
# ("authorized_keys" alone, no path prefix) would slip past every other
# check here, since none of them know the effective working directory changed.

assess_shell_command("export PAGER='open -a Calculator'")
# {'command': "export PAGER='open -a Calculator'", 'risk': 'dangerous',
#  'logical_commands': [
#    {'raw_segment': "export PAGER='open -a Calculator'",
#     'tokens': ['export', 'PAGER=open -a Calculator'],
#     'findings': ['denylisted_pattern'],
#     'normalized_denylist_hits': ['env_poisoning_assignment'],
#     'risk': 'dangerous', ...}
#  ], ...}
# Flagged even with nothing chained after it -- unlike "cd ~/.ssh", a
# poisoned PAGER persists in the calling agent's shell session and can be
# triggered by a later, separately-approved command ("git branch", "man ls")
# this function never sees, since each call only assesses one command string.

assess_shell_command("typeset -i ${(e):-'$(open -a Calculator)'}")
# {'command': "typeset -i ${(e):-'$(open -a Calculator)'}", 'risk': 'suspicious',
#  'logical_commands': [
#    {'raw_segment': "typeset -i ${(e):-'$(open -a Calculator)'}",
#     'tokens': ['typeset', '-i', '${(e):-$(open -a Calculator)}'],
#     'effective_command': 'typeset -i ${(e):-$(open -a Calculator)}',
#     'findings': ['zsh_forced_parameter_expansion'],
#     'raw_denylist_hits': [], 'normalized_denylist_hits': [],
#     'risk': 'suspicious'}
#  ], 'substitutions': [], 'pipe_findings': [], 'bypassed_raw_pattern_match': False}
# Flagged "suspicious", not "dangerous": zsh's (e) flag forces evaluation of the
# default value even though it's single-quoted, so the embedded $(open -a
# Calculator) runs anyway -- but (e) also has legitimate non-malicious uses,
# so this function can't claim certainty from the text alone.

From an MCP client, the same calls happen through natural language, for example asking "hash this string with sha256" or "describe the network 10.0.0.0/24".

Why scan_repo_root exists

Mindgard disclosed (2026-07-15) that Cursor, GitHub Copilot CLI, Gemini CLI, and Codex all resolve an unqualified git command on startup. Windows checks the current working directory before PATH, so a cloned repo that ships a file literally named git.exe at its root runs that file instead of the real Git — before any workspace-trust prompt appears. As of this writing none of the four vendors has shipped a fix.

scan_repo_root closes this independent of which tool eventually opens the repo: point it at a directory before you open it (or wire it into a pre-clone/pre-open hook) and it flags any top-level file whose name shadows a commonly unqualified-invoked command (git, node, npm, python, bash, docker, and similar), tiered by how directly the shape has been confirmed exploitable:

  • criticalgit, the name Mindgard's disclosure confirmed end-to-end.

  • high — shells and interpreters (node, npm, npx, python, bash, cmd, powershell, ...) that agentic tools commonly invoke unqualified.

  • medium — other common dev tools (docker, make, curl, ssh, gh, ...) plausibly invoked the same way but not confirmed by the disclosure.

Only the top-level directory is checked, matching how Windows's own unqualified-command search actually works (current directory, then PATH — it does not recurse into subdirectories).

Wiz's "GhostApproval" (Amazon Q, Cursor) and Cursor's "DuneSlide" (CVE-2026-50548/50549, CVSS 9.3-9.8) disclosures are a second, unrelated masquerading shape: an approval dialog or sandbox check displays a decoy path while a symlink silently redirects the actual write target outside the trusted directory — up to and including ~/.ssh/authorized_keys. Both are zero-click once triggered by a prompt-injected agent action.

scan_repo_root also walks the whole repo tree (not just the top level — a planted symlink can sit anywhere a tool later writes through it) and flags any symlink whose resolved target lies outside the scanned root:

  • critical — the resolved target hits a known sensitive path (an .ssh/.aws/.gnupg/.docker/.kube/.azure directory, or a private key/credential filename like authorized_keys, id_rsa, .npmrc, .git-credentials).

  • high — resolves outside the root to anywhere else.

A symlinked directory's own contents are never walked into (only the symlink entry itself is inspected), so this can't be tricked into recursing outside the intended scan boundary.

Why assess_shell_command exists

GuardFall (2026-06) tested 11 popular open-source AI coding agents (Aider, Cline, Goose, Plandex, and others — roughly 548,000 combined GitHub stars) and found that 10 of them run a command-safety guard which inspects the raw string a model wrote, then hands that same string to a real shell. The shell rewrites the string before anything executes: quotes get removed, backslash escapes get resolved, $(...)/backtick command substitutions run, and variables (including $IFS, the field separator, which defaults to whitespace) get expanded. A guard that pattern-matches the raw text has already lost by the time any of that happens. r'm' -rf / doesn't look like rm -rf / to a regex, but a shell dequotes and concatenates it into exactly that.

assess_shell_command closes that gap by tokenizing with the same POSIX quote-removal rules a real shell uses (shlex), so the normalized command is what gets checked, not the raw string. It also:

  • Extracts $(...)/backtick command substitutions and recursively assesses the command hidden inside them.

  • Flags unquoted variable expansion, $IFS-based space-substitution tricks, ANSI-C ($'...') quoting, and unbalanced quotes — constructs whose real effect can't be determined from the text alone.

  • Flags a fetch piped straight into an interpreter (curl ... | sh), or an encoded payload decoded and piped straight into one (base64 -d | sh, xxd -r | sh) — patterns that give you no chance to inspect what you're about to run.

  • Flags setuid grants (chmod +s, chmod 4755, install -m 4755) and overwriting a credential file in place (sed -i/tee targeting ~/.aws/credentials, ~/.ssh/authorized_keys, and similar).

  • Flags a symlink whose target or link name lands on a sensitive path (ln -s ~/.ssh/id_rsa ./notes.txt), and a cd into a sensitive directory chained with a further command that would act on relative paths inside it (cd ~/.aws && cat credentials) — the shell-level shape of Cursor's DuneSlide disclosure (see below).

  • Flags export/typeset/declare/readonly/local assigning a behavior-redirecting variable (PAGER, BROWSER, PYTHONWARNINGS, PERL5OPT), and zsh's zero-click ${(e):-...} forced-parameter-expansion construct — Cursor's Terminal Tool Allowlist Bypass disclosure (see below).

It never executes the command, or any part of it, at any point — this is static text analysis, not a sandbox. Returns risk (safe, suspicious, or dangerous) plus bypassed_raw_pattern_match: concrete, per-call evidence that a normalized check caught something a raw-text filter would have missed.

Validated against GuardFall's disclosed bypass corpus

The bypass classes above aren't a guess at what GuardFall's disclosure might cover — they were checked directly against GuardFall's own published write-ups (not a summary of them). Confirmed already caught: quote fragmentation/merge (r''m, r'm' -rf /), $IFS-as-space substitution, command substitution used as an argument, backtick substitution, ANSI-C quoting. Two real gaps found and closed in this pass: the encoded-pipeline class (echo <base64> | base64 -d | sh) and several "alternative destructive utility" shapes the denylist didn't cover (setuid grants, in-place credential file overwrites, and $HOME/~-relative sensitive paths like rm -rf "$HOME/.aws/credentials", GuardFall's own cited real-world example).

One limitation is deliberate, not missed: a command substitution that computes the command name itself ($(echo rm) -rf /) can only be flagged suspicious, not dangerous, without actually running the substitution to see what it produces — and running untrusted code to decide whether it's safe to run defeats the point. See tests/test_core.py's "GuardFall disclosed corpus" section for the full payload-by-payload results.

Closing DuneSlide's shell-level shape

Cursor's DuneSlide disclosure (CVE-2026-50548/50549, see the symlink-escape section above) is two write-sandbox escapes: an agent-controlled working_directory parameter that silently expands the writable-path allowlist, and a symlink whose target the sandbox trusts instead of rejecting when canonicalization fails. scan_repo_root's symlink-escape check already finds a symlink planted in a repo before it's opened — but neither Cursor bug is about a pre-existing file; both are about what the agent's own command does mid-session, which is assess_shell_command's job, not scan_repo_root's.

Checked structurally against parsed tokens, the same way as the rm sensitive-target check above (ln's and cd's flags vary too much for a single regex), reusing the same sensitive dir/file name list:

  • ln -s/ln --symbolic, when its target or its link name hits a known-sensitive path (.ssh/.aws/.gnupg/.docker/.kube/.azure, or a credential filename like authorized_keys/id_rsa) — either side can be the sensitive one, since the attack's whole point is to make one side look innocent.

  • cd into a known-sensitive directory, only when chained (&&, ;, a pipe, or a newline) with a further command — a bare cd ~/.ssh with nothing acting on it afterward hasn't done anything yet, the same "danger is in the combination" posture pipe_findings already uses for fetch-piped-to-interpreter.

A plain hard link (ln with no -s) is a structurally different, lower-risk operation and stays out of scope. Both checks tokenize with the same quote- removal and $IFS-expansion rules as everything else in this function, so l'n' -s ~/.ssh/authorized_keys ./x and cd$IFS~/.aws && cat credentials are caught too, not just the unobfuscated form.

Closing CVE-2026-22708's env-poisoning shape

Cursor's Terminal Tool Allowlist Bypass (CVE-2026-22708, fixed in 2.3) is a third, distinct bypass mechanism: a command allowlist validates which external binary runs, but shell builtins aren't external binaries, so export, typeset, declare, readonly, and local execute unconditionally regardless of what's on the allowlist. An attacker (via prompt injection) uses one of them to poison an environment variable a later, separately-approved command reads — PAGER hijacks git branch/man ls, BROWSER hijacks a URL-opening command, PYTHONWARNINGS/PERL5OPT chain into arbitrary Python/Perl execution the next time those interpreters run. None of this requires ever executing a disallowed command string.

assess_shell_command flags an export/typeset/declare/readonly/local invocation that assigns one of these variables as dangerous on its own — deliberately not requiring a chained follow-up command in the same string, unlike the DuneSlide cd check above. A poisoned PAGER persists in the calling agent's shell session; the command that actually gets hijacked is usually issued in a later, separate tool call this function has no visibility into, so the poisoning step itself is what has to be caught:

assess_shell_command("export PAGER='open -a Calculator'")
# risk: dangerous — flagged even though nothing in *this* command string
# reads PAGER back yet.

The disclosure's PoC also included a zero-click variant with no export step at all: zsh's ${(e):-...} parameter-expansion flag forces evaluation of its default value even when that value is single-quoted — typeset -i ${(e):-'$(open -a Calculator)'} runs the embedded command despite the quotes that would normally disable expansion, bypassing the same single-quote assumption this function's own command-substitution extraction relies on elsewhere. Flagged as zsh_forced_parameter_expansion, a construct whose real effect can't be determined from the text alone — the same honest treatment as ifs_manipulation/ansi_c_quoting, not overclaimed as dangerous on its own since (e) also has legitimate, non-malicious uses.

Deliberately out of scope: unset and set, which the same disclosure also names as bypassing the allowlist, but neither can carry a VAR=value assignment the way export/typeset/declare/readonly/local do — unset only removes a variable, and set (without -o) manipulates positional parameters, not the environment. And LD_PRELOAD, a well-known dangerous variable elsewhere, isn't in this list since it wasn't part of this disclosure's own confirmed PoC payloads — added only if a future disclosure or real-world case demonstrates it.

Run with Docker

The included Dockerfile builds a container that launches the server over stdio, so an MCP client can run it without a local Python/uv install:

docker build -t secops-toolkit-mcp .
docker run -i --rm secops-toolkit-mcp

To use it from an MCP client, point the client's config at docker run instead of uv run:

{
  "mcpServers": {
    "secops-toolkit": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "secops-toolkit-mcp"]
    }
  }
}

Troubleshooting

  • Client shows the server as disconnected / no tools listed. MCP clients talk to this server over stdio, so anything else printed to stdout will break the protocol. Confirm you're running uv run secops-toolkit-mcp (or the Docker command above) exactly, not piping it through another wrapper that adds its own output.

  • --directory path errors in the client config. The path must be absolute and point at the cloned repo root (the folder containing pyproject.toml), not the src/ directory.

  • ValueError from hash_text, cidr_info, or ip_in_cidr. These raise on bad input (unsupported hash algorithm, malformed IP/CIDR) with a message naming the invalid value, by design, rather than failing silently.

  • Python version errors during uv sync. The project requires Python 3.11+ (see .python-version); uv will fetch a matching interpreter automatically if one isn't already installed.

Development

uv sync          # install deps (incl. dev)
uv run pytest    # run the test suite

The logic lives in core.py as plain, testable functions; server.py is a thin layer that exposes them as MCP tools.

See CONTRIBUTING.md for the full workflow for adding a new tool, and CHANGELOG.md for release history.

Roadmap

  • Initial tool set: IOC extraction, defang/refang, hashing, password entropy, CIDR math (v0.1.0)

  • CI on Python 3.11 to 3.13, CHANGELOG (v0.2.0)

  • scan_repo_root, a pre-clone/pre-open check for binaries that shadow common dev command names (v0.3.0), closing the Mindgard 2026-07-15 unqualified-git disclosure

  • assess_shell_command, a shell command safety check that assesses what a shell actually runs rather than the raw string a model wrote (v0.4.0), closing the GuardFall 2026-06 bypass class

  • secops-scan-repo, a standalone CLI for scan_repo_root (v0.5.0), so it can run in a pre-clone git hook or CI step without an MCP client

  • scan_repo_root symlink-escape check (v0.6.0): flags a symlink anywhere in the repo tree whose resolved target lies outside the repo root, closing the GhostApproval/DuneSlide hidden-write-target pattern

  • assess_shell_command validated directly against GuardFall's disclosed bypass corpus (v0.7.0), not just a research digest of it — closed two real gaps found this way: encoded pipelines (base64 -d | sh, xxd -r | sh) and alternative destructive-utility shapes (setuid grants, in-place credential-file overwrites, $HOME/~-relative sensitive rm targets)

  • assess_shell_command widened for Cursor's DuneSlide disclosure (v0.8.0): flags an agent-issued ln -s/ln --symbolic targeting (or named after) a sensitive path, and a cd into a sensitive directory chained with a further command — the shell-level shape of both CVE-2026-50548 (working_directory abuse) and CVE-2026-50549 (symlink canonicalization bypass)

  • assess_shell_command widened for Cursor's Terminal Tool Allowlist Bypass (v0.9.0, CVE-2026-22708): flags export/typeset/declare/ readonly/local assigning a behavior-redirecting variable (PAGER, BROWSER, PYTHONWARNINGS, PERL5OPT) that a later, separately-approved command would then respect — a structurally distinct bypass from the GuardFall and DuneSlide shapes above, since it attacks what a trusted command's environment inherits, not what command string runs. Also flags zsh's zero-click ${(e):-...} forced-parameter-expansion construct

  • Widen scan_repo_root's shadowed-name/extension coverage, its sensitive-target symlink list, and assess_shell_command's denylist patterns as real-world use surfaces gaps; all three are intentionally high-signal, not exhaustive (see the module comments in core.py)

  • PyPI packaging, once the same pattern is proven end to end on mcpscan first

Contributions welcome, open an issue or PR.

License

MIT — see LICENSE.

Install Server
A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
2dRelease cycle
8Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    An MCP server that extracts Indicators of Compromise (IoCs) from unstructured text and checks their reputation across multiple threat intelligence services. It enables real-time analysis of IPs, domains, hashes, and URLs, providing enriched context for security workflows within LLMs.
    Last updated
    5
    19
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    MCP security server for AI coding agents. 12 tools: pre-install guardian, vulnerability audit, supply-chain attack detection via static code analysis, and CycloneDX 1.6 SBOM generation. Zero runtime dependencies.
    Last updated
    14
    65
    15
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • Security scanner for MCP servers. Detect vulnerabilities, prompt injection, and tool poisoning.

  • MCP server for Pentest-Tools.com: run scans, manage findings and reports via your preffered LLM.

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/glatinone/secops-toolkit-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server