19 tools for receipt processing, expense tracking, IRS schedule reports, audit risk analysis, and deduction gap detection. Works with Claude, Cursor, and any MCP-compatible client.
Connect in under a minute. Get an API key from your account settings, then pick your setup.
claude mcp add --transport http \
writeoffs-ai https://writeoffs.ai/api/mcp \
--header "Authorization: Bearer YOUR_KEY"{
"mcpServers": {
"writeoffs-ai": {
"url": "https://writeoffs.ai/api/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer YOUR_KEY"
}
}
}
}curl -X POST https://writeoffs.ai/api/mcp \
-H "Authorization: Bearer sk-dip-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}'Everything you need to integrate with the writeoffs.ai MCP server.
All requests use the JSON-RPC 2.0 protocol over HTTP POST. Send requests to https://writeoffs.ai/api/mcp
POST /api/mcp HTTP/1.1
Content-Type: application/json
Authorization: Bearer sk-dip-YOUR_KEY
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tool_name",
"arguments": { ... }
}
}Use tools/list to discover available tools, or tools/call to invoke a tool.
Pass your API key in the Authorization header as a Bearer token. Keys use the sk-dip- prefix.
Authorization: Bearer sk-dip-abc123...Generate and manage keys from your account settings. Keys are hashed with SHA-256 — we never store the raw key.
Every MCP response includes credit and rate limit headers.
| Header | Description |
|---|---|
| X-Credits-Remaining | Credits left in your account after this request |
| X-Credits-Used | Credits consumed by this request (0 or 1) |
| X-RateLimit-Limit | Max requests allowed per window (60) |
| X-RateLimit-Remaining | Requests remaining in current window |
| X-RateLimit-Reset | Unix timestamp when the rate limit resets |
Errors return standard JSON-RPC error objects with descriptive messages.
401 — Invalid API key
{ "error": "Invalid API key. Check that your key starts with sk-dip- and has not been revoked." }402 — Insufficient credits
{ "error": "Insufficient credits. Buy more at https://writeoffs.ai/account" }429 — Rate limit exceeded
{ "error": "Rate limit exceeded. Retry after the time in the Retry-After header." }Pass a callback_url with submit_receipt to receive a POST when processing completes. Webhooks retry up to 3 times with exponential backoff.
Each webhook includes an HMAC-SHA256 signature for verification:
// Headers sent with each webhook POST:
X-Writeoffs-Signature: sha256=<hex_digest>
X-Writeoffs-Timestamp: <unix_seconds>
// Verify the signature:
const expected = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
if (signature !== `sha256=${expected}`) {
// Reject — invalid signature
}19 tools across 4 categories. All accessible through a single MCP endpoint. Expand each tool to see parameters and examples.
7 tools
submit_receipt▶Submit a receipt image for AI processing. Returns the parsed receipt ID.
| Parameter | Type | Req | Description |
|---|---|---|---|
| image_base64 | string | No | Base64-encoded image bytes (max ~3MB before encoding) |
| image_url | string | No | Publicly accessible image URL |
| filename | string | No | Optional filename hint (e.g. receipt.jpg) |
| business_id | string | No | Business UUID to associate with (optional) |
| callback_url | string | No | Optional HTTPS URL to POST receipt result when processing completes. |
| idempotency_key | string | No | Optional unique key to prevent duplicate submissions. Same key returns the original receipt. |
Request
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": { "name": "submit_receipt", "arguments": {
"image_url": "https://example.com/receipt.jpg",
"business_id": "uuid-here",
"callback_url": "https://your-server.com/webhook"
}}}Response
{ "receipt_id": "abc-123", "status": "processing" }batch_submit▶Submit multiple receipt images in one call (1 credit each, max 50).
| Parameter | Type | Req | Description |
|---|---|---|---|
| receipts | array | Yes | Array of receipt objects to submit (max 50) |
Request
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": { "name": "batch_submit", "arguments": {
"receipts": [
{ "image_url": "https://example.com/receipt1.jpg", "business_id": "uuid-here" },
{ "image_url": "https://example.com/receipt2.jpg" }
]
}}}Response
{ "submitted": 2, "deduplicated": 0, "credits_used": 2,
"results": [
{ "receipt_id": "abc-123", "status": "processing" },
{ "receipt_id": "def-456", "status": "processing" }
]}get_upload_url▶Get a presigned upload URL. Required for files >3MB or binary uploads before calling submit_receipt.
| Parameter | Type | Req | Description |
|---|---|---|---|
| filename | string | Yes | Filename with extension (e.g. receipt.jpg, scan.pdf) |
| content_type | string | No | MIME type (e.g. image/jpeg, application/pdf). Auto-detected from filename if omitted. |
get_receipt▶Retrieve a single receipt with category, IRS schedule/line, and business info.
| Parameter | Type | Req | Description |
|---|---|---|---|
| receipt_id | string | Yes | UUID of the receipt |
Request
{ "jsonrpc": "2.0", "id": 2, "method": "tools/call",
"params": { "name": "get_receipt", "arguments": {
"receipt_id": "abc-123"
}}}Response
{ "id": "abc-123", "status": "confirmed", "vendor": "Home Depot",
"total": 342.50, "receipt_date": "2026-02-15",
"dip_categories": { "name": "Repairs", "irs_schedule": "E", "irs_line": "14" }}batch_status▶Get status and parsed data for multiple receipts at once (max 100).
| Parameter | Type | Req | Description |
|---|---|---|---|
| receipt_ids | array | Yes | Array of receipt UUIDs to look up (max 100) |
Request
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": { "name": "batch_status", "arguments": {
"receipt_ids": ["abc-123", "def-456"]
}}}Response
{ "receipts": [
{ "id": "abc-123", "status": "confirmed", "vendor": "Home Depot", "total": 342.50 },
{ "id": "def-456", "status": "processing" }
]}download_receipt▶Get a temporary signed URL to download a receipt image/PDF.
| Parameter | Type | Req | Description |
|---|---|---|---|
| receipt_id | string | Yes | UUID of the receipt |
confirm_receipt▶Confirm a receipt, optionally updating vendor, total, category (by name or ID), or business.
| Parameter | Type | Req | Description |
|---|---|---|---|
| receipt_id | string | Yes | UUID of the receipt |
| vendor | string | No | Vendor name override |
| total | number | No | Total amount override |
| category_id | string | No | Category UUID override |
| category_name | string | No | Category name (case-insensitive). Used instead of category_id. Call list_categories to see valid names. |
| business_id | string | No | Business UUID to assign this receipt to (optional) |
4 tools
list_expenses▶List confirmed receipts with IRS schedule/line details.
| Parameter | Type | Req | Description |
|---|---|---|---|
| year | number | No | 4-digit tax year, e.g. 2025 |
| category | string | No | Category name to filter by (case-insensitive) |
| limit | number | No | Max results to return (default 50, max 200) |
| cursor | string | No | ISO date string cursor for pagination. Use next_cursor from previous response. |
Request
{ "jsonrpc": "2.0", "id": 3, "method": "tools/call",
"params": { "name": "list_expenses", "arguments": {
"year": 2026, "limit": 10
}}}Response
{ "expenses": [{ "id": "...", "vendor": "...", "total": 0, ... }],
"next_cursor": "2026-01-15" }add_expense_from_text▶Create a receipt from natural language (e.g. '$340 at Ferguson Supply').
| Parameter | Type | Req | Description |
|---|---|---|---|
| text | string | Yes | Natural language expense description |
list_categories▶List all expense categories with IDs and names. Use before confirm_receipt to find valid category values.
add_mileage_trip▶Record a business mileage trip with IRS-compliant rates.
| Parameter | Type | Req | Description |
|---|---|---|---|
| distance_miles | number | Yes | Trip distance in miles |
| purpose | string | Yes | Business purpose of the trip |
| start_at | string | Yes | ISO 8601 start datetime |
| end_at | string | No | ISO 8601 end datetime (optional) |
5 tools
get_tax_summary▶Get a tax-year summary grouped by IRS schedule and line item.
| Parameter | Type | Req | Description |
|---|---|---|---|
| year | number | No | 4-digit tax year (defaults to current year) |
Request
{ "jsonrpc": "2.0", "id": 4, "method": "tools/call",
"params": { "name": "get_tax_summary", "arguments": { "year": 2026 }}}Response
{ "year": 2026, "grand_total": 15420.50,
"schedules": { "E": { "total": 12100, "lines": { "14 - Repairs": 5400 } },
"C": { "total": 3320.50, "lines": {} } },
"uncategorized_total": 0 }get_schedule_report▶Get a complete IRS schedule report ready for tax filing.
| Parameter | Type | Req | Description |
|---|---|---|---|
| year | number | Yes | 4-digit tax year, e.g. 2026 |
| schedule | string (E|C|F) | Yes | IRS schedule: E (rental), C (business), or F (farm) |
classify_expense▶Classify a receipt as deductible repair vs capital improvement.
| Parameter | Type | Req | Description |
|---|---|---|---|
| receipt_id | string | Yes | UUID of the receipt to classify |
| answers | object | No | Optional answers to previous clarifying questions (key: question ID, value: answer) |
get_audit_risk▶Get an audit risk assessment with per-line-item risk scores.
| Parameter | Type | Req | Description |
|---|---|---|---|
| year | number | No | 4-digit tax year (defaults to current year) |
detect_deduction_gaps▶Detect likely missing deductions with estimated dollar values.
| Parameter | Type | Req | Description |
|---|---|---|---|
| year | number | No | 4-digit tax year (defaults to current year) |
3 tools
list_businesses▶List all businesses/properties with schedule type and ownership %.
create_business▶Create a business or property for schedule-level tax reporting.
| Parameter | Type | Req | Description |
|---|---|---|---|
| name | string | Yes | Business or property name |
| schedule | string (C|E|F) | No | IRS schedule (default C) |
| entity_type | string (sole_prop|llc|s_corp|c_corp|partnership) | No | Legal structure (default sole_prop) |
| ownership_pct | number | No | Ownership percentage 1-100 (default 100) |
run_cost_segregation▶Run cost segregation analysis for accelerated depreciation.
| Parameter | Type | Req | Description |
|---|---|---|---|
| asset_id | string | No | Optional UUID of an existing asset |
| purchase_price | number | Yes | Property purchase price |
| purchase_date | string | Yes | YYYY-MM-DD purchase date |
| property_type | string (residential_rental|commercial|mixed_use) | Yes | Type of property |
| year_built | number | Yes | Year the property was built |
| square_footage | number | Yes | Total square footage |
| num_units | number | No | Number of units (optional) |
| renovations | string | No | Description of any renovations (optional) |
No subscription required. Sign up free, buy credit packs, and start using the API.
Create a free account, generate an API key, and buy credits. No subscription needed.
AI-powered tools (submit, classify, audit, gaps, cost seg) cost 1 credit each.