内容
# invgate-mcp
一个精选的 [模型上下文协议](https://modelcontextprotocol.io/)(MCP)服务器,通过stdio暴露 **12个只读工具**,用于 [InvGate资产管理](https://www.invgate.com/asset-management)。任何MCP兼容的客户端(例如Claude Desktop)都可以通过自然语言查询资产、人员、计算机、服务器、软件和API健康状况。
- **传输**: 仅限stdio(本地代理的通用默认设置)。
- **身份验证**: OAuth2客户端凭证流(`scope=read`),具有60秒过期缓冲和一次性401重试的内存令牌缓存。
- **验证**: 每个工具输入都使用 [zod](https://zod.dev) 验证;无效输入返回结构化的`validation_error`,而不会调用API。
- **弹性**: HTTP、身份验证和网络故障被转换为MCP文本内容,带有`isError: true` — 服务器永远不会崩溃主机。
- **分发**: 发布到npm,可通过 `npx invgate-mcp` 运行。
## 安装
```bash
# 运行而无需安装
npx invgate-mcp
# 或全局安装
npm install -g invgate-mcp
invgate-mcp
```
## 配置
服务器在启动时读取三个必需的环境变量:
| 环境变量 | 描述 | 示例 |
|---|---|---|
| `INVGATE_BASE_URL` | InvGate公共API基准URL(以 `/public-api/v2` 结尾) | `https://acme.invgate.net/public-api/v2` |
| `INVGATE_CLIENT_ID` | OAuth2客户端ID | `my-client-id` |
| `INVGATE_CLIENT_SECRET` | OAuth2客户端密钥 | `my-client-secret` |
如果缺少任何一个,服务器都会将描述性错误打印到stderr并退出,退出码为1。
OAuth2令牌端点通过从 `INVGATE_BASE_URL` 中剥离 `/public-api/v2` 段并追加 `/oauth2/token/` 而派生,因此 `https://acme.invgate.net/public-api/v2` → `https://acme.invgate.net/oauth2/token/`。
## Claude Desktop 配置
在 `mcpServers` 块中添加 `invgate-mcp`(macOS上为 `~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"invgate": {
"command": "npx",
"args": ["-y", "invgate-mcp"],
"env": {
"INVGATE_BASE_URL": "https://acme.invgate.net/public-api/v2",
"INVGATE_CLIENT_ID": "your-client-id",
"INVGATE_CLIENT_SECRET": "your-client-secret"
}
}
}
}
```
## 工具
| 工具 | 输入 | 行为 |
|---|---|---|
| `invgate_list_asset_types` | 无 | 返回所有资产类型 |
| `invgate_list_assets` | `page`、`per_page`、`asset_type_id`、`criteria` | 带可选过滤器的分页资产列表 |
| `invgate_get_asset` | `asset_id`(必填) | 按ID获取单个资产 |
| `invgate_list_people` | `page`、`per_page`、`criteria` | 分页人员列表 |
| `invgate_get_person` | `person_id`(必填) | 按ID获取单个人员 |
| `invgate_get_person_assets` | `person_id`(必填)、`page`、`per_page` | 分配给人员的资产 |
| `invgate_list_computers` | `page`、`per_page`、`criteria` | “计算机”类型的资产 |
| `invgate_get_computer` | `asset_id`(必填) | 单个计算机资产 |
| `invgate_list_servers` | `page`、`per_page`、`criteria` | “服务器”类型的资产 |
| `invgate_get_server` | `asset_id`(必填) | 单个服务器资产 |
| `invgate_get_health` | 无 | API连接状态 |
| `invgate_list_software` | `page`、`per_page`、`criteria` | 分页安装软件目录 |
### 参数映射
工具输入使用 `snake_case`;服务器将它们映射到InvGate API查询参数。`per_page` → `page_size`,`asset_type_id` → `asset_types`。`criteria`对象映射到InvGate的嵌套语法:`{ "name": "cont:MacBook" }` 在查询字符串中变为 `criteria[name]=cont:MacBook`(操作示例:`cont`、`eq`、`startswith`等)。
### 结果和错误
- **成功**:原始JSON响应正文,经过美化,作为MCP `text`内容。
- **错误**:结构化JSON `{ "error": "...", "message": "...", "status": ... }` 作为文本内容,带有 `isError: true`。类型:`validation_error`、`auth_error`、`api_error`、`network_error`。
## 开发
```bash
npm install
npm run build # tsup → dist/index.js (单个ESM捆绑包)
npm run typecheck # tsc --noEmit
npm test # vitest run (59 tests, MSW用于HTTP拦截)
npm run test:coverage # vitest run --coverage (src/**的80%门控)
npm run dev # tsx src/index.ts
```
需要Node.js 20+(使用原生 `fetch`)。
## 许可证
MIT