trustmcp
Security scanner for MCP (Model Context Protocol) servers — the protocol through which AI agents (Claude, ChatGPT, Cursor, etc.) connect to external tools.
Given an MCP server (source code, a running server, or both), trustmcp produces a vulnerability report and an A–F score, natively integrated into the GitHub Security tab via SARIF.
Interested in the premium tier (semantic analysis, cross-server toxic-flow, continuous monitoring)? Join the waitlist at mcp-scanner.netlify.app.
Grade: F Score: 45/100
Total findings across all modules: 12
✅ Prerequisites
New to the command line? You'll need three things: Python 3.10 or newer installed on your computer; a terminal open (Command Prompt or PowerShell on Windows, Terminal on Mac); and that terminal pointed at the folder containing the MCP server code you want to scan — use the cd command to get there, e.g. cd path/to/my-mcp-server.
⚡ Quick Installation
# Direct execution without installation (recommended)
uvx trustmcp@latest scan --path . --mode static
# Or permanent installation
pip install trustmcp
trustmcp scan --path . --mode static
Static scan only (source code, no running server required):
trustmcp scan --path ./my-mcp-server --mode static
Full scan (static + live dynamic analysis + auth posture + unified score + SARIF):
trustmcp scan --path ./my-mcp-server --mode both \
--target "stdio:python3 server.py" \
--target "url:http://127.0.0.1:8931/mcp"
Outputs: a color-coded console report (via rich), mcp-scan-report.json, and mcp-scan-report.sarif — drop the SARIF file into CI and it automatically appears in the Security → Code scanning tab of your repository.
| Flag | What it does |
|---|---|
--path |
Directory to statically scan and to search for auth-posture evidence (default .) |
--mode |
static, dynamic, or both (default both) |
--target |
Live MCP server to scan dynamically. Repeatable. stdio:<command> or url:<url> |
--no-fuzz |
Disables tool input fuzzing during dynamic analysis |
--json-output |
Path for the JSON report (default mcp-scan-report.json) |
--no-json |
Do not write a JSON report |
--sarif-output |
Path for the SARIF report (default mcp-scan-report.sarif) |
--no-sarif |
Do not write a SARIF report |
--fail-on |
Exit non-zero if a finding at/above this severity exists — low/medium/high/critical (CI gating) |
-v, --verbose |
Verbose logging |
🎯 What It Detects
Four modules, all included in the free tier and always combined into a single score.
| Module | What it checks |
|---|---|
| Static (source code) | eval/exec, os.system/os.popen, subprocess(shell=True), unsafe pickle/yaml.load, path traversal, hardcoded secrets (OpenAI, Anthropic, GitHub, AWS, Stripe, Google, Slack, JWTs, a generic prefixed-credential heuristic, PEM keys), hidden/obfuscated Unicode (zero-width, bidi-control, and Unicode Tag "ASCII smuggling" characters), prompt-injection patterns in @tool/@resource/@prompt descriptions and docstrings (pseudo-tags, concealment directives, role-spoofing lines), runtime mutation of a tool's __doc__/description after definition (the "rug pull" mechanism), MCP config exposed on 0.0.0.0, unpinned or known-vulnerable dependencies (requirements.txt and package.json) |
| Dynamic (live server) | Tool/resource/prompt enumeration, authentication enforcement (401/403 vs. 200), TLS/HSTS for remote servers, live description drift vs. source code, and input fuzzing — malformed payloads sent to every discovered tool to catch crashes and stack-trace/error leakage |
| Auth posture | Detects whether a server appears to implement OAuth 2.1, a static API key, or an environment-variable token — and flags weak or missing mechanisms |
| Scoring | A–F grade, with findings explicitly mapped to the OWASP MCP Top 10 |
OWASP MCP Top 10 Coverage
trustmcp maps findings to official categories rather than inventing its own taxonomy:
MCP01:2025Token Mismanagement & Secret ExposureMCP02:2025Privilege Escalation via Scope CreepMCP03:2025Tool PoisoningMCP04:2025Software Supply Chain Attacks & Dependency TamperingMCP05:2025Command Injection & ExecutionMCP07:2025Insufficient Authentication & AuthorizationMCP10:2025Context Injection & Over-Sharing
Findings without a clear match are not forced into a category — see trustmcp/core/scoring.py.
🔇 Suppressing findings
A specific finding can be suppressed with an inline comment, the same convention most linters use (# noqa, # pylint: disable=...):
os.system(cmd) # trustmcp: ignore[static.os-system]
# trustmcp: ignore[static.path-traversal-open-param]
with open(user_path) as f:
...
eval(user_input) # trustmcp: ignore <- suppresses every rule on this line, not just one
# trustmcp: ignoresuppresses all findings on that line.# trustmcp: ignore[rule.id]suppresses only the named rule; comma-separate several:# trustmcp: ignore[static.os-system, static.dangerous-eval-exec].- The comment is honored on the finding's own line, or the line immediately above it — useful when the flagged line is long or auto-formatted.
- Works for AST-based findings in Python source, and for the line-based checks over
requirements.txt,mcp.json/manifest.json, andpackage.json(in JSON files the comment is stripped before parsing, so it doesn't breakjson.loads).
Use it for confirmed false positives or accepted risk, not to silence findings you haven't actually looked at.
🔬 Honesty Over Marketing
The
confidencefield on every finding is a heuristic per-rule prior (how specific/unambiguous the signature is) — not a statistically measured false-positive rate. Empirical calibration against known-vulnerable and clean MCP servers was run 2026-08-19 and re-run 2026-08-21 — see Validation below.
The dependency-vulnerability list is a small, hand-curated set of notorious CVEs, checked entirely offline — it is not a substitute for pip-audit, npm audit, or OSV.dev, which trustmcp does not call out to by design (no network dependency for a security tool's core scan).
📊 Validation: DVMCP Benchmark (2026-08-21)
Run against Damn Vulnerable MCP Server (DVMCP), cloned fresh, plus 3 clean official modelcontextprotocol/python-sdk example servers for false positives. This is a re-run of the original 2026-08-19 benchmark below, after adding three new static rules aimed directly at three of that run's documented misses (challenges 2, 4, and 7). Full methodology, caveats, and per-challenge evidence below — numbers are exact, not rounded up, and a challenge that still misses says so plainly.
What changed since 2026-08-19: three new static rules were added —
static.tool-description-injection(MCP03) — flags<IMPORTANT>/<HIDDEN>/<SYSTEM>/<SECRET>/<INSTRUCTIONS>/[SYSTEM]pseudo-tags, concealment phrases ("do not mention...", "ignore previous instructions", ...), and role-spoofing lines (a line startingSystem:/Assistant:/AI:), scoped only to a@tool/@resource/@prompt-decorated function's docstring and its decorator'sdescription=argument — deliberately not a whole-file scan, since that self-triggers on this project's own README and source discussing these exact phrases in prose.static.secret-jwt/static.secret-generic-credential(MCP01) — a JWT pattern, plus a generic<prefix>_api/key/token/sk_<random>credential shape gated on Shannon entropy (an all-zeros or all-repeated-character placeholder no longer fires).static.description-mutation(MCP03) — flags anyAssign/AugAssignto<something>.__doc__or<something>.descriptionoccurring after the function/class is defined (the "rug pull" mechanism), with a confidence bonus when the mutation is guarded by what looks like a call-counter comparison (if call_count < 3: ...).
Headline:
- Canonical DVMCP challenges (documented vulnerability,
server.py, matchesdocs/challenges.md): 6/10 fully detected, 1/10 partially detected, 3/10 missed — up from 3/10 fully detected, 1/10 partial, 6/10 missed. Challenges 2, 4, and 7 flipped from Miss to Hit; challenge 10's partial detection substantially deepened (see table). - As-deployed Docker containers (
server_sse.py, whatdocker runon ports 9001-9010 actually serves): 4/10 detected (2 off-label — see caveat), 6/10 missed — unchanged. The three new rules are aimed at patterns present in the canonical challenges; on inspection, none of the deployed variants happen to contain a matching pattern that wasn't already either caught or absent. One new rule did fire on a deployed variant (challenge 9) but turned out to be a false positive on closer inspection — see the table and the new-limitation note below, and don't skip past it: it's not being rounded into either count above. - False positives: 0/3 clean servers (re-confirmed via static analysis after adding the three new rules — see below).
New limitation discovered during this run: the role-spoofing check (a line starting System:/Assistant:/AI:) fired on DVMCP challenge 9's deployed server_sse.py, on the docstring line system: The remote system to access (e.g., "database", "webserver", "fileserver") inside a Google-style Args: block for a parameter literally named system. That is not a role-injection attempt — it's ordinary parameter documentation — so this is a genuine false positive, not a hit, and is reported as a Miss in the table below. The rule as specified only anchors on line-start plus a colon, which cannot distinguish "role-spoofing line" from "an Args: entry for a parameter named system/assistant/ai." Flagging for a design decision rather than silently patching it: narrowing this would need either requiring the whole rest of the line to look like an instruction rather than a type/description fragment, or explicitly excluding lines that look like Args:-block entries.
Important caveat (unchanged from 2026-08-19): DVMCP's own repo has two independent implementations of most challenges — server.py (matches the documented vulnerability class in docs/challenges.md) and server_sse.py (what the official Docker image actually runs on ports 9001-9010). On 6 of 10 challenges these diverge, sometimes completely — e.g. the live "Tool Poisoning" container (port 9002) contains no hidden tool-description instructions at all; it's a command-injection/path-traversal server instead. Both variants are reported below, labeled separately, so neither number is cherry-picked.
Two upstream DVMCP bugs had to be worked around to get it running at all (still present today), unrelated to trustmcp: requirements.txt pins mcp[cli]>=0.5.0 unpinned, which today resolves to mcp==2.0.0 — a version that removed mcp.server.fastmcp, so every challenge server crash-loops out of the box (fixed locally with a separate venv pinning mcp[cli]<2.0.0, which resolved to 1.29.0). Challenge 5's canonical server.py additionally calls FastMCP.resource(..., listed=False), a kwarg that doesn't exist in any current SDK version — it still cannot start at all, on any modern mcp release. Since DVMCP ships only HTTP entrypoints (legacy SSE or raw uvicorn) and trustmcp's dynamic client only speaks Streamable HTTP (not legacy SSE), each challenge was instead driven over stdio: the canonical server.py's module-level FastMCP object directly via .run(transport="stdio"), and the deployed server_sse.py's class-based Challenge<N>Server().mcp the same way — same tool/resource/prompt logic, different wire transport only.
Per-challenge results:
| # | Challenge | Canonical (server.py) |
Deployed Docker (server_sse.py, port 900N) |
|---|---|---|---|
| 1 | Basic Prompt Injection | ❌ Miss — no finding relates to the unsanitized notes://{user_id} reflection |
❌ Miss — identical implementation to canonical |
| 2 | Tool Poisoning | ✅ Hit (new) — 2× HIGH static.tool-description-injection (MCP03), directly on get_company_data and search_company_database's poisoned docstrings (<IMPORTANT>/<HIDDEN> tags plus "do not mention..." concealment phrases) |
⚠️ Off-label hit, unchanged — CRITICAL subprocess-shell-true (MCP05) + MEDIUM path-traversal-open-param (MCP05); the deployed container still replaces tool poisoning with command injection + arbitrary file read entirely, so the new rule correctly finds nothing tool-poisoning-shaped here |
| 3 | Excessive Permission Scope | ✅ Hit, unchanged — 2× MEDIUM path-traversal-open-param (MCP05) on read_file/search_files' unrestricted open() |
✅ Hit, unchanged — MEDIUM path-traversal-open-param (read) + LOW path-traversal-open-param (write mode) on file_manager |
| 4 | Rug Pull Attack | ✅ Hit (new) — 2× HIGH static.description-mutation (MCP03): the poisoning mutation on get_weather_forecast.__doc__ (confidence 85 — the call-counter guard if call_count < 3: bonus applied) and the later reset in reset_challenge (confidence 65); plus the incidental CRITICAL secret-aws-key (MCP01) noted previously |
❌ Miss, unchanged — 0 findings beyond generic auth; the deployed variant still strips out both the secret text and the mutation logic |
| 5 | Tool Shadowing | ❌ Miss, still — dynamic scan still can't connect (server.py still crashes on the listed=False bug above); static analysis catches the same unrelated pre-existing issues as before (4× CRITICAL dangerous-eval-exec, 2× CRITICAL secret-stripe-key, MCP05/MCP01) plus, new this run, 2× HIGH static.tool-description-injection (MCP03) — one each on malicious_server's calculate and combined_server's enhanced_calculate, the two tools actually carrying <HIDDEN> concealment payloads. A real, correct catch of that payload on both shadowing-tool variants, but the scanner still has no rule for the name-collision shadowing mechanism itself, which is the named vulnerability |
❌ Miss, unchanged — only a MEDIUM dynamic.fuzz-timeout on get_user_roles; the deployed variant is a different role-check server, not the shadowing calculators |
| 6 | Indirect Prompt Injection | ❌ Miss, unchanged — no finding relates to unsanitized external/document data | ❌ Miss, unchanged — same |
| 7 | Token Theft | ✅ Hit (new) — 3× HIGH static.secret-jwt + 3× MEDIUM static.secret-generic-credential (MCP01), directly on the hardcoded access_token/api_key values in the tokens dict. Deliberate, accepted miss preserved: the refresh_token values (rt_...) are not caught, since rt isn't followed by the literal word api/key/token/sk — broadening that pattern was rejected as raising false-positive risk on ordinary identifiers |
❌ Miss, still — but for a different reason than "no matching pattern": this deployed variant doesn't hardcode any tokens at all. It implements a distinct vulnerability (predictable MD5 session-token generation in authenticate/verify_token) that no secret-pattern rule could ever catch, hardcoded-credential or not |
| 8 | Malicious Code Execution | ✅ Hit, unchanged — CRITICAL subprocess-shell-true (MCP05) on execute_shell_command + MEDIUM path-traversal-open-param (MCP05) on analyze_log_file (plus an incidental CRITICAL secret-aws-key and 2 dynamic fuzz-timeouts on execute_python_code, not central to the named vulnerability) |
✅ Hit, unchanged — CRITICAL dangerous-eval-exec (MCP05); deployed variant's evaluate_expression calls eval() directly |
| 9 | Remote Access Control | ✅ Hit, unchanged — 4× CRITICAL subprocess-shell-true (MCP05) across the network-diagnostic tools |
❌ Miss, unchanged — deployed variant still replaces the shell-exec tools with a broken-auth-token-check simulation (if auth_token: truthy check, no shell calls at all). One MEDIUM static.tool-description-injection fired on remote_access's docstring but is a false positive — see the new-limitation note above — so this row stays a Miss |
| 10 | Multi-Vector Attack | ⚠️ Partial, substantially deeper — now 4 of 5 explicitly chained vulnerabilities have direct evidence: CRITICAL subprocess-shell-true and MEDIUM path-traversal-open-param (unchanged from before), plus (new) 3× HIGH static.secret-jwt on the hardcoded admin_token/service_token/user_token dict feeding the token-leakage-in-output vulnerability, and 2× HIGH static.tool-description-injection on get_user_profile (explicitly commented VULNERABILITY 2 in the source) and malicious_check_system_status's poisoned descriptions. Still missed: tool-name shadowing itself (malicious_check_system_status mimicking check_system_status) — no rule looks at name similarity between tools, so the poisoned description on that tool is caught but the shadowing relationship is not |
⚠️ Off-label hit, unchanged — 2× MEDIUM path-traversal-open-param (MCP05) on get_config; the deployed variant still only implements one vulnerability (file read), not an actual multi-vector chain |
(Every finding above also produced a generic HIGH auth.no-mechanism-detected (MCP07) — omitted from each cell for brevity; it fired on all 10 challenges both ways.)
False-positive testing: re-ran static analysis (the only module touched this session) against the same 3 clean servers from the official SDK's examples/ — mcpserver/simple_echo.py, servers/simple-prompt, servers/simple-pagination — cloned fresh. 0 findings on all 3 from any rule, old or new (no false secret/JWT/generic-credential/eval/subprocess/traversal/Unicode/description-injection/description-mutation matches). Dynamic and auth-posture results for these 3 servers are unchanged from 2026-08-19 (see that run's notes below) since no dynamic-analysis or auth-posture code was touched this session.
2026-08-19 false-positive testing notes (dynamic/auth-posture, unchanged this session)
Ran full --mode both scans (static + stdio dynamic, fuzzing on) against the 3 clean servers. Dynamic analysis: while testing simple-prompt (a prompts-only server with no tools/resources capability), a real trustmcp bug surfaced — dynamic_client.py's _enumerate_session() called list_tools()/list_resources()/list_prompts() unconditionally with no per-call exception handling, so a server correctly declining an unsupported capability (JSON-RPC "Method not found") was misreported as a HIGH-severity connection failure. Fixed in that session (_list_capability() now catches MCPError with code METHOD_NOT_FOUND per call and records it as a passed check, not a finding); all 3 clean servers correctly showed 0 vulnerability findings. All 3 also triggered a generic "no authentication mechanism" HIGH finding, which is accurate but fires on any unauthenticated local stdio server regardless of context — not counted as a false positive, but worth knowing it inflates finding counts for local dev/example servers.
Known limitation this run confirms (narrowed, not closed): the three new rules catch tool poisoning and rug-pull description mutation when they use one of a specific set of shapes — a pseudo-tag, a concealment phrase, a role-spoofing line, or a literal .__doc__/.description reassignment. A more careful adversary who phrases the same intent in plausible, tag-free natural language, or mutates behavior without ever touching __doc__/description, is still structurally invisible to pattern matching — that gap, plus indirect prompt injection from runtime-loaded document/resource content (never a decorator description, so out of scope for these rules entirely), is exactly what the paid semantic module (see Enterprise tier below) is for. Regex-based secret detection also has a fixed pattern list and a shape-based heuristic for the rest; a credential that matches neither (DVMCP's own refresh_token: "rt_..." being a documented example) won't be caught.
🏢 Enterprise / SaaS Tier
Everything above is free, open source, and stays that way. It's a genuinely complete scanner on its own — static analysis, live dynamic probing with input fuzzing, authentication posture, unified scoring, and SARIF/JSON reporting.
The paid tier builds on top of it with capabilities that go beyond what a single, stateless scan can offer:
- Semantic (LLM) analysis — sends every tool/resource/prompt description to an LLM with a strict, conservatively calibrated rubric to catch what regex cannot: naturally phrased hidden instructions, ambiguous scope, and language attempting to dictate model behavior.
- Cross-server toxic-flow detection — real AI agents connect multiple MCP servers simultaneously; a file-reading server plus a network-calling server can form an exfiltration channel even though each looks harmless alone. Single-server scans, by definition, cannot see this.
- Continuous monitoring — a one-time scan cannot catch a rug pull: a server that passes review cleanly, then changes its tool descriptions or scope after gaining trust. This requires fingerprinting + a saved baseline + drift alerting across scans over time.
- API access for CI/CD integration beyond static SARIF, and a verified, embeddable README badge for MCP registries.
The free tier's trustmcp/core/plugins.py defines the extension point these capabilities plug into — the architecture already supports them; they are simply not distributed in this open-source package.
📩 Interested in early access? Open an issue or contact @v0idw4lker.
🧪 Quick Testing
git clone https://github.com/v0idw4lker/trustmcp
cd trustmcp
pip install -r requirements.txt
# Static scan on this repo itself (fixtures/ is intentionally vulnerable)
trustmcp scan --path . --mode static
# Full pipeline against a fixture server
trustmcp scan --path . --mode both --target "stdio:python3 fixtures/target_server_stdio.py"
# Two fixture servers at once — a good demo of live multi-target scanning
trustmcp scan --path . --mode both \
--target "stdio:python3 fixtures/vulnerable_server_a.py" \
--target "stdio:python3 fixtures/vulnerable_server_b.py"
Running the test suite
pip install -e ".[dev]"
pytest
🗺️ Roadmap
- Published detection-rate + false-positive-rate validation against known-vulnerable and clean MCP server benchmarks — see Validation (2026-08-19, re-run 2026-08-21)
- Complete OAuth 2.1 flow for authenticated dynamic scanning
- Semantic analysis, cross-server toxic-flow, and continuous monitoring (paid tier)
- Listing on
awesome-mcp-securityand official MCP registries
Project Structure
trustmcp/
├── trustmcp/ # installable package — the free tier
│ ├── cli.py # entrypoint: `trustmcp scan --path ... --mode both`
│ ├── core/
│ │ ├── models.py # shared Finding contract used by every module + reporter
│ │ ├── text_safety.py # hidden/obfuscated Unicode detection (shared static + dynamic)
│ │ ├── static_analyzer.py # AST/regex SAST, secrets, dependency auditing
│ │ ├── dynamic_client.py # live MCP client — stdio/HTTP, enumeration, TLS/auth, fuzzing
│ │ ├── auth_posture.py # OAuth 2.1 / static key / env-var token detection
│ │ ├── scoring.py # A-F scoring engine + OWASP MCP Top 10 mapping
│ │ └── plugins.py # extension point for premium modules (unused in the free tier)
│ ├── reporters/
│ │ ├── cli_reporter.py # color-coded terminal report
│ │ ├── json_reporter.py # structured JSON for CI/CD
│ │ └── sarif_reporter.py # SARIF 2.1.0 export for GitHub Security
│ └── utils/ # logging + exception hierarchy
├── fixtures/ # intentionally vulnerable test MCP servers
├── tests/ # pytest suite + clean/vulnerable fixture modules
└── premium/ # LOCAL ONLY, gitignored — see "Enterprise / SaaS Tier" above
License
MIT — see LICENSE.
Built by @v0idw4lker.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file trustmcp-0.1.2.tar.gz.
File metadata
- Download URL: trustmcp-0.1.2.tar.gz
- Upload date:
- Size: 61.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
212afe05b98edf58f0a211289c933f0d7c9405a08b48363457a7b6c21e1d621a
|
|
| MD5 |
7d3eb81d00879ca86d600f2066744863
|
|
| BLAKE2b-256 |
940397e8eed0dbee59063ea93e63bc53bf9c121bdcbc637fde613a49e3c52315
|
Provenance
The following attestation bundles were made for trustmcp-0.1.2.tar.gz:
Publisher:
publish.yml on v0idw4lker/trustmcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
trustmcp-0.1.2.tar.gz -
Subject digest:
212afe05b98edf58f0a211289c933f0d7c9405a08b48363457a7b6c21e1d621a - Sigstore transparency entry: 2546188300
- Sigstore integration time:
-
Permalink:
v0idw4lker/trustmcp@00bef4ea2314e5e1cbc19fec82dc3ae78134e0b8 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/v0idw4lker
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@00bef4ea2314e5e1cbc19fec82dc3ae78134e0b8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file trustmcp-0.1.2-py3-none-any.whl.
File metadata
- Download URL: trustmcp-0.1.2-py3-none-any.whl
- Upload date:
- Size: 57.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7794c88f6239c0cf3f4dda8c57c3df4c979500ab40821eb7ef206b26f0783495
|
|
| MD5 |
e1f184d31c428186581513cff7f78553
|
|
| BLAKE2b-256 |
3d25264141d61333b847e8bc0d34d8bd71b09780f95f01f072a49657d125ebd9
|
Provenance
The following attestation bundles were made for trustmcp-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on v0idw4lker/trustmcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
trustmcp-0.1.2-py3-none-any.whl -
Subject digest:
7794c88f6239c0cf3f4dda8c57c3df4c979500ab40821eb7ef206b26f0783495 - Sigstore transparency entry: 2546188624
- Sigstore integration time:
-
Permalink:
v0idw4lker/trustmcp@00bef4ea2314e5e1cbc19fec82dc3ae78134e0b8 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/v0idw4lker
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@00bef4ea2314e5e1cbc19fec82dc3ae78134e0b8 -
Trigger Event:
push
-
Statement type: