Content
# Tool List
Put [Just One API](https://justoneapi.com)'s **237+ data interfaces** (from 30+ platforms like Douyin, Xiaohongshu, Taobao, Amazon, TikTok, etc.) into a few meta-tools as [MCP](https://modelcontextprotocol.io) services.
Core Features:
- **Tool count doesn't explode with interface growth** - Regardless of the number of backend interfaces, only 4 core tools + 2 maintenance tools are exposed externally.
- **Natural language intelligently selects interfaces** - Based on Alibaba Cloud's `text-embedding-v4` (2048 dimensions) for cross-language semantic search, Chinese questions can directly hit English interface descriptions.
- **SDK/backend updates, MCP code remains unchanged** - All interface knowledge comes from data products (`catalog.json` + `embeddings.json`). Adding, deleting, or modifying interfaces only requires rebuilding data and supports hot loading (no restart needed).
Design details can be found in [`docs/mcp-server-design.md`](docs/mcp-server-design.md).
## How It Works
The backend OpenAPI is the sole source of truth, deriving MCP's interface directory and vector index:
```
Backend OpenAPI → normalized.json → catalog.json + embeddings.json (vector)
↓
LLM orchestrates "search → get parameters → call" to dynamically use all 237+ interfaces:
search_endpoints → get_endpoint_schema → call_endpoint
```
### Exposed Tools
| Tool | Function |
|------|---------|
| `search_endpoints` | Discover interfaces using natural language (semantic search, returns candidate endpoint_id) |
| `get_endpoint_schema` | View the complete parameter contract of an interface |
| `call_endpoint` | Execute the interface with parameters and return data (large results truncated + pagination hints) |
| `list_platforms` | List all platforms and the number of interfaces |
| `check_updates` | [Maintenance · Read-only] Compare with the upstream and list interfaces to be added/removed/changed |
| `rebuild_catalog` | [Maintenance · Admin] Synchronize with the upstream and rebuild the directory and vector index |
## Installation
Python ≥ 3.10 is required.
```bash
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt # Runtime dependencies: mcp / httpx / pydantic
```
## Configuration
### Server-side (environment variables)
| Variable | Required | Description |
|----------|----------|-------------|
| `MCP_TRANSPORT` | Yes | Fixed as `http` |
| `MCP_HOST` / `MCP_PORT` | No | Listening address, default `0.0.0.0:8000` |
| `MCP_ADMIN_TOKEN` | No | Only needed when using MCP tools to remotely call `rebuild_catalog`; not required for daily data retrieval |
### Client-side (Cursor `mcp.json` headers)
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer <your justone token>`, deducts your justone balance when calling business interfaces |
| `X-DashScope-Key` | Yes | Your Baidu Qiankun key, used for semantic search in `search_endpoints` |
| `X-Admin-Token` | **No** | **Only** needed when calling `rebuild_catalog` through MCP, and must match the server's `MCP_ADMIN_TOKEN`; not required for daily search/data retrieval |
## Generating Data Products
Generate `catalog.json` + `embeddings.json` (using Baidu Qiankun encoding, incremental) before the first run:
```bash
python -m tools.mcp_catalog # Generate directory + vector
python -m tools.mcp_catalog --no-embed # Generate directory only, skip vector encoding
```
## Running
### Server
```bash
MCP_TRANSPORT=http MCP_HOST=0.0.0.0 MCP_PORT=8000 python -m justoneapi.mcp.server
```
If you need to remotely call `rebuild_catalog` through MCP tools, set the server's `MCP_ADMIN_TOKEN=<random strong string>`.
### Client (Cursor `mcp.json`)
Daily data retrieval requires only two headers:
```jsonc
{
"mcpServers": {
"justoneapi": {
"url": "http://<server IP or domain>:8000/mcp",
"headers": {
"Authorization": "Bearer <your justone token>",
"X-DashScope-Key": "<your Baidu Qiankun key>"
}
}
}
}
```
Only when calling `rebuild_catalog` through MCP, add `"X-Admin-Token": "<match with server MCP_ADMIN_TOKEN>"`.
> It is recommended to use HTTPS (Nginx/Caddy reverse proxy + TLS) in production environments to avoid transmitting tokens in plain text in request headers.
## Interface Updates
The backend OpenAPI is the sole source of truth; justone's official CI daily submits the normalized `public-api.normalized.json` to the public repository. This project directly synchronizes this public product to keep up with the backend, **no credentials required**:
```bash
python -m scripts.sync_mcp # Pull upstream → rebuild if changes (including interface diff)
python -m scripts.sync_mcp --dry-run # Check differences only, no rebuild
python -m scripts.sync_mcp --force # Rebuild even if no changes
```
You can also call maintenance tools on the client as needed: first `check_updates` to see differences, then `rebuild_catalog` after confirmation (requires `MCP_ADMIN_TOKEN` configuration and `X-Admin-Token` in headers). Rebuilding is atomic replacement, incremental encoding, and the running server automatically loads updates via mtime, **no restart required**.
## Project Structure
```
just-one/
├── justoneapi/
│ ├── _transport.py # Stable call出口 Transport.get(path, params)
│ ├── _exceptions.py
│ ├── _response.py
│ ├── _version.py
│ ├── log.py
│ ├── mcp/
│ │ ├── server.py # FastMCP入口,注册 6 个工具
│ │ ├── search.py # Semantic search
│ │ ├── executor.py # Parameter validation + multi-tenant token + call
│ │ ├── catalog.py # In-memory directory + mtime hot loading
│ │ ├── embedding.py # Baidu Qiankun text-embedding-v4 encapsulation
│ │ └── config.py # Environment variables and platform aliases
│ └── mcp_data/ # Runtime products (generated)
│ ├── catalog.json
│ ├── embeddings.json
│ └── embeddings.meta.json
├── openapi/
│ └── public-api.normalized.json # Interface directory sole data source (synchronized from upstream)
├── scripts/
│ └── sync_mcp.py # Synchronize upstream + rebuild (no credentials)
├── tools/
│ └── mcp_catalog.py # Generate catalog + vector from normalized.json
├── docs/
│ └── mcp-server-design.md
├── requirements.txt
├── pyproject.toml
└── README.md
```
## License
See [LICENSE](LICENSE).