Skip to main content
Glama
yriveiro
by yriveiro
README.md
# python-mcp

A Model Context Protocol (MCP) server for Python code-quality checks with token-efficient output.

## Overview

python-mcp gives LLMs direct access to linting, formatting, type checking, security, dependency, test-collection, dead-code, and spelling checks. Tool output is parsed structurally and reduced to compact diagnostics before it reaches the model.

## Features

- **ruff_check** - Lint files, glob patterns, or everything; `changed_only` checks just the files touched in git
- **ruff_format** - Verify formatting without modifying files
- **ty_check** - Type-check with concise output and an optional `error`/`warning` severity filter
- **vulture_check** - Find unused code and other dead-code candidates
- **bandit_check** - Find common Python security problems
- **deptry_check** - Find missing, unused, obsolete, and misplaced dependencies
- **pytest_collect** - Verify that tests can be collected without executing them
- **codespell_check** - Find likely spelling mistakes in source and documentation
- **pydoclint_check** - Check docstrings against function signatures
- **Structured parsing** - ruff JSON and ty GitLab code-quality output avoid fragile parsing of human-readable text
- **Adaptive aggregation** - large result sets include rule/file rollups before flat diagnostics, reducing repeated context
- **changed_only** - Check only staged, unstaged, and untracked Python files (`*.py`, `*.pyi`)

## How It Works

python-mcp implements the [Model Context Protocol](https://modelcontextprotocol.io) to expose nine read-only tools. All tools return a `CheckResult` with token-efficient `output` text and the underlying `exit_code`.

### Tools

- `ruff_check(paths?, changed_only?)` - Run ruff linting
- `ruff_format(paths?, changed_only?)` - Run `ruff format --check`
- `ty_check(paths?, level?, changed_only?)` - Run `ty check --output-format concise`, filtering by `all` / `error` / `warning`
- `vulture_check(paths?, changed_only?)` - Run vulture dead-code analysis
- `bandit_check(paths?, changed_only?)` - Run Bandit security analysis
- `deptry_check(paths?, changed_only?)` - Run deptry dependency analysis
- `pytest_collect(paths?, changed_only?)` - Collect tests without running them
- `codespell_check(paths?, changed_only?)` - Run codespell spelling analysis
- `pydoclint_check(paths?, changed_only?)` - Run pydoclint docstring analysis

### Output Processing

| Command | Input format | Output |
|---|---|---|
| `ruff check` | JSON | Compact grouped output; large runs get rule/file rollups |
| `ruff format --check` | Concise text | One line per unformatted file |
| `ty check` | GitLab JSON | Compact grouped output; severity filter applied |
| `vulture` | Concise text | Compact grouped dead-code findings |
| `bandit` | JSON | Compact grouped security findings |
| `deptry` | ANSI-free text | Compact grouped dependency findings |
| `pytest --collect-only` | Concise text | Collected test IDs or collection errors |
| `codespell` | Concise text | Compact spelling findings with suggestions |
| `pydoclint` | Concise text | Compact docstring-signature violations |

Small and medium result sets use the plugin-compatible grouped layout because it has lower overhead. Large result sets switch to an rtk-like layout with `Top rules`, `Top files`, and flat diagnostic lines. This addresses rtk's large-result advantage without adding an external runtime dependency.

## Usage

To start the server:

```bash
uvx python-mcp
```

Or from a checkout:

```bash
uv run python-mcp
```

Configure an MCP client to launch the server in the project directory to check, e.g. for opencode:

```json
{
  "mcp": {
    "python-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["python-mcp"]
    }
  }
}
```

The server checks the project in its working directory. To target another directory, set `PYTHON_MCP_PROJECT_DIR`.

### Agent Skill

Install the bundled `python-mcp` skill in a project when the agent client
discovers skills from `.agents/skills`:

```bash
uvx python-mcp skill install python-mcp --target .
```

The skill directs agents to the server's nine read-only tools:
`ruff_check`, `ruff_format`, `ty_check`, `vulture_check`, `bandit_check`,
`deptry_check`, `pytest_collect`, `codespell_check`, and `pydoclint_check`.
It does not describe uv package
or environment management.

### Configuration

Environment variables, all optional:

- `PYTHON_MCP_LOG_LEVEL` - Logging level, default `INFO`
- `PYTHON_MCP_PROJECT_DIR` - Project directory to check, default: server working directory
- `PYTHON_MCP_COMMAND_PREFIX` - Prefix for native ruff/ty/vulture invocations, default `uv run`; set to empty to use binaries from `PATH`
- `PYTHON_MCP_COMMAND_TIMEOUT` - Optional command timeout in seconds

## Development

This project is built with [FastMCP](https://github.com/PrefectHQ/fastmcp) and [uv](https://github.com/astral-sh/uv).

```bash
uv sync --extra dev
uv run ruff check
uv run ty check
uv run pytest
```

TDQS

A3.6/5.0

Scored across 9 tools

Disambiguation5/5

Each tool maps to a distinct well-known Python quality concern: linting, formatting, type checking, dead code, security, dependencies, test discovery, spelling, and docstrings. There is no meaningful overlap between tools despite several sharing a 'check' suffix.

Naming Consistency5/5

All tool names follow a consistent lowercase snake_case pattern of <tool>_<action>, with 'check' used for most tools and 'format'/'collect' used only where semantically appropriate. The convention is predictable and easy to infer.

Tool Count5/5

Nine tools is a well-scoped size for a Python code-quality server. Each tool covers a major independent concern without unnecessary redundancy or bloat.

Completeness5/5

The tool surface covers the core Python quality-checking lifecycle: linting, formatting validation, type checking, dead-code analysis, security scanning, dependency validation, test discovery, spelling, and docstring consistency. No critical gaps are apparent for the evident check-oriented purpose.

Maintenance

ActivitySlowing
ResponsivenessNo issues