invgate-mcp
v0.1.0
Published
Curated MCP server exposing InvGate Asset Management as 12 read-only tools over stdio.
Maintainers
Readme
invgate-mcp
A curated Model Context Protocol (MCP) server that exposes 12 read-only tools over stdio for InvGate Asset Management. Any MCP-compatible client (Claude Desktop, etc.) can query assets, people, computers, servers, software, and API health through natural language.
- Transport: stdio only (the universal default for local agents).
- Auth: OAuth2 client-credentials flow (
scope=read), in-memory token cache with a 60-second expiry buffer and one-shot 401 retry. - Validation: every tool input is validated with zod;
invalid input returns a structured
validation_errorwithout calling the API. - Resilience: HTTP, auth, and network failures are converted to MCP text
content with
isError: true— the server never crashes the host. - Distribution: published to npm, runnable via
npx invgate-mcp.
Install
# Run without installing
npx invgate-mcp
# Or install globally
npm install -g invgate-mcp
invgate-mcpConfiguration
The server reads three required environment variables at startup:
| Env var | Description | Example |
|---|---|---|
| INVGATE_BASE_URL | InvGate public API base URL (ends with /public-api/v2) | https://acme.invgate.net/public-api/v2 |
| INVGATE_CLIENT_ID | OAuth2 client ID | my-client-id |
| INVGATE_CLIENT_SECRET | OAuth2 client secret | my-client-secret |
If any are missing the server prints a descriptive error to stderr and exits with code 1.
The OAuth2 token endpoint is derived from INVGATE_BASE_URL by stripping the
/public-api/v2 segment and appending /oauth2/token/, so
https://acme.invgate.net/public-api/v2 → https://acme.invgate.net/oauth2/token/.
Claude Desktop config
Add invgate-mcp to your mcpServers block
(~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"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"
}
}
}
}Tools
| Tool | Input | Behavior |
|---|---|---|
| invgate_list_asset_types | none | Returns all asset types |
| invgate_list_assets | page, per_page, asset_type_id, criteria | Paginated asset list with optional filters |
| invgate_get_asset | asset_id (required) | Single asset by ID |
| invgate_list_people | page, per_page, criteria | Paginated people list |
| invgate_get_person | person_id (required) | Single person by ID |
| invgate_get_person_assets | person_id (required), page, per_page | Assets assigned to a person |
| invgate_list_computers | page, per_page, criteria | Assets of type "computer" |
| invgate_get_computer | asset_id (required) | Single computer asset |
| invgate_list_servers | page, per_page, criteria | Assets of type "server" |
| invgate_get_server | asset_id (required) | Single server asset |
| invgate_get_health | none | API connectivity status |
| invgate_list_software | page, per_page, criteria | Paginated installed-software catalog |
Parameter mapping
Tool inputs use snake_case; the server maps them to the InvGate API query
parameters. per_page → page_size, asset_type_id → asset_types.
The criteria object maps to InvGate's nested syntax:
{ "name": "cont:MacBook" } becomes criteria[name]=cont:MacBook on the
query string (op examples: cont, eq, startswith, …).
Results & errors
- Success: the raw JSON response body, pretty-printed, as MCP
textcontent. - Errors: structured JSON
{ "error": "...", "message": "...", "status": ... }as text content withisError: true. Types:validation_error,auth_error,api_error,network_error.
Development
npm install
npm run build # tsup → dist/index.js (single ESM bundle)
npm run typecheck # tsc --noEmit
npm test # vitest run (59 tests, MSW for HTTP interception)
npm run test:coverage # vitest run --coverage (80% gate on src/**)
npm run dev # tsx src/index.tsRequires Node.js 20+ (uses native fetch).
License
MIT
