Metadata-Version: 2.4
Name: mcpvet
Version: 0.1.0
Summary: Test, lint, and vet your MCP servers — pytest + eslint + contract testing for MCP, in one CLI.
Project-URL: Homepage, https://github.com/holydement0r/mcpvet
Project-URL: Repository, https://github.com/holydement0r/mcpvet
Project-URL: Issues, https://github.com/holydement0r/mcpvet/issues
Author: joker
License: MIT
License-File: LICENSE
Keywords: ci,lint,mcp,model-context-protocol,testing
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.10
Requires-Dist: jsonschema>=4
Requires-Dist: mcp>=1.9
Requires-Dist: pydantic>=2
Requires-Dist: pyyaml>=6
Requires-Dist: rich>=13
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Description-Content-Type: text/markdown

# mcpvet

> Test, lint, and vet your MCP servers — pytest + eslint + contract testing for MCP, in one CLI.

[![ci](https://github.com/holydement0r/mcpvet/actions/workflows/ci.yml/badge.svg)](https://github.com/holydement0r/mcpvet/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/mcpvet.svg)](https://pypi.org/project/mcpvet/)

## Why

- **~40% of deployed MCP servers ship a broken tool** — an invalid schema, a missing description, or stdout that corrupts the protocol. Agents fail silently and you find out from a user.
- **Schema drift breaks agents without a stack trace.** Rename an argument, tighten a type, drop a tool — the client just stops calling it. Nothing errors. Nothing tells you.
- **Inspector is manual-only.** Great for poking at a server by hand, useless in CI. There's no `pytest` for MCP. Now there is.

`mcpvet` catches all three before they reach production, and it runs in your pipeline.

## Quickstart

```bash
pip install mcpvet          # or: uvx mcpvet ...

# Lint any server — command, URL, or client config
mcpvet lint -- npx -y @modelcontextprotocol/server-filesystem /tmp
mcpvet lint http://localhost:8000/mcp

# Write tests once, run them forever
mcpvet test mcpvet.test.yaml --format junit

# Catch breaking changes between releases
mcpvet snapshot -o v1.json -- python my_server.py
mcpvet diff v1.json "python my_server.py"
```

## Test suites

Declarative YAML — call a tool, assert on the result. No test harness to wire up.

```yaml
# mcpvet.test.yaml
target:
  command: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
tests:
  - name: list_directory returns entries
    tool: list_directory
    args: { path: "/tmp" }
    expect:
      - type: success
      - type: contains
        value: "tmp"
      - type: latency_under
        ms: 2000
  - name: bad path returns proper MCP error
    tool: list_directory
    args: { path: "/nonexistent" }
    expect:
      - type: error
        message_contains: "not found"
```

Expectation types: `success`, `error`, `contains`, `equals`, `regex`, `latency_under`, `jsonschema`.
Output formats: `pretty` (default), `json`, `junit`.

## Lint rules

| Rule  | Severity | Checks                                                            |
|-------|----------|------------------------------------------------------------------|
| MV101 | error    | `inputSchema` is not a valid JSON Schema                          |
| MV102 | warning  | `inputSchema` root `type` is not `"object"`                       |
| MV201 | error    | tool has no description — models can't choose it reliably         |
| MV202 | warning  | description is too short (< 10 chars) to be useful                |
| MV301 | error    | non-protocol output on stdout corrupts the stdio transport       |

## GitHub Action

```yaml
- run: pip install mcpvet
- run: mcpvet lint --format json -- python my_server.py
- run: mcpvet test --format junit > results.xml
```

## Exit codes

| Code | Meaning                                                    |
|------|------------------------------------------------------------|
| 0    | clean — no findings, all tests passed, no breaking changes |
| 1    | findings, test failures, or breaking changes detected      |
| 2    | execution error — couldn't reach or inspect the server     |

## Roadmap

- **record / mock** — record real server traffic, replay it as a mock in tests.
- **scan** — security heuristics: prompt-injection surface, over-broad tool scopes.
- **bench** — latency and throughput benchmarks with regression tracking.

## License

MIT
