thred-mcp and runs locally over stdio.
Ask
Read-only questions about the business — overview, cash flow, AR/AP, reports.
Do
Write actions — create invoices, record payments, manage customers, vendors & bills.
Watch
Proactive alerts (overdue, cash-low, unusual transactions). Roadmap — not yet shipped.
How it works
The MCP server is a thin, stateless adapter. It does not store data — every tool call is translated into a single authenticated request against the Partner API (https://api.thredfi.com).
- The AI client launches
thred-mcpas a subprocess and speaks MCP over stdio. - On the first tool call, the server exchanges your Partner UUID + API Key for an OAuth2 access token.
- The token is cached in memory and reused until ~5 minutes before expiry, then refreshed automatically.
- Each tool maps to one Partner API endpoint; the JSON response is returned to the model.
The MCP server is channel-agnostic and runs entirely on the user’s machine. Your Partner credentials never leave the local process, and no Thred data is persisted by the server.
Installation
Requires Node.js 18+. No global install needed — clients run it vianpx.
Authentication
The server reads two environment variables and performs the OAuth2client_credentials flow for you:
| Variable | Required | Description |
|---|---|---|
THRED_PARTNER_UUID | Yes | Your Partner UUID from the Partner Portal |
THRED_API_KEY | Yes | Your Partner API Key |
POST /v1/platform/oauth2/token/; the returned access_token is then used as a Bearer token on every API call. See Authentication for the underlying token model.
Connecting an AI client
- Claude Desktop
- Cursor / VS Code
- Manual / debugging
Edit A hammer icon appears in the composer — click it to see the Thred tools.
~/Library/Application Support/Claude/claude_desktop_config.json (create it if missing), then fully restart Claude (Cmd+Q and reopen):Tool catalog
The server exposes 49 tools across 9 categories. Every tool requires abusiness_id (resolve it first with list_businesses). Tools are tagged R (read) or W (write); write tools should be confirmed with the user before execution.
Businesses (5)
Businesses (5)
| Tool | Type | Purpose |
|---|---|---|
list_businesses | R | List all businesses under the partner — the entry point for resolving business_id |
get_business | R | Fetch a single business |
create_business | W | Onboard a new business |
update_business | W | Update business details |
archive_business | W | Archive a business |
Customers (6)
Customers (6)
| Tool | Type | Purpose |
|---|---|---|
list_customers | R | List / search customers — used to match a name to a customer_id |
get_customer | R | Fetch a single customer |
create_customer | W | Create a customer (company_name for businesses, individual_name for people) |
update_customer | W | Update a customer |
archive_customer | W | Archive a customer |
unarchive_customer | W | Restore an archived customer |
Invoices (5)
Invoices (5)
| Tool | Type | Purpose |
|---|---|---|
list_invoices | R | List invoices, filterable by status (draft, sent, paid, overdue, void) |
get_invoice | R | Fetch a single invoice |
create_invoice | W | Create an invoice for a customer |
update_invoice | W | Update an invoice |
void_invoice | W | Void an invoice (irreversible) |
Invoice Payments (5)
Invoice Payments (5)
| Tool | Type | Purpose |
|---|---|---|
list_invoice_payments | R | List payments recorded against invoices |
get_invoice_payment | R | Fetch a single payment |
create_invoice_payment | W | Record a payment against an invoice |
update_invoice_payment | W | Update a recorded payment |
delete_invoice_payment | W | Delete a payment (reverts invoice to unpaid) |
Vendors (6)
Vendors (6)
| Tool | Type | Purpose |
|---|---|---|
list_vendors | R | List / search vendors — used to match a name to a vendor_id |
get_vendor | R | Fetch a single vendor |
create_vendor | W | Create a vendor |
update_vendor | W | Update a vendor |
archive_vendor | W | Archive a vendor |
unarchive_vendor | W | Restore an archived vendor |
Bills & Bill Payments (10)
Bills & Bill Payments (10)
| Tool | Type | Purpose |
|---|---|---|
list_bills | R | List bills (accounts payable / vendor spend) |
get_bill | R | Fetch a single bill |
create_bill | W | Record a bill from a vendor |
update_bill | W | Update a bill |
void_bill | W | Void a bill |
list_bill_payments | R | List payments made against bills |
get_bill_payment | R | Fetch a single bill payment |
create_bill_payment | W | Record a payment against a bill |
update_bill_payment | W | Update a bill payment |
delete_bill_payment | W | Delete a bill payment |
Chart of Accounts (6)
Chart of Accounts (6)
| Tool | Type | Purpose |
|---|---|---|
list_chart_of_accounts | R | List all ledger accounts |
get_chart_of_accounts_hierarchy | R | Get the account tree (preferred for categorization) |
get_account | R | Fetch a single account |
create_account | W | Create a ledger account |
update_account | W | Update an account |
archive_account | W | Archive an account |
Financial Reports (6)
Financial Reports (6)
| Tool | Type | Purpose |
|---|---|---|
get_profit_and_loss | R | P&L over a date range (start_date, end_date) |
get_balance_sheet | R | Balance sheet as of a date (as_of_date) |
get_cash_flow | R | Cash flow statement over a date range |
get_ar_aging | R | Accounts receivable aging |
get_ap_aging | R | Accounts payable aging |
get_financial_summary | R | High-level financial insights over a date range |
Composed capabilities
Several product experiences are not single endpoints — the AI assistant orchestrates multiple atomic tools and composes the narrative, emails, or layout around the returned data:| Capability | How it’s composed |
|---|---|
| Board pack | get_profit_and_loss (current + prior period) + get_cash_flow + get_balance_sheet, synthesized into a summary with runway |
| Natural-language dashboard | Report tools called with date ranges derived from the user’s phrasing (“last 6 months”), optionally across multiple periods for comparison |
| Payment reminders | list_invoices (status overdue) → match customer → AI-composed reminder email |
| Vendor outreach | list_vendors / list_bills → identify missing document → AI-composed request |
Behavioral model
Tool descriptions are written to steer the model toward safe, useful behavior:Confirmation
High-risk writes (
create_*, void_*, delete_*) prompt for explicit user confirmation before executing.Slot-filling
Missing required fields (amount, due date, line items) trigger follow-up questions rather than guesses.
Name matching
Customer/vendor names are resolved to IDs via the
list_* tools — the model never fabricates an ID.Request lifecycle & errors
- Transport: JSON-RPC over stdio (
@modelcontextprotocol/sdk). - Auth caching: one token per process, refreshed ~5 minutes before
expires_in. - Methods: tools map to
GET/POST/PATCH/PUT/DELETEon/v1/platform/.... - Errors: non-2xx responses are returned to the model as
Error: API error <status> on <method> <path>: <body>withisError: true, so the assistant can explain or retry. A204 No Contentresolves to an empty result.
Example prompts
Source & package
thred-mcp on npm · npx thred-mcp