Content
# Lingxing MCP
A production-ready remote MCP Server for Lingxing ERP OpenAPI. Using standard **Streamable HTTP**, each Agent is bound to a specific ERP user through `X-Mcp-Key` and performs:
- ERP user shop permission isolation;
- ERP role name synchronization;
- Local "role → functional module/interface read-write permission" mapping;
- Write interface default rejection, explicit authorization;
- Interface directory search, version differences, and MCP resource update notification;
- Unified management of App ID/App Secret, token, signature, rate limiting, and auditing on the server.
The current directory is based on Lingxing's official snapshot, which includes **614 OpenAPI endpoints**. Two authentication endpoints are only for internal service use, and Agents can call 612 business endpoints. To avoid loading hundreds of Tools into the model, this project uses 6 stable Tools to cover all business interfaces.
## Why Not Generate 614 Tools
A large number of dynamic Tools would amplify client initialization context, reduce selection accuracy, and disrupt Tool list stability when the official API adds new interfaces. This project adopts:
1. `search_endpoints` to retrieve interfaces with the current user's permissions;
2. `get_endpoint_schema` to read interface parameters and risk classification;
3. `call_read_endpoint` to call read-only interfaces;
4. `call_write_endpoint` to call interfaces with side effects;
5. `list_my_permissions` to view current identity, shop, and functional authorization;
6. `get_api_changes` to query added, changed, or removed interfaces.
Authentication and renewal endpoints are not exposed to Agents; App Secret, access token, and signature are not included in MCP output.
## Permission Model
Lingxing's official MCP `X-Mcp-Key` is bound to the current ERP account, and the official service can directly use internal account permissions. The public OpenAPI can only read role names and shop permissions returned by `/erp/sc/data/account/lists`, but not the role's menu/functional details.
Therefore, this project adopts an auditable equivalent boundary:
- API Key → ERP `uid`;
- Automatic synchronization of `uid`'s `role` and `seller`;
- Shop name strictly mapped to `/erp/sc/data/seller/lists`'s `sid`;
- Role name mapped to local module/endpoint authorization;
- Unknown roles, unknown shops, duplicate shop names, or interfaces that cannot be narrowed down are rejected by default;
- Interfaces that cannot be constrained by shop parameters must have precise `endpoint_id + allow_unscoped` authorization;
- Role or shop permission cache defaults to 5 minutes, and if synchronization fails after expiration, it will fail closed.
See [Permission and Security Model](docs/permission-model.md) for details.
## Differences from Existing Solutions
| Solution | Tool Coverage | Remote Protocol | Multi-Person Authentication | Shop Isolation | Functional Role Isolation | Write Operation Governance | Version Update |
| --- | ---: | --- | --- | --- | --- | --- | --- |
| Lingxing Official MCP | Officially selected tools | Streamable HTTP | ERP account-bound key | Official internal permissions | Official internal permissions | Official control | Official maintenance |
| `zach22-1999/lingxing-mcp` current public version | Approximately 84 tools/specifications | Custom HTTP JSON-RPC + stdio | Bearer member token | Multiple tokens share the same OpenAPI Service, not limited by token `sid` | Not implemented | Mainly read-only | Document synchronization script |
| This project | 612 business endpoints, 6 stable Tools | Standard Streamable HTTP | `X-Mcp-Key` | Synchronized and enforced verification by ERP user | Role name synchronization + administrator mapping | Default read-only, explicit write permission authorization | `changes.json` + resource notification + SemVer |
References:
- [Lingxing Official MCP Documentation](https://www.lingxing.com/help/article/mcp)
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [`zach22-1999/lingxing-mcp`](https://github.com/zach22-1999/lingxing-mcp)
## Quick Start
For production deployment, please read the [Tencent Cloud Ubuntu Deployment Guide](docs/deployment-ubuntu.md) directly.
Local development requires Node.js 22.5+:
```powershell
npm.cmd install
Copy-Item .env.example .env
```
After configuring `.env`, inject environment variables into the current process and initialize the database:
```powershell
$env:LINGXING_APP_ID = "Your App ID"
$env:LINGXING_APP_SECRET = "Your App Secret"
$env:LINGXING_MCP_KEY_PEPPER = "At least 32 characters of random value"
npm.cmd run admin -- init-db
npm.cmd run admin -- sync-user --uid Your ERP User UID
npm.cmd run admin -- apply-role-map --file config/role-mapping.example.json
npm.cmd run admin -- create-key --uid Your ERP User UID --label "Codex"
npm.cmd start
```
The Key is only displayed once during creation.
## Agent Configuration
```json
{
"mcpServers": {
"LingXing-MCP": {
"type": "streamableHttp",
"url": "https://mcp.example.com/mcp",
"headers": {
"X-Mcp-Key": "Replace with personal API-Key"
}
}
}
}
```
It is recommended to use a separate Key for each user and Agent client for easy revocation and auditing. See [Agent Access Guide](docs/agent-clients.md) for more examples and acceptance methods.
## Management Commands
```bash
# Generate database hash pepper
docker compose -f deploy/compose.yaml run --rm lingxing-mcp \
node src/admin-cli.js generate-pepper
# Synchronize ERP user roles and shops
docker compose -f deploy/compose.yaml exec lingxing-mcp \
node src/admin-cli.js sync-user --uid 123
# Apply role mapping
docker compose -f deploy/compose.yaml exec lingxing-mcp \
node src/admin-cli.js apply-role-map --file /config/role-mapping.json
# Create or revoke personal Key
docker compose -f deploy/compose.yaml exec lingxing-mcp \
node src/admin-cli.js create-key --uid 123 --label "Alice Codex"
docker compose -f deploy/compose.yaml exec lingxing-mcp \
node src/admin-cli.js revoke-key --id KEY_ID
# Audit
docker compose -f deploy/compose.yaml exec lingxing-mcp \
node src/admin-cli.js audit --limit 100
```
## Interface Directory Update
```bash
export LINGXING_DOC_ACCESS='Server-side document access key'
npm run catalog:update
git diff -- catalog/endpoints.json catalog/changes.json
```
The update process downloads and verifies the complete official snapshot. If any page fails, the current directory will be rejected. After the directory file is atomically replaced, the running MCP session receives:
- `lingxing://catalog/version`
- `lingxing://catalog/changes`
Corresponding resource updated notifications. Agents can also use `get_api_changes` to supplement the check after reconnection. See [Version and Catalog Updates](docs/catalog-updates.md) for details.
## Testing
```bash
npm test
npm run check
npm audit --omit=dev --audit-level=high
docker build -t lingxing-mcp:test .
```
## Security Tips
- Do not submit App ID, App Secret, `X-Mcp-Key`, Lingxing access token, or actual `.env` to the repository.
- Keys exposed by users in chat or screenshots should be immediately revoked and recreated.
- Production environments must use HTTPS and should not directly expose port 8099 to the public internet.
- `allow_unscoped` indicates that the endpoint cannot be reliably narrowed down by shop and should only be granted to reviewed administrator roles.
- Role mapping examples are not your production permission definitions; they must be reviewed item by item before going live.
For security issues, see [SECURITY.md](SECURITY.md).
## License
[MIT](LICENSE)