---
title: "Connect Expensify to Claude: Manage Policies and Reconciliation"
slug: connect-expensify-to-claude-manage-policies-and-reconciliation
date: 2026-11-04
author: Uday Gajavalli
categories: ["AI & Agents"]
excerpt: "Learn how to build a managed MCP server to connect Expensify to Claude. Automate expense reports, policy management, and financial reconciliation securely."
tldr: "Step-by-step engineering guide on connecting Expensify to Claude via Truto's managed MCP server. Covers handling Expensify's async file exports, custom FreeMarker templates, zero-data-retention security, and executing multi-step financial workflows."
canonical: https://truto.one/blog/connect-expensify-to-claude-manage-policies-and-reconciliation/
---

# Connect Expensify to Claude: Manage Policies and Reconciliation


If you need to connect Expensify to Claude to automate expense reconciliation, manage policy workflows, or oversee employee spend rules, you need a [Model Context Protocol (MCP) server](https://truto.one/what-is-mcp-and-mcp-servers-and-how-do-they-work/). This server acts as the translation layer between Claude's tool calls and Expensify's API. You can either build and maintain this infrastructure yourself, or use a managed [integration platform like Truto](https://truto.one/managed-mcp-for-claude-full-saas-api-access-without-security-headaches/) to dynamically generate a secure, authenticated MCP server URL. If your team uses ChatGPT, check out our guide on [/connect-expensify-to-chatgpt-sync-expenses-and-automate-reports/](https://truto.one/connect-expensify-to-chatgpt-sync-expenses-and-automate-reports/) or explore our broader architectural overview on [/connect-expensify-to-ai-agents-bulk-update-staff-and-rules/](https://truto.one/connect-expensify-to-ai-agents-bulk-update-staff-and-rules/).

Giving a Large Language Model (LLM) read and write access to a specialized financial system like Expensify is an engineering challenge. You have to handle complex asynchronous file exports, map Expensify's unique domain models to MCP tool definitions, and deal with strict domain-admin scoping constraints. Every time an endpoint changes or you need to support a new FreeMarker template for 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 Expensify, connect it natively to Claude Desktop, and execute complex financial workflows using natural language.

> Want to give your AI agents secure, authenticated access to Expensify and 100+ other SaaS APIs? Let's talk about [managed MCP architecture](https://truto.one/managed-mcp-for-claude-full-saas-api-access-without-security-headaches/).
>
> [Talk to us](https://truto.one/book-a-demo/)

## The Engineering Reality of the Expensify 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, the reality of implementing it against Expensify's API is painful. Expensify does not behave like a standard CRUD REST API; it relies heavily on legacy batch processing patterns and templated exports.

If you decide to [build a custom MCP server](https://truto.one/the-hands-on-guide-to-building-mcp-servers-for-ai-agents-2026/) for Expensify, here are the specific integration challenges you will face:

**FreeMarker Templating for Data Exports**
When you want to pull data out of Expensify - whether it is a list of reports, expenses, or a company card reconciliation - you cannot just call a simple `GET /expenses` endpoint. Expensify requires you to pass a FreeMarker template string in your request payload to define exactly how the output file should be formatted. If your LLM attempts to generate this template on the fly, it will almost certainly fail due to syntax errors or missing required fields. A managed MCP server abstracts this away by strictly defining the expected inputs in the tool schema, guiding the LLM to provide only the necessary parameters while the underlying proxy handles the template injection.

**Asynchronous File Retrieval Workflows**
Exporting data from Expensify is inherently a two-step, asynchronous process. When you request a report export or a reconciliation file, the API does not return the data in the response body. Instead, it triggers a background job and returns a file name. You must then poll the file retrieval endpoint using that specific file name until the JSON data is ready. If you build your own MCP server, you have to write custom orchestration logic to handle this polling, otherwise Claude will simply see a file name and assume the job is finished. 

**Domain Admin Requirements and The Advanced Employee Updater**
Managing employees across policies (workspaces) requires navigating Expensify's strict permissions model. Bulk updating employees or managing company cards requires domain-level administrative rights, not just policy-level rights. Furthermore, updating staff relies on the "Advanced Employee Updater" endpoint, which expects a highly specific payload structure containing nested arrays for adding, updating, and removing employees simultaneously. Without a rigorously defined MCP JSON Schema, Claude will hallucinate the array structures, resulting in rejected API calls.

**Factual Note on Rate Limits**
When [building AI integrations](https://truto.one/the-hands-on-guide-to-building-mcp-servers-for-ai-agents-2026/), rate limits are a critical architectural consideration. Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream Expensify API returns an HTTP 429, Truto passes that error directly to the caller. Truto normalizes the upstream rate limit information into standardized headers (`ratelimit-limit`, `ratelimit-remaining`, `ratelimit-reset`) per the IETF specification. The caller - whether that is your custom code or the agent framework - is entirely responsible for implementing retry and backoff logic. Truto does not automatically absorb rate limit errors.

## How to Create the MCP Server for Expensify

Truto's MCP server generation is dynamic and documentation-driven. Rather than hand-coding tool definitions, Truto derives them directly from the integration's documented resources and schemas. This ensures that only well-curated, AI-ready tools are exposed.

You can generate an MCP server URL for a connected Expensify account in two ways.

### Method 1: Via the Truto UI

This is the fastest method for internal tooling or quick prototyping.

1. Log into your Truto dashboard and navigate to your connected Expensify environment.
2. Go to the integrated account page for the specific Expensify connection.
3. Click the **MCP Servers** tab.
4. Click **Create MCP Server**.
5. Select your desired configuration (e.g., limit to read-only methods, filter by specific tags, set an expiration date).
6. Copy the generated MCP server URL (it will look like `https://api.truto.one/mcp/a1b2c3...`).

### Method 2: Via the Truto API

For production use cases where you are provisioning AI agents dynamically for your customers, you should generate the MCP server programmatically.

Make a `POST` request to `/integrated-account/:id/mcp` with your desired configuration:

```typescript
const response = await fetch('https://api.truto.one/integrated-account/<EXPENSIFY_ACCOUNT_ID>/mcp', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <YOUR_TRUTO_API_TOKEN>',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: "Finance Team Expensify MCP",
    config: {
      methods: ["read", "write"], 
      tags: ["expenses", "policies"]
    },
    expires_at: "2026-12-31T23:59:59Z"
  })
});

const mcpServer = await response.json();
console.log("Your MCP Server URL:", mcpServer.url);
```

The returned URL is a fully self-contained, cryptographically secure endpoint. The URL itself acts as the authentication token, routing the request to the correct tenant's Expensify connection.

## How to Connect the MCP Server to Claude

Once you have the URL, connecting it to Claude is a matter of configuration. The MCP client will handle the JSON-RPC 2.0 handshake to discover the available tools.

### Method A: Via the Client UI (ChatGPT or Claude Web)

If you are using enterprise accounts that support UI-based custom connectors:

1. In your AI client settings, navigate to the integrations or custom connectors section (e.g., **Settings - Connectors - Add custom connector** in Claude, or **Settings - Apps - Advanced settings - Developer mode** in ChatGPT).
2. Provide a recognizable name (e.g., "Expensify Finance API").
3. Paste the Truto MCP Server URL.
4. Save the configuration. The client will immediately parse the available Expensify tools.

### Method B: Via Manual Config File (Claude Desktop)

For local development or custom agent deployments, you can configure Claude Desktop using the `claude_desktop_config.json` file. Because Truto provides a hosted SSE (Server-Sent Events) endpoint, you use the standard `@modelcontextprotocol/server-sse` package to proxy the connection.

Add the following to your configuration file:

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

Restart Claude Desktop. The Expensify tools will now appear as accessible capabilities in your prompt interface.

## Expensify Hero Tools

When you connect Expensify via Truto, Claude gains access to a normalized set of proxy methods. Here are the highest-leverage tools available for Expensify automation.

### List All Policies

**Tool Name:** `list_all_expensify_policies`

Before taking action on expenses or users, an agent needs to know which policy (workspace) it is operating within. This tool lists all policies the authenticated user can access, returning critical metadata including the Policy ID, which is required for almost all subsequent operations.

> "List all the Expensify policies available for this account. Return the Policy ID and name for the primary US entity workspace."

### Create an Expense

**Tool Name:** `create_a_expensify_expense`

This tool allows the agent to generate new expenses directly in an employee's account. It handles the specific JSON payload required by Expensify, ensuring that fields like amount, merchant, date, and the mandatory policy ID are formatted correctly.

> "Create an expense for $150.00 at 'Delta Airlines' for user john.doe@example.com under the US Entity policy. Categorize it as 'Travel' and mark the date as today."

### Create a Report

**Tool Name:** `create_a_expensify_report`

Once expenses are created, they must be grouped into a report for submission and approval. This tool creates a new report container on a specific policy. The agent can use this to logically group expenses by trip, project, or month.

> "Create a new expense report on the US Entity policy named 'Q3 Conference Travel' for user john.doe@example.com."

### Create a Reconciliation

**Tool Name:** `create_a_expensify_reconciliation`

This is a critical tool for finance teams. It triggers the generation of a company-card reconciliation file for a specific domain. Because this endpoint relies on Expensify's background job system, the tool kicks off the process and returns a file name.

> "Trigger a company card reconciliation for the domain example.com for the month of October. Give me the file name so we can retrieve the data."

### Get Single File by ID

**Tool Name:** `get_single_expensify_file_by_id`

This is the required second half of any export or reconciliation workflow. Once `create_a_expensify_reconciliation` or `expensify_reports_export` returns a file name, the agent uses this tool to download the actual JSON data representing the report or reconciliation.

> "Using the file name you just received, fetch the actual reconciliation file contents so I can review the unlinked card transactions."

### Bulk Update Employees

**Tool Name:** `expensify_employees_bulk_update`

This tool interacts with Expensify's Advanced Employee Updater. It allows an agent to add, modify, or remove policy members in bulk. This is exceptionally useful for automating onboarding and offboarding workflows.

> "Add sarah.smith@example.com to the US Entity policy as an 'employee', and update michael.jones@example.com to have an 'auditor' role. Process this as a single bulk update."

For the complete tool inventory and detailed JSON schemas, view the [Expensify integration page](https://truto.one/integrations/detail/expensify).

## Workflows in Action

Providing LLMs with isolated tools is just the starting point. The real power of MCP lies in chaining these operations together to automate multi-step domain workflows.

### Workflow 1: End-to-End Company Card Reconciliation

Finance operations teams spend hours manually matching corporate card feeds to submitted expenses. An AI agent can fully automate the retrieval of this data for auditing.

> "I need to audit our corporate card spend. Please trigger a reconciliation file for our main domain for last month. Once it is ready, fetch the file, analyze the data, and summarize any transactions over $500 that haven't been attached to an expense report yet."

**Execution Steps:**
1.  **`create_a_expensify_reconciliation`**: The agent calls this tool, passing the domain name and date range. Expensify begins processing the background job and returns a `file_name`.
2.  **`get_single_expensify_file_by_id`**: The agent calls this tool using the `file_name` it just received. It may receive a pending status, forcing it to retry briefly, until the full JSON reconciliation file is returned.
3.  **Data Analysis**: The agent parses the returned JSON, filters for unlinked transactions above $500, and formats a summary table for the user.

```mermaid
sequenceDiagram
    participant Claude as Claude Desktop
    participant Truto as Truto MCP
    participant Expensify as Expensify API
    
    Claude->>Truto: Call create_a_expensify_reconciliation
    Truto->>Expensify: POST /reconciliations
    Expensify-->>Truto: Return file_name
    Truto-->>Claude: Return file_name to agent
    
    Claude->>Truto: Call get_single_expensify_file_by_id (file_name)
    Truto->>Expensify: GET /files/{file_name}
    Expensify-->>Truto: Return JSON data
    Truto-->>Claude: Return parsed financial data
```

### Workflow 2: Employee Onboarding and Spend Rules

When a new employee joins, IT and HR need to provision them in Expensify, assign them to the correct workspace, and establish their baseline expense rules.

> "We have a new hire, Alex. Add alex.w@example.com to the primary US workspace as a standard employee. Then, create an expense rule for him that automatically flags any 'Meals' expense over $75."

**Execution Steps:**
1.  **`list_all_expensify_policies`**: The agent looks up the available workspaces to find the exact Policy ID for the "US workspace".
2.  **`expensify_employees_bulk_update`**: The agent constructs the nested array payload to add Alex to the identified policy.
3.  **`create_a_expensify_expense_rule`**: Using Alex's email and the Policy ID, the agent creates a specific rule targeting the 'Meals' category with a $75 limit.

### Workflow 3: Drafting a Client Trip Expense Report

Sales representatives frequently need to log multiple expenses from a single trip and group them together for their manager's approval.

> "I just got back from the Austin conference. I spent $45.50 at 'Terry Blacks BBQ' for dinner yesterday, and $350.00 at 'Hilton Austin' for lodging. Create these expenses for my account, create a new report called 'Austin Sales Trip', and put both expenses into that report."

**Execution Steps:**
1.  **`list_all_expensify_policies`**: The agent retrieves the user's active Policy ID.
2.  **`create_a_expensify_expense`**: The agent calls this tool twice - once for the BBQ meal and once for the hotel - capturing the returned Expense IDs for both.
3.  **`create_a_expensify_report`**: The agent creates the container report.
4.  **`update_a_expensify_report`** (or via the initial creation payload depending on integration depth): The agent links the generated Expense IDs to the newly created Report ID.

## Security and Access Control

Exposing financial systems like Expensify to AI models requires strict security boundaries. Truto's MCP architecture enforces security through several mechanisms on the server URL:

*   **Method Filtering**: You can strictly limit an MCP server to read-only operations by setting `methods: ["read"]`. This allows an agent to fetch policies and view expenses without the ability to create or delete financial records.
*   **Tag Filtering**: By applying `tags: ["reports"]`, you can isolate the server so the LLM only has context on report-related tools, hiding potentially dangerous administrative endpoints.
*   **Required API Token Auth**: For high-security environments, you can enable `require_api_token_auth: true`. This forces the MCP client to pass a valid Truto API token in the Authorization header, meaning the MCP URL alone is useless if leaked.
*   **Time-To-Live (TTL)**: You can set an `expires_at` timestamp. Once reached, the server is automatically destroyed. This is ideal for granting an AI agent temporary access to generate end-of-month reconciliations before revoking permissions.

## Wrapping Up

Connecting Claude to Expensify via MCP transforms the LLM from a passive chat interface into an active financial operator. By utilizing Truto to generate a managed MCP server, you eliminate the need to build custom infrastructure, manage OAuth token lifecycles, or constantly maintain code against Expensify's idiosyncratic endpoints. 

Instead, you get a secure, dynamic integration layer that scales with your AI strategy. Your agents gain the ability to navigate complex asynchronous exports, execute bulk updates safely, and manage financial workflows exactly as a human administrator would - just significantly faster.
