---
name: graiden
description: Read and log the user's personal spending in Graiden, their expense tracker. Use when they ask to connect Graiden, ask about their spending, transactions, budgets or where their money went, or want to log an expense or income.
---

# Graiden

Graiden is the user's personal expense tracker. This skill lets you answer questions about their money (spending, transactions, categories, budgets) and log new transactions for them, through Graiden's HTTP API.

## Connecting

Every request needs the user's Graiden API key (it starts with `grd_`). Look for one in this order:

1. The `GRAIDEN_API_KEY` environment variable
2. The file `~/.config/graiden/api_key`
3. A key the user pasted to you

**If there's no key, get one yourself. Don't ask the user to copy anything.**

1. Start a connection request. Use your own name for `client_name`; it's shown to the user on the approval page.

       curl -s -X POST https://app.graiden.xyz/api/oauth/device \
         -H 'Content-Type: application/json' \
         -d '{"client_name": "Claude Code", "scope": "read write"}'

   The response contains `device_code`, `user_code`, `verification_uri_complete` and `interval` (5 seconds).

2. **Send the user `verification_uri_complete` right away** as a clickable link, for example: "Tap this link to connect Graiden, then press Allow." They can open it on their phone or laptop, and they'll sign in first if they need to.

3. Poll every 5 seconds until you get a key (the request expires after 10 minutes):

       curl -s -X POST https://app.graiden.xyz/api/oauth/token \
         -H 'Content-Type: application/json' \
         -d '{"grant_type": "urn:ietf:params:oauth:grant-type:device_code", "device_code": "<device_code>"}'

   - `{"error": "authorization_pending"}`: they haven't tapped Allow yet, so keep polling.
   - `{"access_token": "grd_...", ...}`: that's the key. You're connected.
   - `access_denied` or `expired_token`: stop, tell the user, and offer to try again.

Ask for `"scope": "read"` instead if you'll only read data. The user can also untick "Add transactions" when they approve.

Never ask for the user's Graiden password. Never print the full key back to the user or put it in a repository, commit, or shared file.

## After connecting

1. **Check the key works.** Run `curl -s https://app.graiden.xyz/api/v1/me -H "Authorization: Bearer $KEY"`. You should get back their currency. A 401 error means the key is wrong or was revoked, so connect again.

2. **Save the key** so future sessions don't need to connect again. If you have a filesystem, write it to `~/.config/graiden/api_key` and make it readable only by the user (`chmod 600`). With no filesystem (a chat app, for example), just use it for this conversation.

3. **Save this skill** so you know how to use Graiden next time. Download https://app.graiden.xyz/skill.md into your skills folder, for example:
   - Claude Code: `~/.claude/skills/graiden/SKILL.md`
   - Codex: `~/.codex/skills/graiden/SKILL.md`
   - Other agents: wherever you keep reusable instructions or rules

4. **Tell the user they're connected.** Include one useful fact from their data (for example this month's spending from /api/v1/summary) and two or three example questions they can ask you.

## Using the API

Base URL: `https://app.graiden.xyz/api/v1`. Send `Authorization: Bearer <key>` on every request. Responses are JSON.

    KEY="${GRAIDEN_API_KEY:-$(cat ~/.config/graiden/api_key 2>/dev/null)}"
    curl -s "https://app.graiden.xyz/api/v1/summary?from=2026-01-01&to=2026-01-31" -H "Authorization: Bearer $KEY"

All amounts are positive numbers in the user's currency (see /me). The `type` field says whether money came in (`income`) or went out (`expense`). Dates are ISO 8601, and filters take YYYY-MM-DD (both ends inclusive).

| Request | What it returns |
| --- | --- |
| `GET /me` | Their currency and plan |
| `GET /summary?from=&to=` | Total income, expenses and net, plus `by_category` and `by_month`. Defaults to the current month. **Use this for "how much did I spend…" questions.** |
| `GET /transactions` | Transactions, newest first. Params: `from`, `to`, `type` (income or expense), `category`, `search` (matches title or notes), `limit` (1-500, default 50), `offset`. Returns `transactions`, `total` and `next_offset` (null on the last page). |
| `GET /categories` | Category names with transaction counts |
| `GET /budgets` | Budgets with `spent`, `remaining` and `percent_used` for the current period |
| `POST /transactions` | Logs a transaction. JSON body: `title` (required), `amount` (required, positive), `type` (`expense` by default), `category` (pick an existing one from /categories, default "Other"), `date` (YYYY-MM-DD, default today), `notes` |

Example of logging an expense:

    curl -s -X POST https://app.graiden.xyz/api/v1/transactions \
      -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
      -d '{"title": "Starbucks", "amount": 6.5, "category": "Food & Dining"}'

Errors:
- **401:** the key is missing, wrong or revoked, so connect again.
- **403 `insufficient_scope`:** the key is read-only. Connect again and keep "Add transactions" ticked.
- **400:** the `message` field says what to fix.

## Tips

- Answer with real numbers and the user's currency. Round to two decimals.
- For trends, use `/summary` over a longer range and read `by_month`. Only page through `/transactions` when you need individual purchases.
- Before you log a transaction, confirm the amount and date unless the user was explicit.
- If you support remote MCP servers, you can use Graiden's MCP server at `https://app.graiden.xyz/api/mcp` instead. It runs its own sign-in (for example `claude mcp add --transport http graiden https://app.graiden.xyz/api/mcp`) or accepts the key as an `Authorization: Bearer` header.
