Scan an MCP endpoint in CI with the AdminKit GitHub Action
AdminKit ships a composite GitHub Action that scans one MCP endpoint for anonymous-access exposure on every push or a schedule, using the exact same open-source, read-only probe as the public MCP server's check_mcp_endpoint tool — no AdminKit account or API key required to run it.
By AdminKit team, Netbase JSC · Updated October 25, 2026
What this action checks
The action installs adminkit-mcp (the same package behind AdminKit’s public MCP server, see mcp/) at the exact commit your workflow pins, then runs its endpoint probe against one URL you give it. The probe only ever sends two JSON-RPC calls — initialize and tools/list — and never tools/call, so it is safe to point at a server that real clients are actively using. It checks for:
- the server accepting
initializewith no credentials at all (“no auth required”) - the tool list being readable anonymously once
initializesucceeds - tool names that look like they grant shell, file or network access (“dangerous tool exposed”)
- the endpoint not being served over TLS
and produces a 0-100 exposure score (lower is worse), a GitHub Actions job summary, and score / findings-json step outputs.
Add it to a workflow
name: Scan MCP endpoint
on:
push:
branches: [main]
schedule:
- cron: "0 6 * * 1" # weekly, Monday 06:00 UTC
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Scan our public MCP endpoint
id: scan
uses: NetbaseJSC/adminkit/integrations/github-action@main
with:
url: https://mcp.example.com/mcp
fail-on: critical
- name: Show the score
run: echo "AdminKit MCP exposure score: ${{ steps.scan.outputs.score }}"
This is the complete example shipped with the action itself (integrations/github-action/examples/scan-mcp-endpoint.yml in the AdminKit repository) — replace url with your own MCP endpoint and uses: with a pinned tag or commit SHA rather than @main once you’ve picked a version to rely on, since the action is not published to the GitHub Marketplace yet.
Inputs
| Input | Required | Default | What it does |
|---|---|---|---|
url | yes | — | MCP endpoint URL to scan. |
fail-on | no | critical | none never fails the step on findings; warning fails on any finding; critical fails on a high/critical-severity finding. |
api-key | no | "" | Reserved for future submission of results to the AdminKit dashboard. The probe is anonymous-only and never sends it to the scanned target. |
allow-private | no | false | Allow scanning a private/loopback target — only for CI jobs scanning a fixture server they started themselves. |
A scan that cannot reach url at all always fails the step, regardless of fail-on. A target refused for being private/loopback (allow-private: false) is reported as skipped and does not fail the step.
Outputs
| Output | Description |
|---|---|
score | 0-100 exposure score (lower is worse); empty if the target could not be reached. |
findings-json | JSON array: [{"id", "severity", "title", "detail", "fix_hint"}, ...]. |
- name: Scan
id: scan
uses: NetbaseJSC/adminkit/integrations/github-action@main
with:
url: https://mcp.example.com/mcp
fail-on: none
- run: echo "score was ${{ steps.scan.outputs.score }}"
Why run this instead of a one-off manual check
AdminKit’s MCP endpoint check tool page runs the identical check from a browser, but it still shows “coming soon” because its web front end is wired to the AdminKit Check API, which has not been deployed yet. The GitHub Action and the public MCP server’s check_mcp_endpoint tool both run the same open-source probe directly — no API dependency — which is exactly why they work today while the web page doesn’t yet. Running it in CI on every push, plus a weekly schedule, catches the case our guide to securing an MCP server calls out explicitly: exposure can change without anyone touching the server’s code, so a one-time check only tells you about right now.
Where AdminKit fits
The action’s own scanning logic is intentionally minimal and permanent: two anonymous JSON-RPC calls, nothing more. For enforcement rather than detection — blocking an unauthenticated call before it reaches your server, not just reporting that one got through — AdminKit’s planned MCP & Agent Gateway sits in front of the server itself; it is in early access and not live yet, so this action’s CI check remains the practical way to catch regressions today. See our AI agent builders page for the fuller picture of what’s free now versus planned.
This guide is general information, not a security audit of your specific network — see our disclaimer for what AdminKit's guidance does and does not commit to.
Frequently asked questions
Do I need an AdminKit account to use this action?
No. The scan itself is anonymous and needs no API key. The action does accept an optional api-key input, but it is reserved for a future dashboard-submission feature and is never sent to the scanned target today.
Is this action published on the GitHub Marketplace?
Not yet — pin your workflow to a tag or commit SHA of the NetbaseJSC/adminkit repository (uses: NetbaseJSC/adminkit/integrations/github-action@main, or a specific ref) rather than a Marketplace listing.
Can this action call tools on my MCP server, not just check it?
No. It only ever sends initialize and tools/list — the same two calls the public MCP server's own probe sends. It never sends tools/call, so it is safe to run against a server that is actually in use.
What does fail-on actually control?
none never fails the step on findings; warning fails on any finding; critical (the default) fails only on a high or critical severity finding. A target that cannot be reached at all (DNS failure, connection refused, timeout) always fails the step, independent of fail-on, because that is a different signal than 'findings below threshold'.
Will this action check more than MCP exposure in the future?
Scope today is MCP endpoint exposure only. API-backed checks (DNS, mail auth, TLS, port exposure) are planned once the Check API is live — see the OpenAPI reference for what is contracted but not yet deployed.
Related tools
Want AdminKit to watch this for you?
Free checks tell you the state today. Protective DNS and monitoring tell you when it changes.