Skip to content

Connect Pennylane to Claude: Streamline Banking and Ledger Tasks

Learn how to connect Pennylane to Claude using a managed MCP server. Automate ledger lettering, bank reconciliation, and invoicing workflows with AI.

Uday Gajavalli Uday Gajavalli · · 9 min read
Connect Pennylane to Claude: Streamline Banking and Ledger Tasks

If you need to give AI agents access to your accounting stack to automate bank reconciliation, supplier invoice processing, or ledger lettering, you need a Model Context Protocol (MCP) server. This server translates Claude's function calls into structured requests against Pennylane's REST APIs. You can either build and host this translation layer yourself, or use a managed integration platform like Truto to dynamically generate an authenticated, ready-to-use MCP server URL.

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 sprawling financial ecosystem like Pennylane is a high-stakes engineering challenge. You have to handle OAuth 2.0 token lifecycles, parse deeply nested JSON schemas for ledger lines, and strictly adhere to French e-invoicing standards. Every time Pennylane updates a resource endpoint or adds a new Factur-X requirement, 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 financial workflows using natural language.

The Engineering Reality of the Pennylane API

A custom MCP server is a self-hosted integration layer. While the open MCP standard provides a predictable way for models to discover tools, implementing it against strict financial APIs is painful. You are not just integrating "Pennylane" - you are integrating their specific ledger logic, banking endpoints, and e-invoicing compliance standards.

If you decide to build a custom MCP server for Pennylane, you own the entire lifecycle. Here are the specific challenges you will face when mapping LLM tool calls to Pennylane's REST architecture:

Complex Lettering State Management Reconciling accounts in Pennylane is not a simple boolean flag update. Reconciling (or "lettering") ledger entry lines requires interacting with the create_a_pennylane_ledger_entry_lines_lettering endpoint, which demands an unbalanced_lettering_strategy and an array of at least two ledger entry line objects. Un-lettering has similar strict requirements. If you expose raw, unconstrained schemas to Claude, the model will frequently attempt to letter a single line or hallucinate the strategy strings, resulting in HTTP 400 errors.

E-Invoicing and Factur-X BT-126 Mandates Pennylane handles French B2B e-invoicing compliance. Importing an e-invoice (create_a_pennylane_e_invoices_import) via a Factur-X PDF file optionally accepts invoice_options to pre-fill customer and line-level data. However, each line's e_invoice_line_id must perfectly match the Factur-X BT-126 (LineID) standard. Building a custom MCP server means you have to write schema validation layers that catch these mismatches before they hit the Pennylane API, or risk the LLM generating completely invalid compliance documents.

State-Dependent Endpoints and Immutability Financial APIs enforce strict state machines. A Pennylane customer invoice in a draft state can be updated, but once it is finalized via update_a_pennylane_customer_invoice_finalize_by_id, it becomes an immutable record that can no longer be edited. Similarly, you cannot match transactions to a draft invoice. If your AI agent attempts to apply a payment to a draft quote or modify a finalized invoice, the API will reject it. Your agent prompts and tool descriptions must be heavily curated to explain this state machine to the LLM.

Strict Rate Limiting and 429 Pass-Through Financial APIs aggressively throttle traffic to protect database integrity. When calling Pennylane endpoints at high volume (such as fetching hundreds of ledger lines), you will inevitably hit rate limits. Truto does not retry, throttle, or apply backoff on rate limit errors. When the Pennylane upstream API returns an HTTP 429, Truto passes that error directly back to Claude.

What Truto does do is normalize the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. This guarantees that your agent framework receives predictable rate limit context, but the caller (the LLM agent) is entirely responsible for pausing execution and retrying the tool call later.

How to Generate a Pennylane MCP Server with Truto

Truto dynamically generates MCP tools based on Pennylane's documented API resources. By using Truto, you abstract away the OAuth flow, schema normalization, and pagination boilerplate, giving Claude immediate access to Pennylane operations.

You can generate the MCP server URL in two ways: via the UI or programmatically via the API.

Method 1: Via the Truto UI

For administrators and non-developers, generating a server from the dashboard takes seconds:

  1. Log in to your Truto dashboard and navigate to the integrated account page for your Pennylane connection.
  2. Click the MCP Servers tab.
  3. Click Create MCP Server.
  4. Configure the server parameters (name, allowed HTTP methods, tags, and an optional expiration date).
  5. Click Save. Copy the generated MCP server URL (e.g., https://api.truto.one/mcp/a1b2c3d4e5f6...).

Method 2: Via the Truto API

For engineering teams orchestrating agents programmatically, you can generate servers on the fly. You send a POST request to Truto specifying the integrated account and the desired configuration.

Truto validates that tools exist, securely hashes the token, and provisions the infrastructure in milliseconds.

Endpoint: POST /integrated-account/:id/mcp

{
  "name": "Pennylane Month-End Audit Agent",
  "config": {
    "methods": ["read", "write"],
    "tags": ["invoicing", "ledger", "banking"]
  },
  "expires_at": "2026-12-31T23:59:59Z"
}

The API responds with a fully formed MCP server URL containing the cryptographic token required for access:

{
  "id": "mcp-9a8b7c6d",
  "name": "Pennylane Month-End Audit Agent",
  "config": { "methods": ["read", "write"] },
  "expires_at": "2026-12-31T23:59:59.000Z",
  "url": "https://api.truto.one/mcp/a1b2c3d4e5f6..."
}

Connecting the MCP Server to Claude

Once you have your Truto MCP URL, you can plug it into any MCP-compliant client.

Option A: Connecting via UI (ChatGPT & Claude Web)

If your organization uses ChatGPT Business or Enterprise (or Claude's web interface when available), you can paste the URL directly into the settings:

  1. In ChatGPT, navigate to Settings -> Apps -> Advanced settings.
  2. Enable Developer mode.
  3. Under Custom connectors, click Add a new server.
  4. Name it (e.g., "Pennylane Accounting").
  5. Paste the Truto MCP URL into the Server URL field and click Add.

Option B: Connecting via Manual Config (Claude Desktop)

For developers running Claude Desktop locally, you inject the URL into your configuration file. Because Truto's MCP servers communicate over Server-Sent Events (SSE), you use the official MCP SSE transport utility to bridge the connection.

Open your claude_desktop_config.json (located at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS) and add:

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

Restart Claude Desktop. The model will initialize the connection, ingest the Pennylane tools, and confirm readiness via the UI.

Pennylane Hero Tools for Claude

Truto automatically maps Pennylane's REST architecture into descriptive, AI-friendly functions. Here are six high-leverage hero tools that transform Claude from a chatbot into a financial operator.

1. Create Invoice from Quote

Tool: create_a_pennylane_customer_invoices_create_from_quote

Instead of forcing the LLM to fetch quote data, map the lines manually, and POST a new invoice payload, this endpoint natively converts a quote into an invoice, inheriting the customer and line data automatically. It requires quote_id and an optional draft boolean.

"Claude, find quote ID 44921, convert it into a customer invoice in draft status, and confirm the new invoice number."

2. List External Transactions

Tool: list_all_pennylane_external_transactions

This tool allows Claude to query banking transactions across connected accounts. It supports filtering by bank_account_id, journal_id, or date, and sorting by id. The LLM can retrieve the amount, currency, and outstanding_balance to assist with reconciliation tasks.

"Fetch all banking transactions for bank account ID 112 from the last 7 days that have an outstanding balance greater than zero."

3. Match Transaction to Supplier Invoice

Tool: create_a_pennylane_supplier_invoice_matched_transaction

Reconciliation is a core accounting workflow. This tool allows the AI to apply a specific banking transaction to a supplier invoice. It requires supplier_invoice_id and transaction_id. Note that it matches one transaction per call; for partial payments across multiple transactions, Claude must call it iteratively.

"Take transaction ID 8831 and match it against supplier invoice ID 5092 to reconcile the payment."

4. Letter Ledger Entry Lines

Tool: create_a_pennylane_ledger_entry_lines_lettering

"Lettering" in Pennylane groups related ledger entry lines together (e.g., tying an invoice line to a payment line). This tool requires an unbalanced_lettering_strategy and an array of at least two ledger_entry_lines. If a passed line is already lettered, Pennylane merges the existing associated lines into the new lettering group.

"Letter ledger entry line 9912 and 9913 together. Use the standard unbalanced lettering strategy for this operation."

5. Update E-Invoice Lifecycle Status

Tool: update_a_pennylane_supplier_invoice_e_invoice_status_by_id

E-invoicing requires strict lifecycle tracking. This tool transitions a supplier invoice's e-invoice state to disputed, refused, or approved. Dispute and refuse transitions require the LLM to supply a valid reason in the payload.

"Update the e-invoice status of supplier invoice 4421 to 'refused'. Set the refusal reason as 'Incorrect VAT classification'."

6. Generate FEC Export

Tool: create_a_pennylane_exports_fec

The Fichier des Écritures Comptables (FEC) is a mandatory audit file for French companies. This tool triggers the asynchronous generation of the FEC export for a given period_start and period_end. Claude can use this in combination with the get_single polling endpoint to wait until the file_url is ready.

"Generate an FEC export for the period of January 1, 2026 through March 31, 2026. Let me know when the job is submitted."

For the complete inventory of available tools, query parameters, and schema details, visit the Pennylane integration page.

Workflows in Action

By chaining these tools together, Claude can execute complex, multi-step financial operations entirely autonomously. Here are two real-world scenarios.

Scenario 1: Automated Accounts Payable Reconciliation

The Persona: A Junior Accountant looking to reconcile a recent batch of supplier payments against the bank feed.

"Claude, check our recent bank transactions from this week. Find the payment of €1,200.00 to AWS. Then, find the corresponding open supplier invoice for AWS and match the transaction to it to clear the balance."

How the Agent Executes:

  1. Claude calls list_all_pennylane_external_transactions filtering for recent dates to find the €1,200.00 outgoing transaction, noting the transaction_id.
  2. Claude calls list_all_pennylane_external_supplier_invoices filtering by the supplier name (AWS) and looking for an accounting_status that indicates it is open or unpaid.
  3. Claude verifies the amounts match.
  4. Claude calls create_a_pennylane_supplier_invoice_matched_transaction passing the supplier_invoice_id and the transaction_id.
  5. Claude reports back that the invoice has been successfully matched and reconciled.
sequenceDiagram
    participant User as Accountant
    participant Claude as Claude Desktop
    participant MCP as Truto MCP Server
    participant Pennylane as Pennylane API

    User->>Claude: "Match the €1,200 AWS transaction to its open invoice."
    Claude->>MCP: tools/call list_all_pennylane_external_transactions
    MCP->>Pennylane: GET /v1/external/transactions
    Pennylane-->>MCP: Returns transactions array
    MCP-->>Claude: JSON transaction list
    Claude->>MCP: tools/call list_all_pennylane_external_supplier_invoices
    MCP->>Pennylane: GET /v1/external/supplier_invoices
    Pennylane-->>MCP: Returns invoices array
    MCP-->>Claude: JSON invoice list
    Claude->>MCP: tools/call create_a_pennylane_supplier_invoice_matched_transaction
    MCP->>Pennylane: POST /v1/supplier_invoices/{id}/matched_transactions
    Pennylane-->>MCP: HTTP 204
    MCP-->>Claude: Success confirmation
    Claude-->>User: "The AWS transaction is matched successfully."

Scenario 2: Year-End Audit Prep & FEC Generation

The Persona: A Controller preparing documentation for an external audit.

"Claude, I need to prep for the Q4 audit. Review the trial balance for Q4 to ensure there are no glaring discrepancies, and if it looks okay, trigger the generation of the FEC export for October 1 through December 31."

How the Agent Executes:

  1. Claude calls list_all_pennylane_external_trial_balances passing period_start (Oct 1) and period_end (Dec 31) to fetch the grouped ledger account balances.
  2. Claude analyzes the debits and credits, quickly scanning for anomalies or unbalanced totals.
  3. Claude calls create_a_pennylane_exports_fec passing the same period_start and period_end dates.
  4. Claude reads the asynchronous response, captures the export id, and informs the Controller that the job is processing, noting that they can retrieve the file_url in a few minutes.

Security and Access Control

Giving an AI agent raw access to a corporate ledger carries inherent risk. Truto provides several mechanisms to lock down your MCP server so Claude only operates within defined boundaries:

  • Method Filtering: Use config.methods: ["read"] to ensure the MCP server only exposes get and list endpoints. This prevents the LLM from accidentally finalizing invoices, deleting mandates, or lettering incorrect lines.
  • Tag Filtering: Restrict the agent's scope to specific functional areas using config.tags. For example, setting tags: ["invoicing"] means Claude will not be able to access general ledger endpoints or banking transactions.
  • Time-to-Live (TTL): Set an expires_at timestamp. Once the timestamp passes, the server URL automatically expires and Truto cleans up the underlying KV records, ensuring temporary contractors or automated jobs do not leave dangling access open.
  • API Token Authentication: By setting require_api_token_auth: true, possession of the MCP URL is no longer sufficient. The connecting client must also supply a valid Truto API token in the headers, adding a secondary layer of authentication for highly sensitive environments.

Closing the Loop on Financial Operations

Connecting Pennylane to Claude via a managed MCP server transforms natural language into actionable financial operations. Instead of burying your engineering team in OAuth tokens, rate limit retry loops, and complex e-invoicing schema validations, Truto handles the infrastructure layer. You get dynamic, documented tool generation out of the box, allowing your AI agents to safely read trial balances, reconcile bank transactions, and draft customer invoices.

FAQ

How does Claude handle Pennylane API rate limits?
When connecting via Truto, Claude receives standard IETF rate limit headers. Truto passes HTTP 429 errors directly through without automatic retries, forcing the LLM or your agent framework to execute its own backoff strategy.
Can I restrict Claude to read-only operations in Pennylane?
Yes. When generating the MCP server in Truto, you can apply method filtering (e.g., restricting the configuration strictly to 'read' operations) ensuring the model cannot alter invoices or ledger entries.
Does Truto cache my Pennylane financial data?
No. Truto's proxy architecture processes requests and responses in memory. Payload data from Pennylane is never persisted in Truto's databases.

More from our Blog