Skip to content

Connect Pennylane to Claude: Manage Sales, Billing and Customers

Learn how to connect Pennylane to Claude using a managed MCP server. Automate invoicing, reconcile transactions, and manage billing without custom code.

Uday Gajavalli Uday Gajavalli · · 10 min read
Connect Pennylane to Claude: Manage Sales, Billing and Customers

If your team uses ChatGPT, check out our guide on connecting Pennylane to ChatGPT or explore our broader architectural overview on connecting Pennylane to AI Agents.

Giving a Large Language Model (LLM) read and write access to a complex financial and accounting platform like Pennylane is a significant engineering challenge. You have to handle OAuth 2.0 token lifecycles, map deeply nested financial schemas to Model Context Protocol (MCP) tool definitions, and deal with strict European e-invoicing compliance formats. Every time the upstream API introduces a breaking change or a new required field for general ledger exports, you have to update your server code, redeploy, and test the integration.

This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for Pennylane, connect it natively to Claude Desktop, and execute complex accounting and sales workflows using natural language.

The Engineering Reality of the Pennylane API

A custom MCP server is a self-hosted integration layer that translates an LLM's tool calls into REST API requests. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against a highly specialized accounting API like Pennylane is painful.

If you decide to build a custom MCP server for Pennylane, you own the entire API lifecycle. Here are the specific challenges you will face:

E-Invoicing and Factur-X Compliance Pennylane is deeply integrated into French and European compliance standards. When importing customer or supplier e-invoices, you are not just passing a flat JSON payload. The API requires handling specific file attachments, such as Factur-X PDF files (create_a_pennylane_e_invoices_import), and interfacing with the Partner Dematerialization Platform (PA). You must ensure that invoice options, line-level data, and e_invoice_line_id attributes perfectly match the Factur-X BT-126 specification. Expecting an LLM to blindly guess these compliance structures from a blank prompt will result in endless 400 Bad Request errors. A managed MCP server exposes these endpoints with strictly typed JSON schemas derived from documentation, guiding the model to generate valid payloads.

Strict Analytical Category Weighting Pennylane uses analytical categories to track profitability across different dimensions (e.g., departments, locations). The API enforces a strict mathematical rule: when assigning categories to a customer, supplier, or invoice line, the weights of the categories within the same group must sum exactly to 1. If an LLM attempts to distribute costs evenly across three categories (0.33 + 0.33 + 0.33 = 0.99), the Pennylane API will immediately reject the request.

Complex Matching and Lettering Logic Reconciliation in Pennylane isn't just updating a boolean paid status. You must explicitly link distinct entities. For example, reconciling bank transactions to customer invoices requires hitting the create_a_pennylane_customer_invoice_matched_transaction endpoint. For ledger entries, you must use create_a_pennylane_ledger_entry_lines_lettering, which requires passing an array of entry lines and an unbalanced_lettering_strategy. This is relational state manipulation that requires precise sequential API calls.

Rate Limits and 429 Handling Pennylane enforces strict API quotas to protect their infrastructure. It is critical to understand how this is handled: Truto does not retry, throttle, or apply backoff on rate limit errors. When the Pennylane API returns an HTTP 429 Too Many Requests, Truto passes that error directly to Claude. Truto normalizes the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. The caller (your AI agent or Claude application) is entirely responsible for reading these headers and implementing its own retry and backoff logic. Do not expect the infrastructure layer to magically absorb rate limits.

Instead of building this infrastructure from scratch, you can use Truto to dynamically generate a secure, authenticated MCP endpoint.

How to Generate a Pennylane MCP Server with Truto

Truto dynamically generates MCP tools from the Pennylane integration's underlying documentation and resource schemas. This means tools are never cached or stale. You can create an MCP server using either the Truto dashboard or the management API.

Method 1: Via the Truto UI

If you prefer a visual setup, you can generate an MCP server directly from your connected Pennylane instance:

  1. Navigate to the Integrated Accounts page in the Truto dashboard and select your active Pennylane connection.
  2. Click the MCP Servers tab.
  3. Click Create MCP Server.
  4. Configure the server. You can assign a human-readable name, set an expiration date, and apply method or tag filters (e.g., selecting only read methods to prevent the LLM from mutating accounting records).
  5. Click Save and copy the generated MCP server URL.

Method 2: Via the Truto API

For teams building programmatic AI applications, you can generate the MCP server dynamically via the API.

Make a POST request to /integrated-account/:id/mcp. You can pass a config object to filter which tools the LLM can access. Filtering is highly recommended - dumping hundreds of Pennylane API endpoints into Claude's context window consumes unnecessary tokens and slows down inference.

const response = await fetch('https://api.truto.one/integrated-account/YOUR_ACCOUNT_ID/mcp', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_TRUTO_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: "Pennylane Billing & Sales Agent",
    config: {
      methods: ["read", "write"], // Restrict to specific method types if needed
      tags: ["invoices", "customers", "billing"] // Only expose tagged endpoints
    },
    expires_at: "2026-12-31T23:59:59Z" // Optional: set a TTL for contractor or temporary agent access
  })
});
 
const mcpServer = await response.json();
console.log(mcpServer.url); 
// Returns: https://api.truto.one/mcp/a1b2c3d4e5f6...

The API generates a cryptographically secure token, hashes it, and stores the metadata in a distributed key-value store. The returned URL (mcpServer.url) is a fully self-contained JSON-RPC 2.0 endpoint. It requires no additional OAuth configuration on the client side.

Connecting the MCP Server to Claude

Once you have your Truto MCP URL, you need to register it with your LLM client.

Method A: Via the Claude or ChatGPT UI

If you are using Claude's web interface or ChatGPT's custom connectors:

For Claude:

  1. Go to Settings -> Integrations -> Add MCP Server (or Custom Connectors, depending on your organization plan).
  2. Name the server (e.g., "Pennylane Truto").
  3. Paste the Truto MCP URL.
  4. Click Add. Claude will immediately issue a tools/list handshake and discover the available Pennylane operations.

For ChatGPT:

  1. Navigate to Settings -> Apps -> Advanced settings.
  2. Toggle Developer mode on.
  3. Under MCP servers / Custom connectors, click add a new server.
  4. Enter the Truto MCP URL and save.

Method B: Via Manual Config File (Claude Desktop)

If you are running Claude Desktop locally and want to bind the MCP server via the configuration file, you use the standard Server-Sent Events (SSE) client transport. Because the Truto MCP endpoint is hosted in the cloud, you instruct Claude to bridge local standard input/output to the remote SSE endpoint using the official @modelcontextprotocol/server-sse package.

Open your claude_desktop_config.json file (typically located at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows) and add the following:

{
  "mcpServers": {
    "pennylane-truto": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-sse",
        "https://api.truto.one/mcp/YOUR_GENERATED_TOKEN"
      ]
    }
  }
}

Restart Claude Desktop. The application will initialize the connection, read the integration schemas, and expose the tools to the chat interface.

Hero Tools for Pennylane Workflows

When the agent connects, it gains access to the specific resources defined in your Truto configuration. Here are the highest-leverage tools available for automating Pennylane.

List All External Customers

Tool: list_all_pennylane_external_customers

This is the foundational tool for identifying client records before creating invoices or billing subscriptions. It returns both company and individual customers, including their external references, billing addresses, and payment conditions. It supports filtering by customer type or external reference.

"Find the customer record for 'Acme Corp' in Pennylane. I need their internal ID and current payment conditions to draft a new quote."

Create a Billing Subscription

Tool: create_a_pennylane_external_billing_subscription

This tool allows the agent to establish recurring revenue rules. Pennylane will use this subscription to automatically generate customer invoices on each recurring occurrence. The tool requires configuring the start date, recurring rule, and linking it to a customer ID.

"Set up a new monthly billing subscription for customer ID 987654. The subscription should start on the first of next month and include a $500 software licensing fee."

Import Customer E-Invoices

Tool: create_a_pennylane_e_invoices_import

Crucial for European compliance, this tool allows the agent to import a customer e-invoice from a Factur-X PDF file. The agent can supply invoice_options to pre-fill line-level data. The schema enforces that the e-invoice line IDs must match the Factur-X BT-126 specification.

"I have a Factur-X PDF file for the latest consulting engagement. Import this as an e-invoice in Pennylane for customer ID 12345, ensuring the line items match the provided BT-126 identifiers."

List Bank Transactions

Tool: list_all_pennylane_external_transactions

Retrieves the banking ledger. This tool exposes banking transactions with their amounts, dates, associated bank accounts, and outstanding balances. It is heavily used in reconciliation workflows to find unmatched deposits.

"Pull the list of recent bank transactions for the primary checking account. Filter for deposits over $1,000 made in the last 7 days."

Match Transaction to Customer Invoice

Tool: create_a_pennylane_customer_invoice_matched_transaction

This is the core reconciliation action. It explicitly links a specific bank transaction ID to a customer invoice ID. If an invoice requires multiple transactions to close, the agent can call this tool multiple times iteratively.

"Match transaction ID tx_778899 to customer invoice ID inv_554433 to reconcile the outstanding balance. Confirm when the match is complete."

List Ledger Entry Lines

Tool: list_all_pennylane_external_ledger_entry_lines

Provides deep access to the raw accounting data. It returns debits, credits, labels, and analytical categories for specific ledger accounts or journals. Agents use this to perform complex audits or prepare data for custom financial reporting.

"Retrieve all ledger entry lines for account 411000 (Accounts Receivable) from the last 30 days. Calculate the total unlettered debit balance."

For a comprehensive list of all available Pennylane operations, pagination schemas, and query parameters, visit the Pennylane integration page.

Workflows in Action

With the MCP server connected, Claude transitions from a passive chat interface to an active financial operator. Here is how specific, multi-step workflows execute in practice.

Workflow 1: Automated Payment Reconciliation

Finance teams spend hours manually matching bank deposits to open invoices. Claude can automate this by querying outstanding balances and executing the match.

"I need to reconcile payments for our enterprise clients. Find all unpaid customer invoices from the last two weeks, check the recent bank transactions for matching deposit amounts, and link the transactions to the invoices to close them out."

Execution Steps:

  1. Query Invoices: Claude calls list_all_pennylane_external_commercial_documents (or a specific invoice listing tool) filtering for documents with a payment_status indicating an outstanding balance.
  2. Query Bank Transactions: Claude calls list_all_pennylane_external_transactions to pull recent deposits.
  3. Analyze and Match: The LLM compares the outstanding invoice amounts against the transaction amounts and dates.
  4. Execute Reconciliation: For each exact match, Claude calls create_a_pennylane_customer_invoice_matched_transaction, passing the customer_invoice_id and the transaction_id.
sequenceDiagram
    participant Agent as Claude Agent
    participant Truto as Truto MCP
    participant Pennylane as Pennylane API
    
    Agent->>Truto: Call list_all_pennylane_external_transactions
    Truto->>Pennylane: GET /external/transactions
    Pennylane-->>Truto: Return raw transaction list
    Truto-->>Agent: Return JSON-RPC result
    
    Agent->>Agent: Identify $5,000 deposit
    
    Agent->>Truto: Call create_a_pennylane_customer_invoice_matched_transaction
    Truto->>Pennylane: POST /customer_invoices/{id}/matched_transactions
    Pennylane-->>Truto: 204 No Content
    Truto-->>Agent: Return Success

Workflow 2: Supplier E-Invoice Processing

When a new vendor invoice arrives via email, an agent can ingest the file, map the supplier, and push the record directly into Pennylane's general ledger.

"We received a new invoice from AWS for $1,200. I have uploaded the PDF attachment to your context. Import this as a new supplier invoice in Pennylane, link it to the Amazon Web Services supplier record, and set the deadline to 30 days from today."

Execution Steps:

  1. Upload File: Claude calls create_a_pennylane_external_file_attachment to upload the PDF bytes and receives a file_attachment_id in return.
  2. Find Supplier: Claude calls list_all_pennylane_external_suppliers, searching for "Amazon Web Services" to retrieve the supplier_id.
  3. Import Invoice: Claude calls create_a_pennylane_supplier_invoices_import. It maps the file_attachment_id, supplier_id, calculates the deadline, and populates the currency_amount based on its extraction of the PDF context.
  4. Validate Accounting: Finally, Claude calls update_a_pennylane_supplier_invoice_validate_accounting_by_id to transition the imported draft into a Complete accounting state.

Security and Access Control

Giving an LLM access to a company's general ledger demands strict security boundaries. Truto's MCP architecture enforces control at the infrastructure layer, preventing prompt injection attacks from compromising your financial data.

  • Secure Token Storage: The generated token in the URL is never stored in plain text. It is hashed via HMAC using a secure signing key before being persisted in a distributed key-value store.
  • Method Filtering: You can configure the methods property on the MCP token to strictly allow specific HTTP verbs. For example, setting methods: ["read"] ensures the agent can query ledger lines but is physically blocked at the proxy layer from executing create or update operations.
  • Tag Grouping: You can use tags to restrict access by functional area. An agent analyzing sales metrics only needs access to tools tagged with "crm" or "billing", completely hiding supplier payment endpoints.
  • API Token Authentication Layer: By default, possessing the MCP URL is enough to connect. For high-security environments, you can enable require_api_token_auth: true. This forces the Claude client to pass a valid Truto API token in the Authorization header, adding a second layer of identity validation.
  • Automated Expiration: The expires_at field allows you to create temporary MCP servers. Once the timestamp passes, a distributed alarm system automatically deletes the token metadata, permanently severing the connection.

Through automated documentation parsing, normalized proxy routing, and strict cryptographic controls, Truto allows engineering teams to ship production-grade AI integrations without writing integration-specific code.

FAQ

Does Truto automatically handle Pennylane rate limits?
No. Truto does not retry, throttle, or apply backoff on rate limit errors. When Pennylane returns an HTTP 429, Truto passes that error directly to Claude, normalizing the rate limit headers. Your agent is responsible for implementing retry logic.
Can I restrict the MCP server to only read data from Pennylane?
Yes. When creating the MCP server via the Truto API or UI, you can apply method filters. Setting the configuration to only allow 'read' or 'list' methods ensures the LLM cannot mutate your accounting data.
How are Pennylane API pagination differences handled?
Truto normalizes upstream pagination models into standard 'limit' and 'next_cursor' fields within the tool schemas. The LLM is explicitly instructed to pass cursor values back unchanged to fetch subsequent pages.
Do I need to maintain the Pennylane API schemas?
No. Truto automatically generates and updates the MCP tool definitions, including descriptions and parameter schemas, directly from the underlying integration documentation. If Pennylane updates an endpoint, the tool schema updates dynamically.

More from our Blog