Skip to main content
Glama
README.md
# api-mcp

[![npm version](https://img.shields.io/npm/v/@hassanjamal/api-mcp.svg)](https://www.npmjs.com/package/@hassanjamal/api-mcp)
[![npm downloads](https://img.shields.io/npm/dw/@hassanjamal/api-mcp.svg)](https://www.npmjs.com/package/@hassanjamal/api-mcp)
[![node](https://img.shields.io/node/v/@hassanjamal/api-mcp.svg)](https://nodejs.org)
[![license](https://img.shields.io/npm/l/@hassanjamal/api-mcp.svg)](./LICENSE)

> 📦 **Published on npm:** [`@hassanjamal/api-mcp`](https://www.npmjs.com/package/@hassanjamal/api-mcp)
> — install with `npm i -g @hassanjamal/api-mcp` (no cloning or building needed).

An **MCP (Model Context Protocol) server** you plug into any codebase — React Native, web,
Flutter, or a backend — that:

1. **Discovers** every API endpoint in the code (client calls *and* server routes)
2. **Reads or generates** an OpenAPI / Swagger spec (if none exists, it builds one)
3. **Generates** test cases + edge cases for each endpoint, based on its HTTP method and params
4. **Auto-logs in per role** (from just credentials — finds the login endpoint, extracts the token)
5. **Harvests real IDs** from responses + JWTs and injects the *right* resource id into each path param
6. **Executes** them against your running server — like Postman — scoped to each role's real permissions
7. **Reports** everything as **PDF + XLSX** (per-role + an overall audit + the endpoint inventory)

The **QA one-call** (`qa_audit`) does all of it from a project path + role logins. All artifacts are
written to a `.api-mcp/` folder inside the project you point it at.

---

## What it detects

| Platform | Frameworks / libraries detected |
| -------- | ------------------------------- |
| **Web** | `fetch`, `axios` (`.get/.post/…`, `axios({url,method})`, `.request()`, custom instances), Angular `HttpClient`, **RTK Query**, **SWR**, **jQuery** (`$.get/$.post/$.ajax`) |
| **React Native** | `fetch`, `axios`, `apisauce` (JS libraries, same detectors as web) |
| **Flutter / Dart** | `http` (`Uri.parse`/`Uri.https`), `Dio`, **Retrofit-dart** (`@GET`), **Chopper** (`@Get(path:)`) |
| **Mobile native** | **Retrofit** (Android/Kotlin `@GET`), **Alamofire** (iOS/Swift `AF.request`) |
| **Backend routes** | Express / Fastify / Koa `router`, NestJS decorators, FastAPI, Flask, Spring (`@GetMapping`) |

Detection is text/pattern based, so it works on any language without running the code, and
handles both `:param` / `{param}` / `<param>` styles and JS `${...}` / Dart `$var` interpolation.
Every framework above is covered by the regression suite (`npm test`) so accuracy can't silently
regress.

---

## Install

Install once, globally — this gives a fast, reliable `api-mcp` command:

```bash
npm i -g @hassanjamal/api-mcp
```

> Requires **Node.js 18+**. Global install is recommended over `npx` because `npx` re-checks
> the registry on every launch (~6s) and can trip a host's connection health-check; the global
> binary starts in ~1s.

---

## Connect it to a host

An MCP server does nothing on its own — a **host** (the app you chat with an AI in) connects to
it and exposes its tools. Pick your host:

### Claude Code

Register it once for **all** your projects (user scope):

```bash
claude mcp add -s user api-mcp -- api-mcp
```

Verify: `claude mcp list` → `api-mcp - ✔ Connected`. (Mind the spacing: `-- api-mcp`.)

### Cursor

Settings → **MCP** → *Add new server*, or edit `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "api-mcp": { "command": "api-mcp" }
  }
}
```

### Claude Desktop

Edit `claude_desktop_config.json` (Windows: `%APPDATA%\Claude\claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "api-mcp": { "command": "api-mcp" }
  }
}
```

Restart the host after editing config. The tools (and the `/qa-audit`, `/scan` slash commands)
then appear to the AI.

**Updating:** `npm i -g @hassanjamal/api-mcp@latest`

---

## Slash commands (Claude Code)

Two guided entry points show up as slash commands:

| Command | Does |
| ------- | ---- |
| `/qa-audit` | Prompts for base URL + role logins, then runs the full read-only per-role audit |
| `/scan` | Scans the current project and summarizes the endpoints found |

You can also just ask in natural language (see below) — the slash commands are a convenience.

---

## Tools exposed

| Tool | What it does |
| ---- | ------------ |
| `scan_endpoints` | Scan a project and list every endpoint found. Writes `discovery-report.md` + `endpoints.json`. |
| `detect_openapi` | Report any existing Swagger/OpenAPI spec in the project. |
| `generate_openapi` | Build an OpenAPI 3.0 spec from the code (JSON or YAML). Reuses an existing spec unless told otherwise. |
| `generate_tests` | Produce happy-path / edge / negative / security test cases. Writes `tests.json`. |
| `run_tests` | Execute the tests against your live server and save responses + a report. |
| `full_audit` | One call that runs the entire pipeline end-to-end. |
| `export_report` | Regenerate the **HTML** report + **colorful XLSX** from already-saved JSON. |
| `detect_base_url` | Auto-detect the API base URL from `.env` / axios / Dart config (web + mobile). |
| `login` | Auto-detect the login endpoint, post credentials, and extract the token. |
| `qa_audit` | **QA one-call:** role credentials → auto-login → role-scoped, precise-ID testing → **PDF + XLSX** reports. |

Once connected, just ask the AI in natural language, e.g.:

> "Run a full API audit on this project against http://localhost:3000 using my API_TOKEN."

The AI will call `full_audit` with the right arguments.

---

## QA workflow (the easy path)

A QA engineer provides only **credentials per role** — the tool figures out the rest
(base URL, login endpoint, token extraction, per-role runs):

> "Run a qa_audit on this project with admin `a@x.com / pw`, teacher `t@x.com / pw`,
> student `s@x.com / pw`."

`qa_audit` then:
1. **Detects the API base URL** from the code (`.env`, axios/Dart `baseURL`) — or you pass `baseUrl`
2. **Logs in as each role**, extracting the token from the response **or the JWT** (`token`, `accessToken`, `data.token`, `jwt`…)
3. **Harvests real resource IDs** from every response + each JWT and injects the *correct* id into each
   path param (`{courseId}` ← a real course id; a bare `{id}` ← that endpoint's own resource), preferring
   ids the current role can access — turning wrong-id `404`s into real `200`s
4. **Scopes each role** to endpoints its route-guard permits (reads `authorizeAdmin()`, `@Roles('teacher')`…),
   so you get more `200`s and far less `403`/`404` noise
5. **Skips session-breaking endpoints** (logout/refresh/delete-account/password/register) so a test can't
   revoke its own token, and **paces around rate limits** (marks throttled requests *not tested*, not failed)
6. **Writes PDF + XLSX only** — overall `qa-audit.pdf`, per-role `qa-report-{role}.pdf`/`.xlsx`, and
   `endpoints.pdf`/`.xlsx`

**Read-only by default.** Useful arguments:

| Argument | Default | Effect |
| -------- | ------- | ------ |
| `roles` | — | `[{role, email, password}]` per role to test |
| `baseUrl` | auto-detect | API base URL |
| `includeWrites` | `false` | also run POST/PUT/PATCH/DELETE (throwaway/staging only) |
| `roleScoped` | `true` | test each role only on endpoints its guard permits (`false` = full RBAC coverage) |
| `includeDestructive` | `false` | also test logout/refresh/delete-account/password/register |
| `maxRateLimitWaitMs` | `8000` | max pacing wait per request; raise (e.g. `900000`) for exhaustive coverage |

### Web vs mobile — what to provide

The tool always tests the **HTTP API**, so the inputs are the same for both. The only
difference is which source files get scanned for endpoints.

| | Web app | Mobile app (React Native / Flutter / native) |
| --- | ------- | -------------------------------------------- |
| Provide | API base URL* + role credentials | API base URL* + role credentials — **same** |
| Base URL source | frontend `.env` (`VITE_API_URL`…) | the app's config/constants (the backend it calls) |
| What's scanned | JS/TS (`fetch`, `axios`) | Dart (`http`, `Dio`), + native client libs |
| Execution | identical | identical |

### Understanding the results (why not all 200s?)

A **healthy** API returns a mix of status codes under automated testing — that's it correctly
guarding itself, not a sign it's broken. Each request passes gates in order; the status tells you
which gate stopped it:

| Status | Meaning | A problem? |
| ------ | ------- | ---------- |
| **200** | Worked — returned data | ✅ success |
| **400** | Request incomplete/malformed (missing query param, wrong id type) | ❌ No — validation *working* |
| **401** | Wrong identity for that endpoint | ❌ No — auth *working* |
| **403** | Role/owner not permitted | ❌ No — RBAC *working* (the inverse curve across roles proves it) |
| **404** | That resource doesn't exist for this user | ❌ No — correct "not found" |
| **500** | Server **crashed** (unhandled exception) | 🔴 **Yes — the real bug to fix** |

You can't (and shouldn't) get all-`200`s from automated testing — that would mean the API accepts
anything. **Only the `500`s indicate actual defects.**

*The base URL is auto-detected when possible; a mobile app has no "app URL" of its own —
you give the **backend API URL** it talks to (which lives in the app's config).

## Configuration

Live execution needs to know your server URL and auth. Provide it either **per tool call**
(`baseUrl`, `bearerToken`, `headers` arguments) or via a config file in the target project root.

Copy `api-mcp.config.example.json` to `api-mcp.config.json`:

```json
{
  "baseUrl": "http://localhost:3000",
  "bearerToken": "${API_TOKEN}",
  "headers": { "X-Api-Key": "${API_KEY}" },
  "timeoutMs": 15000,
  "sampleValues": { "id": 1, "body": { "name": "example" } }
}
```

`${ENV_VAR}` references are expanded from the environment, so secrets stay out of the file.
Secret-looking headers are redacted in saved reports.

---

## Output artifacts (`.api-mcp/`)

| File | Contents |
| ---- | -------- |
**`qa_audit` writes PDF + XLSX only:**

| File | Contents |
| ---- | -------- |
| `qa-audit.pdf` | **Overall report** — KPIs, role matrix, and a "how to read the statuses" guide |
| `qa-report-{role}.pdf` / `.xlsx` | Per-role results (status summary + full request/response table) |
| `endpoints.pdf` / `endpoints.xlsx` | The discovered-endpoint inventory |

**The other tools** (`scan_endpoints`, `generate_openapi`, `run_tests`, `full_audit`) also write:

| File | Contents |
| ---- | -------- |
| `discovery-report.md` / `.html` | Endpoint inventory (Markdown + color-coded web page) |
| `endpoints.json` | Structured endpoint list |
| `openapi.json` / `.yaml` | Generated OpenAPI 3.0 spec (open in https://editor.swagger.io) |
| `tests.json` | The full generated test plan |
| `test-report.md` / `.html` / `.pdf` | Pass/fail summary + status codes + failure details |
| `test-report.xlsx` | **Colorful multi-sheet spreadsheet** — Summary, Endpoints, Test Results |
| `results.json` | Full request/response record for every test |

### The HTML & XLSX outputs

- **`.html` reports** are self-contained (no internet needed), color-coded by result and status
  code, and adapt to light/dark themes. Just double-click to open in any browser.
- **`test-report.xlsx`** is a styled workbook with three sheets:
  - **Summary** — totals, pass/fail counts, and a status-code distribution
  - **Endpoints** — every endpoint with method color badges
  - **Test Results** — one row per test with **complete data** (request/response bodies, headers,
    status, duration, errors), color-coded green/red/amber, with auto-filters enabled.

  Open it in Excel, Google Sheets, or LibreOffice. Secret-looking header values are redacted.

Already have `results.json` from a previous run and just want the pretty output? Ask the AI to
run `export_report` — it rebuilds the HTML + XLSX from the saved JSON without re-running anything.

---

## Test categories generated

- **happy-path** — valid request with sample params/body; expects success
- **edge-case** — non-existent resources, malformed params, empty bodies
- **negative** — malformed JSON, wrong HTTP method (expects 4xx/405)
- **security** — same request with credentials stripped (expects 401/403)

---

## Develop from source (contributors)

```bash
git clone https://github.com/Hassan-Jamal/Automated_API_MCP.git
cd Automated_API_MCP
npm install
npm run build     # compile to dist/
npm test          # 63 tests: detectors, scanner, auth, schema, harvesting, PDF, etc.
```

The `examples/sample-app/` folder has JS, Dart, and Express files demonstrating the detectors.

---

## Do I need to run my app first?

Depends on the step:

| Step | App/server running? |
| ---- | ------------------- |
| Scan, generate Swagger, generate tests | **No** — reads source code statically |
| **Execute** tests (`run_tests` / `full_audit`) | **Yes** — sends real HTTP requests |

For a **React Native or web app**, what must be running is the **backend API server** the app
talks to (e.g. `http://localhost:3000`) — **not** the emulator or the web frontend. This tool
calls the API directly, the same API your app calls. Point `baseUrl` at that server.

If your project **is** the backend (Express/NestJS/FastAPI/Flask), start it, then run the tests.

> Tip: use `dryRun: true` on `run_tests` to preview the requests without sending any — handy
> before pointing it at a real server.

## Onboarding a new QA (2 commands)

No cloning, no building — the package is on npm. On each machine (needs Node.js 18+ and a host):

```bash
npm i -g @hassanjamal/api-mcp          # install once
claude mcp add -s user api-mcp -- api-mcp   # register for all projects
```

Verify with `claude mcp list` → `✔ Connected`. Then open an app folder and either use the
`/qa-audit` slash command or ask in natural language. To update later:
`npm i -g @hassanjamal/api-mcp@latest`.

## Notes & limits

- Detection is heuristic (regex-based). It finds string-literal paths; fully dynamic URLs built
  from variables may be partially normalized (`${expr}` → `{param}`).
- Generated request bodies are placeholders — refine them via `sampleValues` in config for
  endpoints with strict validation.
- The executor sends **real requests**. Point it at a dev/staging server, not production.

TDQS

A3.9/5.0

Scored across 10 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: detecting base URLs, detecting OpenAPI specs, scanning endpoints, generating specs, generating tests, running tests, logging in, full audit, QA audit, and exporting reports. Descriptions are detailed and unique, preventing confusion.

Naming Consistency4/5

Most tool names follow a verb_noun pattern with snake_case (e.g., detect_base_url, generate_tests). A couple use compound nouns (full_audit, qa_audit) but still adhere to the overall lowercase underscore convention, making them predictable.

Tool Count5/5

Ten tools cover the entire API auditing workflow without being excessive. Each tool addresses a specific step or role, making the set well-scoped for the domain.

Completeness5/5

The tools cover the full lifecycle: endpoint discovery, OpenAPI spec handling, test generation, execution, login, and reporting. No obvious gaps exist for the intended purpose of API testing and auditing.

Maintenance

ActivityMaintained
ResponsivenessSyncing