Skip to main content
Glama
nitish-iiitd

API Doctor MCP

by nitish-iiitd
README.md
# API Doctor MCP

A deterministic, stateless MCP server for validating OpenAPI documents, JSON Schemas, and JSON payloads.

It uses Python libraries only. It does not call an LLM, persist user data, or require login.

## Current tools

- `validate_openapi`
- `list_openapi_endpoints`
- `compare_openapi_specs`
- `view_openapi_breaking_changes`
- `view_openapi_validation_card`
- `validate_json_schema`
- `validate_payload`

## Architecture

```text
MCP transport
    -> ServerFactory
        -> ToolProvider discovery
            -> Handlers
                -> Services
                    -> Validators / Comparators
```

Important properties:

- **Stateless:** no database, sessions, cache, or persistent files.
- **Open/Closed:** add a new `IToolProvider` implementation; discovery registers it automatically.
- **Dependency Inversion:** handlers depend on service interfaces, not concrete libraries.
- **Strategy:** parsers, validators, and comparison rules are replaceable strategies.
- **Factory:** application and server creation are centralized.
- **Adapter:** third-party validation libraries are hidden behind internal interfaces.
- **Class-based:** application behavior is represented by classes and objects.
- **CamelCase Python filenames:** used as explicitly requested.

## Run locally

```bash
uv sync --extra dev
uv run uvicorn app.Main:app --host 0.0.0.0 --port 8085
```

MCP endpoint:

```text
http://localhost:8085/mcp
```

Health endpoint:

```text
http://localhost:8085/health
```

The server uses the MCP Python SDK v2 beta and exposes one Streamable HTTP application. Modern `2026-07-28` requests are sessionless. `stateless_http=True` also prevents legacy clients from creating retained HTTP sessions.

## MCP HTTP usage

The callable MCP endpoint is:

```text
http://localhost:8085/mcp
```

This server uses the modern stateless MCP HTTP format for protocol version `2026-07-28`.

Each MCP request is a single HTTP `POST` with:

- header `Content-Type: application/json`
- header `Accept: application/json, text/event-stream`
- header `mcp-protocol-version: 2026-07-28`
- header `mcp-method: <json-rpc-method>`
- header `mcp-name: <tool-name>` for `tools/call` requests
- JSON-RPC body containing `params._meta`

See [MCP_API.md](MCP_API.md) for complete request and response examples for:

- `tools/list`
- `validate_json_schema`
- `validate_payload`
- `validate_openapi`
- `list_openapi_endpoints`
- `compare_openapi_specs`
- `view_openapi_breaking_changes`

## MCP Apps

This repo now includes two MCP Apps:

- `view_openapi_breaking_changes`
- `view_openapi_validation_card`

It follows the MCP Apps pattern described in the official docs:

- the tool advertises `_meta.ui.resourceUri`
- the server exposes a `ui://...` resource
- the host fetches and renders the bundled HTML app in a sandboxed iframe

The bundled app source lives in:

```text
mcp_apps/breaking-change-viewer/
```

Build the app bundle:

```bash
make app-build
```

The built artifact served by the Python MCP server is:

```text
mcp_apps/breaking-change-viewer/dist/mcp-app.html
```

### Test with basic-host

The easiest local host-level test path is the MCP Apps `basic-host`.

1. Start this server:

```bash
make run
```

2. In another folder, clone the MCP Apps repository and start the host:

```bash
git clone https://github.com/modelcontextprotocol/ext-apps.git
cd ext-apps/examples/basic-host
npm install
SERVERS='["http://localhost:8085/mcp"]' npm start
```

3. Open:

```text
http://localhost:8080
```

4. Select and call either `view_openapi_breaking_changes` or `view_openapi_validation_card`

When the host calls the tool, it should fetch the `ui://...` resource and render the inline app. The validation card is intentionally small and is useful as a lightweight MCP Apps demo.

## Test

```bash
uv run pytest
uv run ruff check .
uv run mypy app
```

## Docker

```bash
docker compose up --build
```

## Add a tool without modifying existing code

1. Add a service interface and implementation, when needed.
2. Add a handler class.
3. Add a concrete class implementing `IToolProvider` under `app/ToolProviders`.
4. Give the provider a parameterless constructor.
5. The provider-discovery mechanism imports and registers it automatically.

Providers receive the application `ServiceContainer` during registration.

## Production note

The pinned MCP SDK is a prerelease. Upgrade the exact pin deliberately after testing API changes.