Content
# 🔌 API MCP Manager
> A visualized API knowledge base MCP client - providing a unified multi-project API document retrieval gateway for AI Agents (Cursor / Claude Desktop, etc.).
Based on the MCP (Model Context Protocol) protocol's **Streamable HTTP** transport, supporting Swagger/OpenAPI (2.x/3.x/3.1), YApi, Apifox, Postman four types of data sources (automatic pull or import JSON), lazy loading secondary cache, partial `$ref` dereferencing, and two-way authentication and reinforcement. Providing Electron desktop + Linux CLI Node SEA single binary + Web management background three delivery forms.
## ✨ Core Features
- **Streamable HTTP Transport**: Adopting the MCP official new standard (single endpoint `POST /mcp`), while retaining the `GET /mcp` SSE endpoint for compatibility with old clients.
- **Three Read-Only Tools**: `list_projects` / `get_api_list` / `get_api_details`, strictly read-only boundary.
- **Four Data Sources × Dual Access Mode**:
- **Swagger / OpenAPI** (2.0 / 3.0 / **3.1**): URL automatic pull; Swagger 2.0 automatic normalization, 3.1 automatic downgrade to 3.0.
- **YApi**: Open API automatic pull (menu grouping + concurrent details + environment domain name).
- **Apifox**: Open API automatic pull OpenAPI document, or import native data export JSON.
- **Postman**: Import Collection v2.1/v2.0 JSON.
- All sources support "import JSON" mode (manual paste offline document).
- **Lazy Loading Secondary Cache**: Only pull upstream documents when called for the first time, TTL default 2h + automatic GC, avoid startup stuck and memory surge; support Memory (single machine) and Redis (cross-process sharing) two cache backends.
- **Partial `$ref` Dereferencing**: Only expand the target interface node's schema, prevent circular references, control token cost.
- **Structured Response Rendering**: Request body / response schema recursive expansion to tree-shaped indentation table (nested object / array complete presentation), nullable field mark `?`, empty schema automatic skip.
- **Web Management Background**: React + Tailwind visual management, support project CRUD, interface search preview (Markdown syntax highlighting), connection test, cache refresh, security settings.
- **Two-Way Authentication Reinforcement**:
- MCP Client: Static API Key (Bearer Header / X-MCP-Token / Query downgrade) + OAuth 2.1 reserved skeleton.
- Management Background: Dynamic Session Token, only loopback address allows query delivery, CORS runtime adaptive.
- **Security Storage**: Configuration file `0600` permission, upstream token optional AES-256-GCM encryption, log automatic desensitization.
- **Multi-Form Delivery**: Electron desktop (Win/Mac, tray resident / boot self-start) + Linux CLI (Node SEA single binary, no Node.js runtime).
## 🏗️ Architecture
```
api-mcp-manage/
├─ packages/
│ ├─ core/ # MCP core engine: Express server, MCP tool registration, four source pull and parsing, authentication, configuration management, cache
│ ├─ web/ # React 18 + Vite 5 + Tailwind CSS 3 management background SPA
│ └─ desktop/ # Electron shell (tray resident / boot self-start / window management)
└─ apps/
└─ cli/ # Linux no interface CLI entrance (Node SEA single binary packaging)
```
### Architecture Panorama
```
MCP Client (Cursor / Claude Desktop)
│
POST /mcp (Bearer token)
GET /mcp (SSE compatible)
│
StaticKeyAuthProvider
│
┌────────┴────────┐
│ MCP Server │ ← @modelcontextprotocol/sdk
│ (request-level instance) │ stateless mode
│ │
│ list_projects │── config (hot update)
│ get_api_list │── swagger/cache (lazy loading)
│ get_api_details │── swagger/dereference (partial $ref)
└────────┬────────┘
│
┌────────────┼────────────┐
│ │ │
MemoryStore RedisStore normalize.ts
(single machine) (cross-process) (Swagger 2→3 / 3.1→3.0 downgrade)
│
┌────────────┼────────────┐────────────┐
│ │ │ │
format.ts dereference.ts yapi.ts apifox.ts / postman.ts
(Markdown) (partial expansion) (YApi→OpenAPI) (each source→OpenAPI)
Admin API (/admin/api/*) Web Dashboard (/admin)
│-- projects CRUD │-- project management (CRUD)
│-- security / cache │-- interface search and preview (Markdown highlighting)
│-- test / refresh / apis │-- connection test / cache refresh
│-- import (import JSON) │-- import JSON (Swagger/YApi/Apifox/Postman)
│-- security settings / Token management
│-- cache configuration (Memory/Redis)
```
## 🚀 Quick Start
### Environment Requirements
- Node.js ≥ 20
- pnpm ≥ 9
### Installation and Running
```bash
# Install dependencies
pnpm install
# Build all packages (core + web + cli, not including desktop)
pnpm build
# Start CLI service (need to complete build, tsx can directly run TypeScript source code without build)
pnpm start
```
> **Development Tip**: `pnpm start` uses tsx to directly run TypeScript source code (without pre-compilation). But the Web management background needs to `pnpm build` or separate `pnpm --filter @api-mcp/web build` to access.
After starting, the console output:
```
🚀 API MCP Manager Server (V1.3) started!
─────────────────────────────────────────────────────
📡 MCP Endpoint (Streamable HTTP): http://localhost:3001/mcp
🛠️ Web Dashboard: http://localhost:3001/admin?token=Session_xxx
🔑 MCP Client Token: mcp_key_xxx
─────────────────────────────────────────────────────
```
### Development Mode
```bash
# Terminal 1: Start core server (watch)
pnpm --filter @api-mcp/core dev
# Terminal 2: Start web development server (hot update, proxy to core)
pnpm --filter @api-mcp/web dev
```
## 🔗 Client Access
Add to MCP configuration in Cursor or Claude Desktop:
**Cursor (Header authentication, recommended)**
```json
"mcpServers": {
"api-mcp-manager": {
"url": "http://localhost:3001/mcp",
"headers": { "Authorization": "Bearer mcp_key_xxx" }
}
}
```
**Claude Desktop (Query parameter, need to pay attention to log leakage)**
```json
"mcpServers": {
"api-mcp-manager": {
"url": "http://localhost:3001/mcp?token=mcp_key_xxx"
}
}
```
Token can be viewed and reset in the Web background's "Security" panel.
## 🛠️ MCP Tools
| Tool | Input | Output | Description |
|------|------|------|------|
| `list_projects` | — | JSON | All API project list (id, name, description) |
| `get_api_list` | `projectId`, `keyword?` | Markdown | Interface route summary (lazy loading, support keyword filtering) |
| `get_api_details` | `projectId`, `path`, `method` | Markdown | Interface details (parameter table + request body/response schema tree expansion, partial `$ref` dereferencing; YApi/Apifox source project additional display environment domain name) |
> All tools are marked `readOnlyHint: true`, strictly read-only, do not execute or modify any resources.
## 🔐 Security Design
| Defense Layer | Mechanism |
|--------|------|
| MCP Endpoint Authentication | Static API Key, three parameter passing methods (Bearer / X-MCP-Token / Query downgrade), 401 intercept unauthorized |
| MCP SSE Compatibility | `GET /mcp` endpoint also walk authentication, support old client |
| Management Background Authentication | One-time Session Token, URL passed immediately cleared; only loopback address allows query delivery, non-loopback rejection |
| Configuration Storage | File `0600` permission, upstream token optional AES-256-GCM encryption (key from environment variable or machine binding derivation) |
| Log Desensitization | URL `token=xxx` automatic desensitization to `***`; metadata token/authorization field also desensitization |
| TLS Warning | Start detection non-loopback binding, output strong warning prompt need reverse proxy TLS termination; can pass `MCP_SKIP_TLS_WARNING=1` suppression |
## 📦 Data Source Support
Each project can choose "automatic pull" (timed/first access pull from upstream) or "import JSON" (manual paste offline document, no upstream dependency). Different sources support mode:
| Source | Automatic Pull | Import JSON | Description |
|------|:--------:|:---------:|------|
| **Swagger / OpenAPI** | ✅ URL | ✅ | OpenAPI 2.0 / 3.0 / **3.1** document |
| **YApi** | ✅ Open API | ✅ | Native interface list + details; or data export JSON |
| **Apifox** | ✅ Open API | ✅ | export-openapi endpoint; or native data export JSON |
| **Postman** | ❌ | ✅ | Collection v2.1/v2.0 export JSON |
### OpenAPI / Swagger
Support Swagger 2.0, OpenAPI 3.0 and **3.1**:
- **Swagger 2.0** automatic normalization to 3.0 structure (body/formData parameter → requestBody, response.schema → content)
- **OpenAPI 3.1** automatic downgrade to 3.0 (`type: ["string","null"]` → `type:"string" + nullable`; `exclusiveMinimum` digital → boolean form), downstream unified processing a set of formats
### YApi (Native Support)
Directly through YApi open API pull interface data (non-swagger export method), support:
- Press menu grouping display interface list (`catname`)
- Concurrent limited pull details (5 concurrent)
- Interface details display each environment domain name (`get_api_details` pull `/api/project/get` get domain name, render in details)
- Automatic conversion: req_query/req_headers/req_params → OpenAPI parameter; req_body_form/req_body_other → requestBody; res_body → response schema
- Import mode: support interface details array, or data export format (including grouping `list`)
### Apifox
Through Apifox open API automatic pull standard OpenAPI document, or import native data export JSON:
- **Automatic Pull**: Call `export-openapi` endpoint (`projectId` + access token; `baseUrl` default `https://api.apifox.com`, private deployment can be modified), return standard OpenAPI document, reuse swagger same pipeline
- **Import JSON**: Apifox "data export → Apifox" native format (including `apiCollection` nested folder/api tree), automatic conversion parameters/requestBody/jsonSchema
- Interface details display `servers` environment domain name (with YApi domain name display alignment)
### Postman (Only Import)
Import Postman Collection v2.1/v2.0 export JSON:
- Nested folder/request tree automatic expansion
- Support multiple url forms (string / `{path, query}` object / `{{host}}/path` variable placeholder)
- Request body conversion: `raw`+json (→ schema or example), `urlencoded`, `formdata`; response body (JSON string) → example
- Compatible request string abbreviation form
### Import JSON Mode
All sources support "import JSON" mode: users in the Web background paste/upload offline document JSON, press project source type verification after conversion to unified OpenApiDocument persistence. After import project no upstream dependency, no automatic pull/refresh cache, suitable for internal network or no API endpoint scene.
## 🖥️ Web Management Background
Built-in React 18 + Tailwind CSS 3 management background, function including:
| Function Module | Description |
|----------|------|
| Project Management | CRUD, support Swagger / YApi / Apifox / Postman four types of source switching, Token encryption input |
| Import JSON | Paste or upload offline document (press source type verification: OpenAPI / YApi array / Apifox export / Postman Collection), support local file selection |
| Interface Browse | Press project view interface list (method color label), keyword search, click view Markdown details (code syntax highlighting + XSS protection) |
| Connection Test | Verify upstream document source accessibility, return document title / interface number / version |
| Cache Refresh | Forced from upstream re-pull document, immediate effect |
| Security Settings | MCP client Token view / copy / reset, one-click old Token invalidation; Web background access Token persistence switch |
| Cache Configuration | Memory / Redis switching, TTL setting, Redis connection test after saving, service automatic restart |
| MCP Access Guide | Built-in help pop-up window, provide Cursor / Claude Desktop configuration JSON (one-click copy) |
### Interface Screenshot


## 🧪 Test
```bash
# Run all tests (13 test files, covering config / auth / format / $ref dereferencing / normalization / cache / cache storage / YApi / Apifox / Postman / import / tool / server / integration)
pnpm --filter @api-mcp/core test
# Type check (4 packages)
pnpm -r run typecheck
```
### Test Coverage
| Test File | Coverage |
|----------|----------|
| `config` | Default configuration creation, 0600 permissions, AES-256-GCM encryption/decryption, CRUD, Token reset, cache settings, ID generator |
| `auth` | Bearer/X-MCP-Token/Query parameter passing, 401 rejection, Admin token, loop/non-loop query policy |
| `format` | List/keyword filtering/empty path, detailed parameter table + response tree expansion, nested objects/arrays, nullable marking, empty schema skipping, deprecation marking, NotFound prompt |
| `dereference` | OpenAPI 3.x / Swagger 2.x `$ref`, nested recursion, circular references, sibling property merging, unhit retention |
| `normalize` | Swagger 2.0 body→requestBody, response.schema→content, formData merging; **OpenAPI 3.1 downgrade** (type array→nullable, exclusiveMin/Max numbers→boolean, nested recursion), deep copying |
| `cache` | Concurrent deduplication, TTL expiration, invalidation, GC, reinitCache switching, failure retry |
| `cache-store` | Memory/Redis Store interface contract, JSON round-trip, TTL passing, error downgrade, Redis URL parsing |
| `yapi` | query/header/path/form/json/raw body conversion, res_body intelligent judgment, HTML cleaning, menu name concatenation |
| `apifox` | apiCollection nesting, query/header parameter, json/multipart/raw request body, jsonSchema response, automatic request construction, environment domain extraction |
| `postman` | Nested folder/request, URL string/object/variable placeholder, raw json/urlencoded/formdata request body, response example, abbreviated form |
| `import` | Swagger/YApi/Apifox/Postman four-source import verification and conversion, format recognition, error prompt |
| `tools` | `$ref` dereferencing in parameter/requestBody/response, paramType readability |
| `server` | MCP authentication, initialize/tools/list/list_projects protocol, Admin CRUD + hot update, Token reset |
| `integration` | Public Petstore v2/v3 complete pipeline (pulling → normalization → list → details → dereferencing → formatting) |
## 🛠️ Tech Stack
| Layer | Technology |
|----|------|
| Runtime | Node.js ≥ 20 |
| Language | TypeScript 5.6 (strict mode) |
| Package Management | pnpm 9 (monorepo workspace) |
| MCP Protocol | `@modelcontextprotocol/sdk` ^1.29 (Streamable HTTP + SSE) |
| HTTP Server | Express 4 (single-port MCP + Admin + static files) |
| Frontend Framework | React 18 + Vite 5 + Tailwind CSS 3 |
| Markdown Rendering | marked 18 + highlight.js 11 + DOMPurify (XSS protection) |
| Logging | Winston (structured logging + sensitive information desensitization) |
| Validation | Zod (MCP tool input) |
| Cache | Memory Map (single machine) / ioredis (cross-process) |
| Desktop | Electron 33 + electron-builder 25 |
| Single Binary | Node.js SEA + esbuild + postject |
| Testing | Vitest (13 test files) |
## 📦 Packaging
### Complete Process (one-time output of all forms)
```bash
pnpm install # Install dependencies
pnpm build # core + web + cli (excluding desktop)
pnpm --filter @api-mcp/cli build:sea # Linux/no-interface single binary
pnpm --filter @api-mcp/desktop build # desktop main process packaging (esbuild → CJS)
pnpm --filter @api-mcp/desktop dist # Electron installation package (DMG / NSIS)
```
### Detailed Explanation
| Target | Command | Product | Description |
|------|------|------|------|
| Core Engine | `pnpm --filter @api-mcp/core build` | `packages/core/dist/` | TypeScript compilation |
| Web Management Backend | `pnpm --filter @api-mcp/web build` | `packages/web/dist/` | Vite construction, runtime hosted by core |
| One-click Build (core+web+cli) | `pnpm build` | — | Equivalent to `pnpm -r --filter=!@api-mcp/desktop run build`, daily local operation use this + `pnpm start` |
| **Linux Single Binary** | `pnpm --filter @api-mcp/cli build:sea` | `apps/cli/sea-out/api-mcp-<platform>-<arch>` (about 174M) | Node SEA, script built-in verification (startup + MCP response) |
| **Electron Desktop** | `pnpm --filter @api-mcp/desktop build && pnpm --filter @api-mcp/desktop dist` | `packages/desktop/release/API MCP Manager-1.3.0.dmg` (about 102M) / `.exe` | macOS DMG / Windows NSIS |
> ⚠️ **Electron Two-step Build**: desktop's `build` (esbuild compiles main process + `@api-mcp/core` into a single CJS, avoiding ESM/CJS interoperability issues) and `dist` (electron-builder) are two independent steps, **cannot skip `build` directly to `dist`**, otherwise, the asar lacks the entry file.
### SEA Single Binary Execution
```bash
# Product path contains platform and architecture suffix, e.g., darwin-x64 / linux-x64
./apps/cli/sea-out/api-mcp-darwin-x64
# Optional: place the web build product in the same directory as the binary, enable management backend UI
mkdir -p apps/cli/sea-out/assets/web
cp -r packages/web/dist/* apps/cli/sea-out/assets/web/
```
**SEA Deployment Form**: place the generated binary + `assets/web/` (optional) in the target machine, no Node.js runtime required.
### Auxiliary Commands
| Command | Purpose |
|------|------|
| `pnpm test` | All tests (13 files) |
| `pnpm -r run typecheck` | 4 package type checks |
| `pnpm start` | Local CLI service operation (tsx runs source code directly) |
| `pnpm --filter @api-mcp/web dev` | Web development hot update (proxy to core:3001) |
| `pnpm --filter @api-mcp/core dev` | Core watch mode |
| `pnpm --filter @api-mcp/desktop pack` | Electron only packs directory package (no installation package generation, for debugging) |
## 🧪 Verification Status
| Verification Item | Status |
|--------|------|
| Unit + Integration Tests (13 files: config / auth / format / $ref / normalization / cache / cache store / YApi / Apifox / Postman / import / tools / server / integration) | ✅ All passed |
| MCP Protocol End-to-End (initialize / tools/list / tools/call, including authentication) | ✅ Passed |
| `$ref` Dereferencing (real Petstore API, including Swagger 2.x body parameter + circular reference protection) | ✅ Passed |
| YApi Native Pulling and Conversion (menu grouping / concurrent detail pulling / OpenAPI conversion) | ✅ Passed |
| Apifox Automatic Pulling (export-openapi endpoint) + Native Data Import (real export file verification) | ✅ Passed |
| Postman Collection v2.1 Import Conversion (nested / multi-URL form / multi-body mode) | ✅ Passed |
| OpenAPI 3.1 Downgrade (type array / exclusiveMin/Max / nested recursion) | ✅ Passed |
| Import JSON Schema (four-source format verification + persistence) | ✅ Passed |
| Hot Update (Admin CRUD after list_projects immediate reflection of changes) | ✅ Passed |
| Production Integration (web hosting + CRUD + interface search + Markdown rendering + XSS protection) | ✅ Passed |
| Node SEA Single Binary (independent operation + MCP response + management API) | ✅ Passed |
| Electron Desktop (DMG packaging + tray menu + MCP server startup + tools/list) | ✅ Passed |
| Cache Dual-mode Switching (Memory ↔ Redis, reinitCache smooth migration) | ✅ Passed |
## 📋 Configuration and Data Flow
### Configuration File
Storage Path:
- macOS/Windows (Electron): `app.getPath('userData')/mcp-projects.json` (e.g., `%APPDATA%/api-mcp-manager/`)
- Linux (CLI): `~/.config/api-mcp-manager/mcp-projects.json` (or `$XDG_CONFIG_HOME`)
- SEA Single Binary: binary same directory `config/mcp-projects.json`
### Data Flow
```
User adds project (Web Admin)
→ POST /admin/api/projects
→ config/index.ts persistence (encrypted token → 0600 file)
→ MCP tool dynamic reading of latest configuration (hot update, no restart required)
AI calls get_api_list (MCP Client)
→ tools/index.ts reads project configuration
→ swagger/cache.ts getProjectDoc()
├── Import mode → directly returns persisted importedDoc
├── Cache hit and not expired → directly returns
├── Cache miss → fetchAndParse()
│ ├── source=swagger → fetchJson(url) → normalizeDocument() (Swagger 2→3 / 3.1→3.0)
│ ├── source=yapi → fetchYapiDocument() (concurrent 5, pulling menu + details)
│ ├── source=apifox → fetchApifoxDocument() → validateOpenApi + normalizeDocument()
│ └── source=postman → only supports import mode (already returned in the previous text)
└── Concurrent deduplication (same project repeated requests share the same Promise)
→ swagger/dereference.ts (partial `$ref` expansion)
→ swagger/format.ts (Markdown formatting: parameter table / tree response / nullable marking)
→ Return to LLM
```
## 📄 License
MIT
## 🌐 Environment Variables
| Variable | Purpose | Default Value |
|------|------|--------|
| `MCP_PORT` | CLI/SEA server port | `3001` (core internal automatic detection 3001-3100) |
| `MCP_CONFIG_PATH` | Custom configuration file path | Platform default path |
| `MCP_CONFIG_KEY` | Token encryption key (AES-256-GCM) | Machine binding derivation |
| `MCP_CONFIG_DISABLE_ENCRYPT` | Set to `"1"` to disable Token encryption | — |
| `MCP_LOG_LEVEL` | Log level (debug/info/warn/error) | `info` |
| `MCP_SKIP_WEB` | Set to `"1"` to not host Web management backend | — |
| `MCP_SKIP_TLS_WARNING` | Set to `"1"` to suppress non-loopback TLS warning | — |
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available