YNAB预算管理服务器

一个提供Claude安全访问YNAB(You Need A Budget)API的模型上下文协议(MCP)服务器,用于通过自然对话管理预算数据。

  • by Bernix01
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 Bernix01/ynab-mcp

使用说明

YNAB MCP服务器

一个模型上下文协议(MCP)服务器,为Claude提供对YNAB(You Need A Budget)API的安全访问。

为什么存在

此MCP服务器允许Claude直接管理您的YNAB预算数据——通过自然对话创建交易、检查余额、更新类别等。

示例用例: YNAB的自动银行同步功能并非在所有地区都可用。使用此服务器,您可以向Claude发送您的银行对账单(PDF、CSV或屏幕截图),并让它添加缺失的交易,匹配现有的交易,并保持预算的准确性。不再手动输入。

数据隐私

我们存储的内容:

  • 您的电子邮件和密码哈希 --用于对此MCP服务器进行身份验证
  • YNAB OAuth令牌(加密) --这样克劳德就可以代表您访问您的YNAB数据。这些在存储之前用AES-256-GCM加密

我们不存储的内容:

  • 您的银行对账单 --这些信息直接发送给克劳德,永远不会触及我们的服务器
  • 您的YNAB预算数据 -我们只代理YNAB的API请求;没有缓存或存储任何内容
  • 交易 --所有交易数据都流向YNAB,不会被保留

它是如何工作的:

  1. 您通过此服务器进行身份验证(创建会话)
  2. 您连接您的YNAB帐户(我们存储加密令牌)
  3. 当Claude需要YNAB数据时,它会调用我们的MCP工具,该工具代理YNAB的API
  4. 你的银行对账单与克劳德的背景直接相关——我们从未见过

建筑

flowchart TB
    subgraph Client["Claude Client"]
        CC[Claude Code/Desktop]
    end

    subgraph Server["MCP Server (Vercel)"]
        MCP[MCP Handler]
        BA[BetterAuth<br/>OAuth 2.1 Provider]
        TOOLS[YNAB Tools]
        JWT[JWT Verification<br/>via JWKS]
    end

    subgraph Database["Neon Postgres"]
        USERS[(users)]
        SESSIONS[(sessions)]
        OAUTH[(oauth_clients)]
        YNAB_TOKENS[(ynab_tokens<br/>encrypted)]
    end

    subgraph External["External Services"]
        YNAB_API[YNAB API]
    end

    CC -->|"1. MCP OAuth 2.1<br/>(PKCE + JWT)"| BA
    BA --> USERS
    BA --> SESSIONS
    BA --> OAUTH

    CC -->|"2. MCP Requests<br/>(Bearer Token)"| MCP
    MCP --> JWT
    JWT -->|Verify via JWKS| BA
    MCP --> TOOLS

    TOOLS -->|"3. YNAB API Calls"| YNAB_API
    TOOLS --> YNAB_TOKENS

身份验证流程

MCP OAuth 2.1流(客户端到服务器)

sequenceDiagram
    participant C as Claude Client
    participant S as MCP Server
    participant BA as BetterAuth
    participant U as User Browser

    C->>S: Initial MCP Request
    S-->>C: 401 + OAuth Discovery URL
    C->>BA: GET /.well-known/oauth-authorization-server
    BA-->>C: OAuth Metadata (endpoints, PKCE support)

    alt Dynamic Registration
        C->>BA: POST /oauth2/register (Dynamic Client Registration)
        BA-->>C: client_id
    else Well-known Client
        Note over C: Use client_id "ynab"
    end

    C->>C: Generate PKCE (code_verifier + code_challenge)
    C->>U: Open Browser to /oauth2/authorize
    U->>BA: Login (email/password)
    BA->>U: Consent Screen
    U->>BA: Approve
    BA-->>C: Authorization Code (via callback)

    C->>BA: POST /oauth2/token (code + code_verifier)
    BA-->>C: Access Token (JWT) + Refresh Token

    C->>S: MCP Request + Bearer Token
    S->>S: Verify JWT via JWKS
    S-->>C: MCP Response

YNAB OAuth流(服务器到YNAB)

sequenceDiagram
    participant C as Claude Client
    participant S as MCP Server
    participant DB as Database
    participant Y as YNAB API
    participant U as User Browser

    C->>S: Call YNAB Tool (e.g., list_budgets)
    S->>S: Verify MCP JWT Token
    S->>DB: Check for YNAB tokens

    alt No YNAB Tokens
        S-->>C: Error: "Visit /api/ynab/authorize"
        C->>U: Show authorization URL
        U->>S: GET /api/ynab/authorize
        S->>S: Generate state token
        S->>DB: Store state for CSRF protection
        S-->>U: Redirect to YNAB OAuth
        U->>Y: Authorize access
        Y-->>U: Redirect to callback with code
        U->>S: GET /api/ynab/callback?code=XXX
        S->>Y: Exchange code for tokens
        Y-->>S: Access + Refresh tokens
        S->>S: Encrypt tokens
        S->>DB: Store encrypted tokens
        S-->>U: Redirect to success page
    end

    S->>DB: Get YNAB tokens
    S->>S: Decrypt tokens

    alt Token Expired (2 hours)
        S->>Y: Refresh token
        Y-->>S: New tokens
        S->>DB: Update encrypted tokens
    end

    S->>Y: API Request
    Y-->>S: Budget Data
    S-->>C: Tool Response

代币生命周期

stateDiagram-v2
    [*] --> NoToken: First Use

    NoToken --> Authorizing: User visits /api/ynab/authorize
    Authorizing --> Valid: OAuth callback success

    Valid --> NeedsRefresh: Token expires (2 hours)
    NeedsRefresh --> Valid: Auto-refresh successful
    NeedsRefresh --> Invalid: Refresh failed

    Invalid --> NoToken: Tokens deleted

    Valid --> [*]: API calls work

特征

  • 通过带有PKCE的BetterAuth进行完整的OAuth 2.1身份验证
  • 通过JWKS端点验证JWT令牌
  • YNAB OAuth集成自动令牌刷新
  • 预算、账户、交易和类别管理工具
  • 加密令牌存储(AES-256-GCM)
  • 使用Neon Postgres在Vercel上部署

入门指南

您可以使用公共托管实例,也可以运行自己的实例。

连接克劳德

连接按顺序有三个帐户/步骤:

1.在MCP服务器上创建帐户

访问 https://ynab-mcp.vercel.app (或您的自托管URL)并单击 创建账户.

这个帐户是克劳德验证的对象——它是 与YNAB登录分开 并且仅用于向此服务器识别您的身份。您的电子邮件和密码哈希值已存储;关于你的其他一切都没有保留下来。

2.将服务器添加到您的Claude客户端

选择与您的客户匹配的部分,并按照以下代码段进行操作:

在第一次连接时,Claude将打开一个浏览器,以便您可以登录到MCP服务器(步骤1中的帐户)。在批准OAuth同意屏幕后,客户端会收到一个令牌,连接即生效。

3.首次调用工具时授权YNAB

MCP服务器仍需要权限才能代表您与YNAB通信。您有两个选择:

  • 推荐: 登录地址: https://ynab-mcp.vercel.app (与步骤1相同的帐户),然后单击 连接YNAB帐户。您将被重定向到YNAB,批准访问,您就完成了。
  • 或者: 让克劳德做任何与YNAB相关的事情(例如。 “列出我的YNAB预算”).第一个调用返回一个一次性授权URL——打开它,在YNAB上批准,然后重试请求。

YNAB令牌在存储之前经过加密(AES-256-GCM),并在过期时(每2小时)自动刷新。

您可以随时通过询问Claude来检查连接: “检查我的YNAB连接状态。” (使用 ynab_connection_status 工具)。

示例提示

连接后,尝试:

  • “列出我的YNAB预算。”
  • “我现在的支票账户余额是多少?”
  • “给我看看本月‘杂货’类别中超过50美元的交易。”
  • “添加我昨天用杂货类信用卡在Costco进行的42.18美元交易。”
  • “这是我最新的银行对账单(附PDF)。查找YNAB中缺少的任何交易并添加它们,并标记任何看起来重复的交易。”
  • “这个月我还能在外出就餐上花多少钱?”
  • “本月将我的紧急基金类别预算增加200美元。”

银行对账单工作流程是标题用例:将文件放入Claude中,无需键入每一行即可与YNAB进行对账。

先决条件

快速开始

1.克隆和安装

git clone <your-repo-url>
cd ynab-mcp
npm install

2.配置环境

复制示例环境文件并填写您的值:

cp .env.example .env

所需的环境变量:

# Database (Neon Postgres)
DATABASE_URL=postgres://user:password@host/database?sslmode=require

# BetterAuth
BETTER_AUTH_SECRET=<generate-a-secure-secret>
BETTER_AUTH_URL=http://localhost:3000

# YNAB OAuth
YNAB_CLIENT_ID=<your-ynab-client-id>
YNAB_CLIENT_SECRET=<your-ynab-client-secret>
YNAB_REDIRECT_URI=http://localhost:3000/api/ynab/callback

3.设置数据库

将模式推送到您的Neon数据库:

npm run db:push

4.运行开发服务器

npm run dev

服务器将在以下时间可用 http://localhost:3000.

YNAB OAuth设置

  1. 首选 YNAB开发人员设置
  2. 点击“新建OAuth应用程序”
  3. 填写申请详情:
    • 应用程序名称:您的应用程序名称
    • 重定向URI: http://localhost:3000/api/ynab/callback (开发)或您的生产URL
  4. 将客户端ID和客户端密码复制到您的 .env 文件

部署

部署到Vercel

  1. 将您的存储库推送到GitHub
  2. 将项目导入 Vercel
  3. 在Vercel仪表板中配置环境变量
  4. 部署

记得更新:

  • BETTER_AUTH_URL 到您的Vercel部署URL
  • YNAB_REDIRECT_URI 到 https://your-domain.vercel.app/api/ynab/callback

MCP配置

克劳德桌面

将服务器添加到Claude Desktop配置中(claude_desktop_config.json):

{
  "mcpServers": {
    "ynab": {
      "type": "http",
      "url": "https://ynab-mcp.vercel.app/api/mcp"
    }
  }
}

服务器提供了一个众所周知的OAuth客户端(client_id: "ynab")支持:

  • 具有任何端口的本地主机回调(用于MCP的动态端口分配)
  • 公共客户端身份验证(PKCE,不需要客户端密钥)

在第一次连接时,Claude Desktop将打开一个浏览器供您登录并授权访问。

克劳德代码(CLI)

对于Claude Code,添加到您的项目 .mcp.json:

{
  "mcpServers": {
    "ynab": {
      "type": "http",
      "url": "https://ynab-mcp.vercel.app/api/mcp"
    }
  }
}

手动OAuth配置(高级)

如果您的MCP客户端需要明确的OAuth配置:

{
  "mcpServers": {
    "ynab": {
      "url": "https://your-domain.vercel.app/api/mcp",
      "transport": {
        "type": "http"
      },
      "auth": {
        "type": "oauth2",
        "client_id": "ynab",
        "discoveryUrl": "https://your-domain.vercel.app/.well-known/oauth-authorization-server"
      }
    }
  }
}

可用工具

连接状态

  • ynab_connection_status -检查YNAB连接和令牌有效性

预算管理

  • ynab_list_budgets -列出所有预算
  • ynab_get_budget -按ID获取预算详细信息
  • ynab_get_budget_settings -获取预算设置

账户管理

  • ynab_list_accounts -列出预算中的所有账户
  • ynab_get_account -获取帐户详细信息

事务管理

  • ynab_list_transactions -使用筛选器列出交易记录
  • ynab_get_transaction -获取交易详情
  • ynab_create_transaction -创建新交易
  • ynab_update_transaction -更新现有交易
  • ynab_delete_transaction -删除交易

计划交易管理

  • ynab_list_scheduled_transactions -列出已安排(经常性/即将发生)的交易
  • ynab_get_scheduled_transaction -获取计划交易详细信息
  • ynab_create_scheduled_transaction -创建新的计划交易
  • ynab_update_scheduled_transaction -更新现有的计划交易
  • ynab_delete_scheduled_transaction -删除计划交易

品类管理

  • ynab_list_categories -列出所有类别
  • ynab_get_category -获取类别详细信息
  • ynab_get_category_month -获取特定月份的类别详细信息
  • ynab_update_category_budget -更新某一类别的预算金额

月份管理

  • ynab_list_months -列出预算月份
  • ynab_get_month -获取预算月份详细信息

技术栈

组件 技术
框架 Next.js 16(应用路由器)
语言 TypeScript 5.7+
Auth BetterAuth+OAuth提供程序
数据库 Neon Postgres+Drizzle ORM
MCP @modelcontextprotocol/sdk
YNAB 官方YNAB SDK
部署 Vercel

安全

加密

  • 静止加密的YNAB令牌(AES-256-GCM)
  • PBKDF2密钥推导(100000次迭代)

OAuth安全

  • MCP OAuth:需要PKCE(S256),通过JWKS验证JWT令牌
  • YNAB OAuth:CSRF保护的状态参数,加密令牌存储

API安全

  • 身份验证端点的速率限制
  • 用户隔离(用户只访问自己的数据)
  • 日志中的敏感数据编辑

发展

脚本

npm run dev          # Start development server
npm run build        # Build for production
npm run start        # Start production server
npm run lint         # Run Biome linter
npm run format       # Format code with Biome
npm run db:generate  # Generate Drizzle migrations
npm run db:migrate   # Run Drizzle migrations
npm run db:push      # Push schema to database
npm run db:studio    # Open Drizzle Studio

项目结构

src/
├── app/
│   ├── api/
│   │   ├── auth/[...all]/     # BetterAuth routes
│   │   ├── mcp/               # MCP handler
│   │   └── ynab/              # YNAB OAuth routes
│   └── .well-known/           # OAuth discovery endpoints
├── db/
│   ├── index.ts               # Database client
│   └── schema.ts              # Drizzle schema
└── lib/
    ├── auth.ts                # BetterAuth configuration
    ├── mcp/
    │   ├── helpers.ts         # MCP helper functions
    │   └── tools/             # YNAB tool implementations
    │       ├── accounts.ts
    │       ├── budgets.ts
    │       ├── categories.ts
    │       ├── months.ts
    │       ├── status.ts
    │       └── transactions.ts
    └── ynab/
        ├── client.ts          # YNAB API client
        ├── oauth.ts           # YNAB OAuth flow
        ├── state.ts           # OAuth state management
        └── tokens.ts          # Token management

许可证

GPL-3.0-参见 许可证 了解详情。