Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ TESTOMATIO_PROJECT_ID=your_project_id_here
# Optional: API host.
# Default: https://app.testomat.io
# Use beta when needed:
# TESTOMATIO_HOST=beta.testomat.io
# Or set the full URL, which takes precedence over TESTOMATIO_HOST:
# TESTOMATIO_BASE_URL=https://beta.testomat.io
20 changes: 20 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Tests

on:
push:
branches: [main]
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 24

- run: npm install -g npm@latest
- run: npm ci
- run: npm test
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ jspm_packages/
dist/
build/

# Cloudflare Worker local state
.wrangler/
.dev.vars

# IDE files
.vscode/
.idea/
Expand Down
84 changes: 82 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,15 @@ export TESTOMATIO_PROJECT_ID=<PROJECT_ID>
testomatio-mcp
```

**Optional: custom base URL**
**Optional: custom host**
```bash
export TESTOMATIO_HOST=beta.testomat.io
testomatio-mcp --host beta.testomat.io
```

A bare hostname is expanded to `https://<host>`. For full control use
`--base-url` / `TESTOMATIO_BASE_URL`, which takes precedence over the host option:

```bash
export TESTOMATIO_BASE_URL=https://beta.testomat.io
```
Expand Down Expand Up @@ -151,6 +159,48 @@ Add this config to `opencode.json` in your project root, or to `~/.config/openco
}
```

## HTTP Transport

Besides stdio, the server runs over Streamable HTTP on a Cloudflare Worker hosted by
Testomat.io. The project is part of the URL, so every tool signature stays the same:

```
https://mcp.testomat.io/mcp/<project_id>
```

Point an MCP client at that URL with a project token:

```json
{
"mcpServers": {
"testomatio": {
"url": "https://mcp.testomat.io/mcp/<PROJECT_ID>",
"headers": {
"Authorization": "Bearer <PROJECT_TOKEN>"
}
}
}
}
```

Web connectors such as claude.ai have nowhere to put a static token and instead run
OAuth 2.1 with PKCE and Dynamic Client Registration against the same URL. Tokens
starting with `testomat_` or `tstmt_` always bypass OAuth and are passed straight
through, so IDE clients and CI keep working.

The endpoint is POST only; `GET` returns `405`, because the server never initiates
traffic. Testing with `curl` requires both media types in `Accept`:

```bash
curl -sS https://mcp.testomat.io/mcp/<PROJECT_ID> \
-H "Authorization: Bearer <PROJECT_TOKEN>" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
```

Self-hosted installations keep using stdio.

## Quick Examples

**List tests:**
Expand Down Expand Up @@ -232,7 +282,8 @@ src/
| `TESTOMATIO_PROJECT_TOKEN` | Yes* | - | Project token (preferred) |
| `TESTOMATIO_API_TOKEN` | Yes* | - | Alternative token |
| `TESTOMATIO_PROJECT_ID` | Yes | - | Project ID |
| `TESTOMATIO_BASE_URL` | No | `https://app.testomat.io` | API base URL |
| `TESTOMATIO_HOST` | No | - | API host, e.g. `beta.testomat.io` |
| `TESTOMATIO_BASE_URL` | No | `https://app.testomat.io` | API base URL, wins over `TESTOMATIO_HOST` |
| `TESTOMATIO_TOOLS` | No | `full` | Tool profile: `full`, `core`, or `read` |

*Either `TESTOMATIO_PROJECT_TOKEN` or `TESTOMATIO_API_TOKEN`
Expand Down Expand Up @@ -287,6 +338,7 @@ NODE_EXTRA_CA_CERTS=/path/to/company-root-ca.pem testomatio-mcp --token <TOKEN>
```bash
npm install
npm run start -- --token <TOKEN> --project <PROJECT_ID>
npm test
```

For local MCP development, point Claude Desktop to the checked-out entrypoint:
Expand Down Expand Up @@ -372,3 +424,31 @@ Example `analytics_charts_results` call:
}
}
```

### Worker deployment

The `worker/` directory holds the Cloudflare Worker and is excluded from the npm
package. Deploy it from that directory:

```bash
cd worker
npx wrangler kv namespace create OAUTH_KV
npx wrangler secret put TESTOMATIO_MCP_WORKER_SECRET
npx wrangler deploy
```

Put the namespace id returned by the first command into `kv_namespaces` in
`worker/wrangler.jsonc`. `TESTOMATIO_MCP_WORKER_SECRET` is the shared secret used to
redeem authorization codes against Testomat.io server-to-server and is never
committed.

A beta worker is the same code deployed to the `beta` environment, which targets
`https://beta.testomat.io` and keeps its own KV namespace so beta grants never
reach the production one:

```bash
npx wrangler kv namespace create OAUTH_KV --env beta
npx wrangler secret put TESTOMATIO_MCP_WORKER_SECRET --env beta
npx wrangler deploy --env beta
```

Loading
Loading