reizan-mcpcheck
reizan-mcpcheck is the fail-closed authorization conformance checker the
official MCP conformance suite does not cover. It probes MCP HTTP
authorization implementations for the MCP-2026 OAuth hardening requirements
with deterministic PASS/FAIL/INCONCLUSIVE verdicts, exact HTTP evidence, and
SHA-256-attested transcripts. No LLM is used in the verdict path.
This v0 tracks the draft MCP authorization specification as of 2026-06-26, targeting the MCP-2026 final release expected on 2026-07-28.
Scope and authorization
Use this only against MCP servers, authorization servers, and test fixtures that you own or are explicitly authorized to assess. Reports contain exact request and response evidence, including bearer tokens from the run.
reizan-mcpcheck is not a vulnerability scanner for third-party systems. The
target config requires "owner_authorized": true so CI jobs make that boundary
explicit.
Probes
resource_param_mandatory: verifies thatresourceis sent in both the authorization request and token request, then checks that omitting it is rejected fail-closed.rfc9207_iss_validation: validates the authorization responseissagainst the configured issuer using exact string comparison, with no URI normalization.token_not_replayable_across_services: mints a token for resource A and verifies that resource B rejects it.fail_closed_missing_invalid_resource_or_audience: verifies rejection for invalid resource indicators, missing Authorization, invalid bearer tokens, and wrong-audience tokens.
Each probe returns a deterministic verdict and a transcript_sha256 over the
canonical JSON representation of the exact HTTP request/response transcript.
The top-level report also includes a report_sha256.
Install
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
CLI
reizan-mcpcheck examples/compliant.json --json
reizan-mcpcheck examples/compliant.json --out reports/mcpcheck.json
Exit codes:
0: no probe returned FAIL.1: one or more probes returned FAIL.2: config or invocation error.
Use --fail-on-inconclusive if CI should also reject INCONCLUSIVE probes.
Target config
{
"name": "my-owned-mcp-lab",
"owner_authorized": true,
"allow_insecure_http": false,
"authorization_server": {
"issuer": "https://auth.example.test",
"authorization_endpoint": "https://auth.example.test/oauth/authorize",
"token_endpoint": "https://auth.example.test/oauth/token",
"authorization_response_iss_parameter_supported": true
},
"client": {
"client_id": "mcpcheck",
"redirect_uri": "http://127.0.0.1:65535/callback",
"scope": "mcp:tools"
},
"resources": [
{
"name": "service-a",
"resource": "https://mcp-a.example.test/mcp",
"endpoint": "https://mcp-a.example.test/mcp"
},
{
"name": "service-b",
"resource": "https://mcp-b.example.test/mcp",
"endpoint": "https://mcp-b.example.test/mcp"
}
],
"invalid_resource": "https://mcp-a.example.test/not-a-valid-resource"
}
The v0 runner assumes a noninteractive authorization endpoint that redirects with an authorization code. Browser/login-driven flows may return INCONCLUSIVE unless wrapped by a self-run lab harness.
Deterministic demo
make demo
The demo starts two local, key-free fixtures:
http://127.0.0.1:8765: compliant fixture, expected PASS.http://127.0.0.1:8766: deliberately misconfigured fixture, expected FAIL.
It writes:
examples/compliant.jsonexamples/misconfigured.jsonreports/demo-compliant.jsonreports/demo-misconfigured.json
Tests
make test
References
- MCP draft authorization spec: https://modelcontextprotocol.io/specification/draft/basic/authorization
- RFC 8707, Resource Indicators for OAuth 2.0: https://www.rfc-editor.org/rfc/rfc8707
- RFC 9207, OAuth 2.0 Authorization Server Issuer Identification: https://www.rfc-editor.org/rfc/rfc9207
- Official MCP conformance package: https://github.com/modelcontextprotocol/conformance
Metadata
Release files for reizan-mcpcheck 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| reizan_mcpcheck-0.1.0.tar.gz | 19.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| reizan_mcpcheck-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.1 kB
Release files / reizan_mcpcheck-0.1.0.tar.gz
| Download URL | reizan_mcpcheck-0.1.0.tar.gz |
|---|---|
| Size | 19.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b85da04d16e3f1fb3a80cc8ff22d54bb6eb3990f46d0f48e41843b00434f75df
|
|
BLAKE2b-256 checksum How to use checksums |
9a91e10381298ebef0edd7ac783f8b817b8482ca3d363f1d6a25997b5ac4ede9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / reizan_mcpcheck-0.1.0-py3-none-any.whl
| Download URL | reizan_mcpcheck-0.1.0-py3-none-any.whl |
|---|---|
| Size | 21.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f2729a718497a7752ff8e901d771cf784467674f3e1674611ac5fef84dd90312
|
|
BLAKE2b-256 checksum How to use checksums |
c734f90ad2c46c96178c8a21618b666d7661ef5b78153e94aba5733234407031
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|