Core concepts

What is model context protocol (MCP) and why does it matter?

MCP is an open protocol that allows AI assistants to call external tools and APIs in a structured, reliable way. Instead of asking Claude to "figure out" how to call an API from documentation, MCP gives Claude a typed, discoverable set of tools it can invoke directly.

The Zenskar MCP Server packages the entire Zenskar REST API surface (103 operations) as MCP tools. This means you can interact with your billing, contracts, and accounting data using plain language, and Claude will translate your intent into precise API calls.

The key benefits are:

  • No code required. You don't need to write API clients or know Zenskar's REST endpoints.
  • Composability. Claude can chain multiple tool calls to accomplish complex workflows — for example, finding a customer, identifying their open invoices, and approving them in a single conversation.
  • Auditability. Every action goes through the Zenskar API and is recorded in your account's audit log.

sequenceDiagram
    autonumber
    participant U as User (Human)
    box rgb(240, 248, 255) Local Environment (e.g., Laptop)
    participant C as MCP Host (e.g., Claude Desktop)
    participant S as Zenskar MCP Server
    end
    box rgb(255, 245, 240) Cloud
    participant API as Zenskar REST API
    end

    Note over C,S: Initialization: Host discovers 103 typed tools from Server

    U->>C: Prompts: "Show me open invoices for Acme Corp."
    
    activate C
    Note right of C: Host interprets intent<br/>and selects 'listInvoices' tool.
    C->>S: Invokes 'listInvoices' tool (JSON-RPC)
    activate S
    
    Note right of S: Server translates tool call<br/>to REST API request.

    S->>API: HTTP GET /invoices?status=open&customer=Acme (with Auth)
    activate API
    API-->>S: Returns JSON data (Invoices list)
    deactivate API

    S-->>C: Returns raw JSON results
    deactivate S

    Note right of C: Host sanitizes data<br/>and summarizes response.
    C-->>U: Responds: "Here are the 3 open invoices..."
    deactivate C

How the server handles authentication

The server is stateless: it stores no credentials between calls. Every tool invocation independently supplies authentication headers to the Zenskar API.

Token format detection is automatic. If your token is a JWT (starts with eyJ), it's sent as a Bearer token. Otherwise it's sent as an API key via the x-api-key header. You don't need to configure this; the server detects it at runtime.

This design means you can switch between API keys and JWT tokens without changing your configuration — you only need to update the token value.


How credentials are resolved at runtime

Credentials follow a clear precedence chain:

  1. Inline tool call parameters: If credentials are passed directly in a tool invocation, they take priority. This is useful when working across multiple Zenskar organizations in the same session.
  2. Environment variables: ZENSKAR_ORGANIZATION and ZENSKAR_AUTH_TOKEN serve as a fallback. Setting these in the config file is the recommended default for single-organization use.

If neither source provides credentials, the tool call will fail with an authentication error. The server will not attempt to prompt interactively outside of Claude's conversation context.


Design decisions and limitations

Why 103 separate tools?

MCP works best when each tool has a single, well-defined purpose. Rather than exposing a generic "call Zenskar API" tool, each operation is discrete. This lets Claude reason accurately about what it's doing, reduces ambiguity in tool selection, and makes error messages meaningful.

Asynchronous operations

Some Zenskar operations — invoice generation and revenue recognition in particular — are asynchronous. The server exposes listJobs and getJobById so Claude can poll for completion. In practice, Claude will do this automatically when it knows an operation is async, but you can also ask explicitly: "Check the status of job [job ID]."

No data stored by the server

The MCP server is a thin proxy. It receives tool calls, constructs HTTP requests to the Zenskar API, and returns the response. No data is cached, logged, or stored by the server itself. All persistence happens in your Zenskar account.

Scope of this server

The server covers the full published Zenskar API surface as of the time of release. If Zenskar adds new API endpoints after a given server version is published, those endpoints won't be available until the server package is updated. Run npm outdated -g mcp-zenskar to check for a newer version.