@wanadev/pennylane-mcp
v0.2.0
Published
MCP server for the Pennylane v2 API — auto-generated from the official OpenAPI spec.
Readme
pennylane-mcp
MCP server for the Pennylane v2 API, auto-generated from the official OpenAPI spec. Exposes 165 tools covering customers, invoices, suppliers, products, transactions, ledger entries, journals, quotes, categories, and more.
Install & run
Requires Node.js 18.17+.
From npm (once published)
npx -y @wanadev/pennylane-mcpFrom source
git clone <this-repo> && cd pennylane-mcp
npm install # runs `npm run generate && npm run build` via prepare
node build/server.jsAuthentication
The server resolves the API key in this order:
PENNYLANE_API_KEYenvironment variable--apiKey <key>CLI flag
Generate a Company API token at https://pennylane.readme.io/docs/generating-my-api-token.
Use with Claude Desktop
Edit your Claude Desktop config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"pennylane": {
"command": "npx",
"args": ["-y", "@wanadev/pennylane-mcp"],
"env": {
"PENNYLANE_API_KEY": "your-token-here"
}
}
}
}Restart Claude Desktop and the Pennylane tools will appear under the hammer icon.
Tool naming
Each operation in the OpenAPI spec becomes a tool named pennylane_<operationId_in_snake_case>. Examples:
| Tool | Endpoint |
| ----------------------------------- | ------------------------------------------ |
| pennylane_get_me | GET /me |
| pennylane_get_customers | GET /customers |
| pennylane_get_customer | GET /customers/{id} |
| pennylane_post_company_customer | POST /company_customers |
| pennylane_get_customer_invoices | GET /customer_invoices |
| pennylane_finalize_customer_invoice | POST /customer_invoices/{id}/finalize |
| pennylane_get_supplier_invoices | GET /supplier_invoices |
| pennylane_get_products | GET /products |
| pennylane_get_trial_balance | GET /trial_balance |
List endpoints accept cursor and limit for cursor-based pagination.
Development
npm run sync:openapi # re-fetch openapi/accounting.json from pennylane.readme.io
npm run generate # regenerate src/generated/tools.ts from the OpenAPI
npm run build # compile TypeScript → build/
npm run dev # run the server with tsx (no compile step)src/generated/tools.ts is git-ignored — it's a build artifact regenerated by the prepare script.
Architecture
src/
├── server.ts MCP server entry-point (CLI, stdio transport, signals)
├── client.ts Axios-based Pennylane client (Bearer auth, error wrapping)
├── auth.ts Resolves API key from env / CLI flag
└── generated/
└── tools.ts 165 registerTool() calls, generated from OpenAPI
scripts/
├── sync-openapi.ts Re-fetch the OpenAPI spec
└── generate-tools.ts OpenAPI → src/generated/tools.ts
openapi/
└── accounting.json Vendored OpenAPI 3.0 spec (1.9 MB, 120 paths, 165 ops)Limits
- Rate limits: Pennylane caps requests at 4/s globally and 2/s on
customer_invoices. The server does not throttle; rapid loops may hit429 Too Many Requests. - File downloads: endpoints returning binary data (e.g. invoice PDFs) currently return the raw response as a JSON-stringified blob. A proper MCP
resourcemapping is a follow-up. - OAuth2: only static API keys are supported. OAuth2 flows are a follow-up.
License
MIT
