Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "expensify",
"description": "Connect Claude to your Expensify account — analyze spending, run expense reports, and get plain-English summaries of your team's financial data.",
"version": "1.0.0",
"author": {
"name": "Expensify",
"email": "contributors@expensify.com"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"email": "contributors@expensify.com"
"email": "concierge@expensify.com"

},
"homepage": "https://use.expensify.com",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"homepage": "https://use.expensify.com",
"homepage": "https://expensify.com",

"repository": "https://github.com/Expensify/expensify-plugin",
"license": "MIT",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add MIT LICENSE.md to this repo?

"keywords": ["expensify", "expenses", "finance", "accounting", "mcp"]
}
8 changes: 8 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mcpServers": {
"expensify": {
"type": "sse",
"url": "https://www.expensify.com/mcp"
}
}
}
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,47 @@
# Expensify Plugin for Claude

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed yesterday a lot of companies have a single plugin repo that holds all of their plugins, i.e. codex, claude, grok, etc. Should we generalize this? I think we are already headed that direction by having the claude settings in .claude-plugin. Here is stripe's for example https://github.com/stripe/ai


Connect Claude to your Expensify account and analyze your financial data using natural language.

## What this plugin does

This plugin connects Claude to the Expensify MCP server, giving Claude live access to your expenses, reports, receipts, trips, and workspace data. It includes two built-in skills for common financial workflows.

## Skills

### `/expensify:spend-brief`

Generate a plain-English spend summary for any time period. Claude pulls your Expensify transactions, organizes them by total, category, person, and vendor, flags anything unusual, and writes a narrative with recommended next steps.

**Example:** "Give me a spend brief for last month" or `/expensify:spend-brief Q3 2026`

### `/expensify:flux-analysis`

Compare spending across two periods to identify what changed and why. Claude surfaces the biggest movers by category and vendor, and explains the variance in plain English.

**Example:** "What changed in our spending last month vs. the month before?" or `/expensify:flux-analysis`

## Setup

### From the Claude plugin directory (once listed)

1. Open **Customize → Plugins → Browse plugins** in Claude Cowork.
2. Search for "Expensify" and click **Install**.
3. When prompted, sign in to your Expensify account to authorize access.

### Add this repo as a marketplace (available now)

1. Open **Customize → Plugins → Add marketplace** in Claude Cowork.
2. Enter `Expensify/expensify-plugin` and confirm.
3. The plugin appears in your marketplace list — click **Install**.
4. When prompted, sign in to your Expensify account to authorize access.

### Install from a zip file

1. Download the latest zip from the [releases page](https://github.com/Expensify/expensify-plugin/releases) (or zip this repo yourself).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's no release flow in this repo so unless we're going to do this manually we should either remove this or add a github action to create releases

2. Open **Customize → Plugins → Add plugin → Upload plugin** in Claude Cowork.
3. Select the zip file and install.
4. When prompted, sign in to your Expensify account to authorize access.

## Privacy

Claude accesses only the Expensify account you authorize. Your data is scoped to your account and workspace(s) and is not shared with third parties. See [Expensify's privacy policy](https://use.expensify.com/privacy).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Claude accesses only the Expensify account you authorize. Your data is scoped to your account and workspace(s) and is not shared with third parties. See [Expensify's privacy policy](https://use.expensify.com/privacy).
Claude accesses only the Expensify account you authorize. Your data is scoped to your account and workspace(s) and is not shared with third parties. See [Expensify's privacy policy](https://www.expensify.com/privacy).

58 changes: 58 additions & 0 deletions skills/flux-analysis/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
name: flux-analysis
description: Compare spending across two periods to identify what changed and why, surfacing the biggest movers by category and vendor with a plain-English explanation.
triggers:
- /expensify:flux-analysis

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is scoping like this best practice? I don't think i've ever seen this before. Should we also consider other trigger words that aren't / led? Do people use skills like this in Claude desktop?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or is that covered by the "when to use" section?

---

# Flux Analysis

Triggered by `/expensify:flux-analysis`. Compares spending across two periods — current vs. prior — identifies significant changes by category and vendor, and explains what drove the variance.

## When to use

Use this skill when the user asks about spending changes, variances, or trends — for example "what changed in our spending last month vs. the month before?" or "run a flux analysis on Q3 vs Q2."

## Steps

1. **Determine the periods.** Identify the current period and the prior comparison period from the user's request. If not specified, default to current month vs. prior month. Confirm before proceeding.

2. **Get workspaces.** Call `GetWorkspaceList` to find the user's workspaces and note the relevant policyID(s).

3. **Search with flux filters.** Call `Search` with `type: "expense"`, `shouldCalculateTotals: true`, and a `fluxPeriod` filter. The `fluxPeriod` filter compares the current period against an equivalent prior period automatically. Use `sortBy: "flux"` to surface the largest movers first. Run two searches:
- `groupBy: "category"` — variance by category
- `groupBy: "merchant"` — variance by vendor

Include `policyID` to scope to the workspace.

4. **Identify significant movers.** From the results, surface:
- Categories or vendors where spending increased or decreased by more than 20% (or a meaningful absolute amount)
- Any category or vendor that appeared in one period but not the other
- The single largest absolute dollar variance

5. **Write the analysis.** Structure it as:

**Flux Analysis: [Current Period] vs. [Prior Period]**

**Headline:** Total spend in each period, absolute change, and % change.

**Biggest increases:** Top 3–5 categories or vendors that grew the most, with prior amount, current amount, and % change.

**Biggest decreases:** Top 3–5 categories or vendors that shrank the most.

**New this period:** Any categories or vendors that had zero spend in the prior period.

**Dropped off:** Any categories or vendors present in the prior period but absent this period.

**What this means:** A 2–3 sentence plain-English interpretation of what drove the overall change — for example, "Most of the increase came from travel and software, while meals declined. The software spike is concentrated in two vendors..."

**Next steps:** 1–2 concrete actions, such as reviewing a specific category with a reviewer or checking whether a budget threshold was exceeded.

End with a link to the Expensify search using `search.searchURL` so the user can explore the details.

## Notes

- Amounts are in cents. Divide by 100 and format as currency.
- Time-period `groupBy` values (month, week, year, quarter) are incompatible with `fluxPeriod` — do not combine them. Use `groupBy: "category"` or `groupBy: "merchant"` with `fluxPeriod`.
- `fluxBasis` in the response is the prior-period total; `fluxAmount` is the change. Both are in cents.
- If the dataset is large, focus on the top 10 movers in each direction rather than listing everything.
62 changes: 62 additions & 0 deletions skills/spend-brief/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
name: spend-brief
description: Generate a plain-English spend summary for a time period, organized by total, category, person, and vendor, with anomaly flags and recommended next steps.
triggers:
- /expensify:spend-brief
---

# Spend Brief

Triggered by `/expensify:spend-brief`. Produces a plain-English spend summary for a given time period, organized by total, category, person, and vendor, with anomaly flags and recommended next steps.

## When to use

Use this skill when the user asks for a spending summary, overview, or brief for a period — for example "give me a spend brief for last month" or "summarize our Q3 spending."

## Steps

1. **Determine the period.** If the user specified a period, use it. If not, default to the current calendar month and confirm with the user before proceeding.

2. **Get the authenticated user.** Call `GetCurrentUser` to get the user's email and accountID.

3. **Get workspaces.** Call `GetWorkspaceList` to find the user's workspaces. If there is more than one, ask the user which workspace to analyze, or analyze all of them if they say so. Note the policyID(s) for use in subsequent searches.

4. **Run four parallel searches** for the period using `Search` with `type: "expense"`, `shouldCalculateTotals: true`, and the appropriate date filters on `"date"`. Run each with a different `groupBy`:
- `groupBy: "category"` — spending by category
- `groupBy: "from"` — spending by person
- `groupBy: "merchant"` — spending by vendor (top vendors)
- No `groupBy`, with `status: "all"` — full transaction list for anomaly detection (limit to top expenses by amount if the result set is large)

Include the `policyID` in each search to scope to the workspace. For personal spend questions, omit `policyID`.

5. **Calculate totals.** Use the `search.total` and `search.count` from the `shouldCalculateTotals` response as the headline figures.

6. **Flag anomalies.** Look for:
- Any single expense that is unusually large relative to the category average
- Categories with spending significantly above or below the prior comparable period (if data is available)
- Vendors that appear only once and carry a high amount
- Missing receipts on expenses above a reasonable threshold

7. **Write the brief.** Structure it as:

**[Period] Spend Brief**

**Headline:** Total spend, transaction count, number of people with expenses.

**By category:** Top 5–7 categories by spend, each with total and % of overall.

**By person:** Top spenders with their totals (omit if this is a personal account with one user).

**By vendor:** Top 5–7 vendors by total spend.

**Anomalies:** Bulleted list of anything that stands out. If nothing stands out, say so briefly.

**Next steps:** 2–3 concrete, actionable recommendations based on what the data shows — for example, following up on missing receipts, reviewing a category that spiked, or submitting outstanding reports.

End the brief with a link to the full search in Expensify using `search.searchURL` from one of the Search responses, so the user can drill in.

## Notes

- Amounts in Search results are in cents. Divide by 100 and format as currency when presenting to the user.
- Use the `personalDetailsList` map to resolve accountIDs to names/emails when presenting per-person breakdowns.
- If the workspace has no expenses in the period, say so clearly and suggest checking a broader date range.