Skip to main content
Glama
MSPbotsAI

pax8-mcp

by MSPbotsAI
README.md
# pax8-mcp

Stateless HTTP MCP service for the [Pax8 Partner API](https://devx.pax8.com/reference/findcompanies). Exposes Pax8 data as MCP tools so AI assistants can query companies, subscriptions, invoices, orders, products, and usage data.

## Architecture

- **Stateless** — no user state or credentials stored between requests
- **Per-request auth** — access token passed via `X-Pax8-Token` header on every call
- **Concurrent-safe** — Python `contextvars` isolate credentials across parallel requests
- **Transports** — HTTP (production) or stdio (development)

## Endpoints

| Endpoint | Description |
|----------|-------------|
| `POST /mcp` | MCP protocol entry point (JSON-RPC) |
| `GET /health` | Health check |

Default port: **8080**

## Authorization

Pass your Pax8 access token in every `/mcp` request:

```
X-Pax8-Token: <your_access_token>
```

The service forwards the token as `Authorization: Bearer <token>` to the Pax8 API. Tokens are never stored globally — each request is fully isolated.

## Tool List

| Tool | Description | Key Parameters |
|------|-------------|----------------|
| `pax8_list_companies` | List companies in the partner account | `page`, `size`, `sort`, `name` |
| `pax8_list_company_contacts` | List contacts for a company | `company_id`, `page`, `size` |
| `pax8_list_subscriptions` | List subscriptions | `page`, `size`, `sort`, `company_id`, `status`, `product_id` |
| `pax8_list_subscription_usage_summaries` | List usage summaries for a subscription | `subscription_id`, `page`, `size` |
| `pax8_list_invoices` | List invoices | `page`, `size`, `sort`, `company_id`, `status` |
| `pax8_list_invoice_items` | List line items for an invoice | `invoice_id`, `page`, `size` |
| `pax8_list_orders` | List orders | `page`, `size`, `sort`, `company_id`, `status` |
| `pax8_list_products` | List products in the Pax8 marketplace | `page`, `size`, `sort`, `vendor_name`, `product_name` |
| `pax8_list_usage_summary_lines` | List usage lines for a usage summary | `usage_summary_id`, `page`, `size` |

### Parameter Details

**Pagination** (all list tools):
- `page` — zero-based page number (default: `0`)
- `size` — results per page (default: `10`)
- `sort` — field and direction, e.g. `"name,asc"` or `"createdDate,desc"`

**`pax8_list_subscriptions` status values:**
`Active`, `Cancelled`, `PendingManual`, `PendingAutomated`, `PendingCancel`, `Terminated`, `Expired`, `Trial`

## Quick Start

### Local development (env mode)

```bash
# Copy and edit environment config
cp .env.example .env
# Set PAX8_API_TOKEN and AUTH_MODE=env in .env

# Install dependencies
uv sync

# Run the server
MCP_TRANSPORT=http AUTH_MODE=env python -m pax8_mcp
```

### Docker (gateway mode — production)

```bash
docker build -t pax8-mcp .
docker run -p 8080:8080 -e AUTH_MODE=gateway pax8-mcp
```

Or with Docker Compose:

```bash
docker compose up
```

## Test Examples

**Health check:**

```bash
curl http://localhost:8080/health
# {"status":"ok","transport":"http","auth_mode":"gateway"}
```

**List companies:**

```bash
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "X-Pax8-Token: <your_access_token>" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "pax8_list_companies",
      "arguments": {"page": 0, "size": 5}
    }
  }'
```

**List subscriptions for a company:**

```bash
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "X-Pax8-Token: <your_access_token>" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "pax8_list_subscriptions",
      "arguments": {"company_id": "<company_uuid>", "status": "Active"}
    }
  }'
```

**List invoice items:**

```bash
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "X-Pax8-Token: <your_access_token>" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "pax8_list_invoice_items",
      "arguments": {"invoice_id": "<invoice_uuid>"}
    }
  }'
```

**List usage lines for a usage summary:**

```bash
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "X-Pax8-Token: <your_access_token>" \
  -d '{
    "jsonrpc": "2.0",
    "id": 4,
    "method": "tools/call",
    "params": {
      "name": "pax8_list_usage_summary_lines",
      "arguments": {"usage_summary_id": "<usage_summary_uuid>"}
    }
  }'
```

## Configuration Reference

| Variable | Default | Description |
|----------|---------|-------------|
| `PAX8_API_TOKEN` | — | Access token (env mode only) |
| `PAX8_BASE_URL` | `https://api.pax8.com/v1` | Pax8 API base URL |
| `PAX8_AUTH_HEADER` | `X-Pax8-Token` | MCP request header carrying the token |
| `MCP_TRANSPORT` | `stdio` | `http` for production, `stdio` for local dev |
| `MCP_HTTP_PORT` | `8080` | HTTP listen port |
| `MCP_HTTP_HOST` | `0.0.0.0` | HTTP listen host |
| `AUTH_MODE` | `gateway` | `gateway` (per-request, SOP-compliant) or `env` (dev only) |

TDQS

A3.7/5.0

Scored across 9 tools

Disambiguation5/5

Each tool targets a distinct entity (companies, contacts, invoices, subscriptions, etc.), so there is no overlap or ambiguity in purpose.

Naming Consistency5/5

All tools follow the exact same pattern 'pax8_list_<entity>', with clear and consistent naming conventions.

Tool Count5/5

With 9 tools, the set is well-scoped for a read-only listing API, covering all major data entities without excess.

Completeness3/5

The tool surface covers listing for all main entities but lacks any retrieval by ID, creation, update, or delete operations, making it incomplete for full CRUD/lifecycle coverage typical of a domain API.

Maintenance

ActivityMaintained
ResponsivenessNo issues