# Contributing to MCP Server for Propel

## Prerequisites

- Python 3.10+
- [uv](https://docs.astral.sh/uv/) (recommended) or pip

## Local Development Setup

```bash
git clone https://github.com/propel/mcp-server-propel.git
cd mcp-server-propel

# Install dependencies (including dev group)
uv sync --group dev
```

## Running the Server Locally

```bash
export PROPEL_API_TOKEN="your-token"

# Against production API
uv run mcp-server-propel

# Against local Propel API
export PROPEL_API_URL="http://localhost:6060"
uv run mcp-server-propel
```

## Testing with MCP Inspector

[MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector) lets you interact with the server without Claude Desktop:

```bash
uv run mcp dev src/mcp_server_propel/server.py
```

## Testing with Claude Desktop (local build)

Add this to your Claude Desktop config to point at your local checkout:

**MacOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "propel": {
      "command": "uv",
      "args": [
        "--directory", "/path/to/mcp-server-propel",
        "run", "mcp-server-propel"
      ],
      "env": {
        "PROPEL_API_TOKEN": "your-token",
        "PROPEL_API_URL": "http://localhost:6060"
      }
    }
  }
}
```

Restart Claude Desktop after updating the config.

## Running Tests

```bash
uv run pytest -v
```

## Project Structure

```
src/mcp_server_propel/
  __init__.py            # Package version
  server.py              # MCP server setup and lifespan
  propel_client.py       # Async HTTP client for Propel API
  tools/
    __init__.py
    review_tools.py      # Tool implementations (submit, get, check status)
```

## Publishing a New Release to PyPI

Before publishing, ensure the following checklist is complete:

- [ ] Version bumped in `pyproject.toml` **and** `src/mcp_server_propel/__init__.py` following [Semantic Versioning](https://semver.org) (`MAJOR.MINOR.PATCH`)
- [ ] Lock file regenerated: `uv lock`
- [ ] All tests pass: `uv run pytest -v`
- [ ] Git tag created and pushed: `git tag vX.Y.Z && git push origin vX.Y.Z`
- [ ] Package builds cleanly: `uv build`
- [ ] Local install verified: `uv pip install dist/*.whl`

Once the tag is pushed, the GitHub Actions workflow will automatically build and publish to PyPI via Trusted Publishing.

To publish manually using `uv`:

```bash
uv build
uv publish
```

`uv publish` will prompt for your PyPI API token, or you can set it via the `UV_PUBLISH_TOKEN` environment variable.

## Key Design Decisions

- **`from __future__ import annotations`** is used in all modules to allow modern type syntax while maintaining compatibility with the Python 3.10 floor set by the MCP SDK.
- **Polling in `get_review`**: The tool polls every 12 seconds for up to ~12 minutes. This is intentional — reviews take 5-10 minutes and the MCP protocol doesn't support server-initiated push notifications.
- **Retry with backoff** in `PropelClient._request`: Server errors (5xx) and timeouts are retried up to 3 times with exponential backoff.
- **Client-side validation** in `PropelClient.create_review`: Diff size, repository length, and base commit length are validated before making the API call to give faster, clearer error messages.
