CI-first conformance, security, and benchmarking CLI for MCP servers. Lint your MCP server before your users do.
Project description
mcp-halflist
CI-first conformance, security, and benchmarking CLI for MCP servers.
Lint your MCP server before your users do.
What It Does
Point it at any MCP server (stdio or HTTP) and get a scored conformance report, security vulnerability scan (prompt injection, tool poisoning, data exfiltration), and per-tool latency benchmarks. Fully offline, zero API keys, CI-native. One pip install, one command, done.
See It In Action
Terminal output:
HTML reports: Check report · Bench report · Audit report
Install
pip install mcp-halflist
macOS users: use
python3instead ofpythonin server commands.
Quick Start
# Full audit of the official MCP reference server (runs instantly, no setup)
halflist audit --stdio "npx -y @modelcontextprotocol/server-everything"
# Security scan + conformance check
halflist check --stdio "npx -y @modelcontextprotocol/server-everything"
# Benchmark tool latency
halflist bench --stdio "npx -y @modelcontextprotocol/server-everything" --all
# Pin tools, then verify later for rug pull detection
halflist pin --stdio "npx -y @modelcontextprotocol/server-everything"
halflist check --stdio "npx -y @modelcontextprotocol/server-everything" --verify-pins
# Your own server
halflist audit --stdio "python3 my_server.py"
# HTTP transport (Streamable HTTP with SSE fallback)
halflist check --http http://localhost:8080/mcp
halflist audit --http http://localhost:8080/mcp
# HTTP with auth
halflist check --http https://mcp.example.com/v1 --header "Authorization: Bearer tok123"
# HTTP with OAuth2 client credentials
halflist audit --http https://mcp.example.com/v1 \
--oauth-token-url https://auth.example.com/token \
--oauth-client-id my-client \
--oauth-client-secret my-secret
# OAuth2 PKCE (automatic on 401, opens browser for authorization)
halflist check --http https://mcp.example.com/v1
# OAuth2 PKCE headless mode (prints URL instead of opening browser)
halflist check --http https://mcp.example.com/v1 --no-browser
# Skip automatic OAuth PKCE
halflist check --http https://mcp.example.com/v1 --no-auth
# Custom tool arguments for tools that need specific inputs
# args.json: {"get_user": {"user_id": "abc123"}}
halflist bench --http http://localhost:8080/mcp --tool get_user --args-file args.json
# More real servers to try
halflist check --stdio "npx -y @modelcontextprotocol/server-time"
halflist check --stdio "npx -y @modelcontextprotocol/server-filesystem /tmp"
CI Integration
JUnit XML output works with GitHub Actions, GitLab CI, Jenkins, and any CI system that supports JUnit test reporters:
# Generate JUnit XML for CI test reporters
halflist check --stdio "python3 server.py" --format junit -o results.xml
halflist audit --stdio "python3 server.py" --format junit -o audit.xml
Commands
| Command | What it does |
|---|---|
halflist check |
Protocol conformance + security scanning |
halflist bench |
Per-tool latency benchmarking (p50/p95/p99) |
halflist audit |
Combined check + bench in one shot |
halflist watch |
Continuous health monitoring |
halflist report |
Generate markdown, HTML reports, or SVG badges from JSON |
halflist pin |
Save tool hashes for rug pull detection |
See the full command reference for all flags and examples.
Security Scanning
halflist scans tool descriptions for prompt injection, data exfiltration instructions, cross-tool manipulation, suspicious encoding (base64, zero-width characters), and rug pull attempts via tool pinning. All scanning runs locally: zero API calls, zero data sharing. Unlike mcp-scan which sends tool descriptions to an external API, halflist runs entirely on your machine.
See security scanning details for the full list of detection patterns.
Debug Logging
# Enable debug output
halflist check --stdio "python3 server.py" --debug
# Save debug log to file
halflist audit --http https://example.com/mcp --debug-log debug.log
# Environment variable (useful in CI)
HALFLIST_LOG_LEVEL=DEBUG halflist audit --stdio "python3 server.py"
Configuration
Create a halflist.toml in your project root:
[server]
transport = "stdio"
command = "python3 my_server.py"
[check]
timeout = 30
[bench]
iterations = 20
args_file = "args.json"
Then just run:
halflist check
halflist audit
CLI flags override config values. Use ${ENV_VAR} for secrets:
[server.oauth]
client_secret = "${MCP_CLIENT_SECRET}"
Config file discovery order: halflist.toml (cwd) > .halflist.toml (cwd) > ~/.halflist/config.toml. Or pass --config path/to/file.toml explicitly.
Output Formats
Terminal (colored, default) · JSON (--format json) · JUnit XML (--format junit) · Markdown · HTML · SVG Badge
See the output format reference for details.
How It Compares
| Tool | Approach | Needs API key | Sends data externally |
|---|---|---|---|
| MCP Inspector | Interactive browser UI | No | No |
| mcp-probe | Interactive TUI (Rust) | No | No |
| mcp-server-tester | LLM-generated tests | Yes (Anthropic) | Yes |
| mcp-scan | Security scanning | Yes (OpenAI for local) | Yes (Invariant API) |
| mcp-halflist | CI-first check + security + bench | No | No |
Development
git clone https://github.com/abhishekhsingh/mcp-halflist.git
cd mcp-halflist
pip install -e ".[dev]"
ruff check src/ tests/
ruff format --check src/ tests/
pytest -v --tb=short
License
MIT
Author
Project details
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 mcp_halflist-1.0.0.tar.gz.
File metadata
- Download URL: mcp_halflist-1.0.0.tar.gz
- Upload date:
- Size: 576.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7fda7f915d5307dc7dfa73fd87f465390268d7f2558cdfe9b71f844732b8dcc3
|
|
| MD5 |
3fe256c40b45d86663531c5a7596b630
|
|
| BLAKE2b-256 |
b5818e6e3514bb5113e5b2de42c08f7763146e86b2092948b93535fd0ba91779
|
Provenance
The following attestation bundles were made for mcp_halflist-1.0.0.tar.gz:
Publisher:
publish.yml on abhishekhsingh/mcp-halflist
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_halflist-1.0.0.tar.gz -
Subject digest:
7fda7f915d5307dc7dfa73fd87f465390268d7f2558cdfe9b71f844732b8dcc3 - Sigstore transparency entry: 1666272768
- Sigstore integration time:
-
Permalink:
abhishekhsingh/mcp-halflist@a490a946f579b7ae6755429d3b9e8f4c61c8cdee -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/abhishekhsingh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a490a946f579b7ae6755429d3b9e8f4c61c8cdee -
Trigger Event:
release
-
Statement type:
File details
Details for the file mcp_halflist-1.0.0-py3-none-any.whl.
File metadata
- Download URL: mcp_halflist-1.0.0-py3-none-any.whl
- Upload date:
- Size: 49.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45616cd51effe9d7be091ec295d43e863d83463c4a46210e006eb586c4afa4aa
|
|
| MD5 |
e331f0ab0fffb61a655572dce7a3f34a
|
|
| BLAKE2b-256 |
4d580f69d200ea192faeabc27d9aa99e6ba8ce359c4390afb7f82c8d06649695
|
Provenance
The following attestation bundles were made for mcp_halflist-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on abhishekhsingh/mcp-halflist
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_halflist-1.0.0-py3-none-any.whl -
Subject digest:
45616cd51effe9d7be091ec295d43e863d83463c4a46210e006eb586c4afa4aa - Sigstore transparency entry: 1666272823
- Sigstore integration time:
-
Permalink:
abhishekhsingh/mcp-halflist@a490a946f579b7ae6755429d3b9e8f4c61c8cdee -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/abhishekhsingh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a490a946f579b7ae6755429d3b9e8f4c61c8cdee -
Trigger Event:
release
-
Statement type: