Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
คำอธิบายจากผู้ทำ (ภาษาอังกฤษตามต้นฉบับ)
Monarch Money API client with 30 MCP tools for accounts, transactions, budgets, and cashflow.
สามเรื่องนี้ไม่รวมเป็นคะแนนเดียว เพราะความเห็น การวัด และความนิยม เป็นคนละเรื่องกัน
ตัวนี้ยังไม่ได้เรียบเรียงเป็นภาษาไทย ด้านล่างคือข้อเท็จจริงที่เราอ่านจาก registry
เลือกโปรแกรม AI ที่คุณใช้ แล้วคัดลอกค่าตั้งไปวาง
MONARCH_TOKENค่าที่ติดป้ายความลับคือกุญแจของบัญชีคุณ อย่าส่งให้ใคร และอย่าวางในแชต
ต้องเตรียมก่อน
คุณใช้แอปไหน
เลือกแอปด้านบน เราจำไว้ให้ ครั้งหน้าปุ่มจะขึ้นว่า “ติดตั้งลง …”
เปิด Claude Desktop → Settings → Developer → Edit Config แล้ววางค่านี้ในไฟล์ claude_desktop_config.json
{
"mcpServers": {
"monarchmoney": {
"command": "npx",
"args": [
"-y",
"@hakimelek/monarchmoney"
],
"env": {
"MONARCH_TOKEN": "ใส่ค่าของคุณ"
}
}
}
}พิมพ์คำสั่งนี้ใน Terminal
claude mcp add monarchmoney --env MONARCH_TOKEN='ใส่ค่าของคุณ' -- npx -y @hakimelek/monarchmoneyเติมค่าที่เว้นว่างไว้ก่อนรัน
วางในไฟล์ .cursor/mcp.json ของโปรเจกต์ หรือ ~/.cursor/mcp.json
{
"mcpServers": {
"monarchmoney": {
"command": "npx",
"args": [
"-y",
"@hakimelek/monarchmoney"
],
"env": {
"MONARCH_TOKEN": "ใส่ค่าของคุณ"
}
}
}
}เบราว์เซอร์จะถามก่อนเปิดแอป จากนั้นแอปแสดงค่าตั้งให้ตรวจแล้วกดยืนยัน ช่อง key เว้นว่างไว้ให้คุณใส่เอง
วางในไฟล์ .vscode/mcp.json ของโปรเจกต์
{
"servers": {
"monarchmoney": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@hakimelek/monarchmoney"
],
"env": {
"MONARCH_TOKEN": "ใส่ค่าของคุณ"
}
}
}
}เบราว์เซอร์จะถามก่อนเปิดแอป จากนั้นแอปแสดงค่าตั้งให้ตรวจแล้วกดยืนยัน ช่อง key เว้นว่างไว้ให้คุณใส่เอง
ตัวนี้รันในเครื่องคุณ แต่ ChatGPT ต่อได้เฉพาะ server บนอินเทอร์เน็ต ลองเลือกแอปอื่น
ตัวเลือกเก็บในคุกกี้บนเครื่องนี้ ไม่ต้องมีบัญชี
ค่าตั้งนี้สร้างจากข้อมูลใน registry ของผู้ทำ ถ้าไม่ตรงกับ README ให้เชื่อ README
รันในเครื่องคุณ รายการเครื่องมือจะขึ้นในแอป AI หลังติดตั้ง
เราตรวจจากข้อมูลที่ใครก็เปิดดูได้ ยังไม่ได้อ่านโค้ด ข้อที่ไม่เกี่ยวกับตัวนี้ไม่นับในตัวหาร · ตรวจเมื่อ 7 พ.ย. 2569
ชื่อใน registry ยืนยันด้วยบัญชี GitHub hakimelek ซึ่งเป็นเจ้าของ repo
ยังไม่ได้อ่านข้อมูล repo จาก GitHub
ยังไม่ได้อ่านข้อมูล repo จาก GitHub
ตัวนี้รันบนเครื่องคุณ ไม่มี endpoint บนอินเทอร์เน็ต
ตัวนี้รันบนเครื่อง ใช้ค่าที่ตั้งในเครื่องแทน
รันในเครื่องคุณ เราอ่านรายการเครื่องมือได้เฉพาะตัวที่มี endpoint บนอินเทอร์เน็ต
เทียบกับทุก server ที่ยังใช้งานในหมวดนี้ทั้งทะเบียน ดาวนับเฉพาะเมื่อผู้ลงทะเบียนเป็นเจ้าของ repo
จากการตรวจเบื้องต้นของเรา ผ่าน 1 จาก 1 ข้อที่ตรวจได้ เรายังไม่ได้อ่านโค้ด ก่อนใส่กุญแจหรือ token ให้ดูว่า server ขอสิทธิ์อะไร และเลือกกุญแจที่ทำได้เท่าที่จำเป็น
ต้องใส่ค่าเหล่านี้: MONARCH_TOKEN
รันบนเครื่องของคุณ โปรแกรม AI จะเปิด server ขึ้นมาเองเมื่อใช้ ข้อมูลไม่ต้องผ่านเซิร์ฟเวอร์ของผู้ทำ (ยกเว้นตัวที่ไปเรียกบริการออนไลน์ต่อ)
repo บน GitHub มีการแก้โค้ดล่าสุด – และส่งรุ่นล่าสุด (0.3.1) เข้า registry 8 เดือนที่ผ่านมา
โปรแกรมที่รองรับ MCP เช่น Claude Desktop, Claude Code, Cursor และ VS Code ตัวนี้ต้องมี Node.js ในเครื่องด้วย
ในหมวดเดียวกันมี Spec Driven Development, Remote Desktop Commander, Qemu MCP
server หมวดเดียวกันจากผู้ทำคนอื่น เรียงตามดาว
อ่านการ์ด:★ ดาว GitHubiสามเสา: รีวิว · ผลตรวจ · การใช้งานiอัปเดต = วันที่ส่งรุ่นล่าสุดเข้า registryi
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Boot and drive QEMU VMs from an AI agent: keys, screenshots, serial. No guest agent.
ส่วนนี้คัดจาก repo ของผู้ทำตามต้นฉบับ PopNx MCP ไม่ได้ตรวจหรือรับรองเนื้อหา ตัด HTML รูปภาพ และสคริปต์ออกแล้ว ลิงก์จะพาออกนอกเว็บ
Node.js/TypeScript library for accessing Monarch Money data.
Disclaimer: This project is unofficial and not affiliated with Monarch Money.
npm install @hakimelek/monarchmoney
Requires Node.js 18+ (uses native fetch and AbortSignal.timeout).
import {
MonarchMoney, EmailOtpRequiredException, RequireMFAException, } from "@hakimelek/monarchmoney";
const mm = new MonarchMoney();
try { await mm.login("your@email.com", "password"); } catch (e) { if (e instanceof EmailOtpRequiredException) { // Monarch sent a verification code to your email const code = await promptUser("Enter the code from your email:"); await mm.submitEmailOtp("your@email.com", "password", code); } else if (e instanceof RequireMFAException) { // TOTP-based MFA is enabled on the account await mm.multiFactorAuthenticate("your@email.com", "password", "123456"); } }
// Fetch data — fully typed responses const { accounts } = await mm.getAccounts(); console.log(accounts[0].displayName, accounts[0].currentBalance);
Monarch's API requires email verification (OTP) for new devices/sessions, even when MFA is disabled. The library handles this with distinct exception types so your app can respond appropriately.
try {
await mm.login(email, password); } catch (e) { if (e instanceof EmailOtpRequiredException) { // A code was sent to the user's email — prompt them for it const code = await yourApp.promptForEmailCode(); await mm.submitEmailOtp(email, password, code); } }
await mm.login("email", "password", {
mfaSecretKey: "YOUR_BASE32_SECRET", });
The MFA secret is the "Two-factor text code" from Settings > Security > Enable MFA in Monarch Money.
After a successful login (including email OTP), you can save the token to avoid re-authenticating on every run:
// Save token after login
mm.saveSession(); // writes to .mm/mm_session.json (mode 0o600)
// Next time, login() loads the saved session automatically await mm.login(email, password); // uses saved token, no network call
// Or pass the token directly (skip login entirely) const mm = new MonarchMoney({ token: "your-saved-token" });
mm.saveSession(); // save to disk
mm.loadSession(); // load from disk mm.deleteSession(); // remove the file mm.setToken("..."); // set token programmatically
await mm.interactiveLogin(); // prompts for email, password, email OTP or MFA code
All methods return typed responses. Hover over any method in your editor for full JSDoc and type information.
| Method | Returns | Description |
|---|---|---|
getAccounts() | GetAccountsResponse | All linked accounts |
getAccountTypeOptions() | GetAccountTypeOptionsResponse | Available account types/subtypes |
getRecentAccountBalances(startDate?) | GetRecentAccountBalancesResponse | Daily balances (default: last 31 days) |
getAccountSnapshotsByType(startDate, timeframe) | GetSnapshotsByAccountTypeResponse | Snapshots by type ("year" / "month") |
getAggregateSnapshots(options?) | GetAggregateSnapshotsResponse | Aggregate net value over time |
getAccountHoldings(accountId) | GetAccountHoldingsResponse | Securities in a brokerage account |
getAccountHistory(accountId) | AccountHistorySnapshot[] | Daily balance history |
getInstitutions() | GetInstitutionsResponse | Linked institutions |
getBudgets(startDate?, endDate?) | GetBudgetsResponse | Budgets with actuals (default: last month → next month) |
getSubscriptionDetails() | GetSubscriptionDetailsResponse | Plan status (trial, premium, etc.) |
getTransactionsSummary() | GetTransactionsSummaryResponse | Aggregate summary |
getTransactions(options?) | GetTransactionsResponse | Transactions with full filtering |
getAllTransactions(options?) | Transaction[] | All matching transactions (auto-paginates) |
getTransactionPages(options?) | AsyncGenerator | Async generator yielding pages |
getTransactionCategories() | GetTransactionCategoriesResponse | All categories |
getTransactionCategoryGroups() | GetTransactionCategoryGroupsResponse | Category groups |
getTransactionDetails(id) | typed response | Single transaction detail |
getTransactionSplits(id) | typed response | Splits for a transaction |
getTransactionTags() | GetTransactionTagsResponse | All tags |
getCashflow(options?) | GetCashflowResponse | Cashflow by category, group, merchant |
getCashflowSummary(options?) | GetCashflowSummaryResponse | Income, expense, savings, savings rate |
getRecurringTransactions(start?, end?) | GetRecurringTransactionsResponse | Upcoming recurring transactions |
isAccountsRefreshComplete(ids?) | boolean | Check refresh status |
| Method | Returns | Description | |
|---|---|---|---|
createManualAccount(params) | CreateManualAccountResponse | Create manual account | |
updateAccount(id, updates) | UpdateAccountResponse | Update account settings/balance | |
deleteAccount(id) | DeleteAccountResponse | Delete account | |
requestAccountsRefresh(ids) | boolean | Start refresh (non-blocking) | |
requestAccountsRefreshAndWait(opts?) | boolean | Refresh and poll until done | |
createTransaction(params) | CreateTransactionResponse | Create transaction | |
updateTransaction(id, updates) | UpdateTransactionResponse | Update transaction | |
deleteTransaction(id) | boolean | Delete transaction | |
updateTransactionSplits(id, splits) | UpdateTransactionSplitResponse | Manage splits | |
createTransactionCategory(params) | CreateCategoryResponse | Create category | |
deleteTransactionCategory(id, moveTo?) | boolean | Delete category | |
deleteTransactionCategories(ids) | `(boolean \ | Error)[]` | Bulk delete |
createTransactionTag(name, color) | CreateTransactionTagResponse | Create tag | |
setTransactionTags(txId, tagIds) | SetTransactionTagsResponse | Set tags on transaction | |
setBudgetAmount(params) | SetBudgetAmountResponse | Set/clear budget | |
uploadAccountBalanceHistory(id, csv) | void | Upload balance history CSV |
import {
MonarchMoneyError, // base class for all errors EmailOtpRequiredException, // email verification code needed — call submitEmailOtp() RequireMFAException, // TOTP MFA required — call multiFactorAuthenticate() LoginFailedException, // bad credentials or auth error (includes .statusCode) RequestFailedException, // API/GraphQL failure (includes .statusCode, .graphQLErrors) } from "@hakimelek/monarchmoney";
try { await mm.login(email, password); } catch (e) { if (e instanceof EmailOtpRequiredException) { // e.code === "EMAIL_OTP_REQUIRED" // Prompt user for the code sent to their email const code = await getCodeFromUser(); await mm.submitEmailOtp(email, password, code); } else if (e instanceof RequireMFAException) { // e.code === "MFA_REQUIRED" // Prompt for TOTP code or use mfaSecretKey } else if (e instanceof LoginFailedException) { // e.code === "LOGIN_FAILED", e.statusCode console.error("Login failed:", e.message); } }
try { await mm.getAccounts(); } catch (e) { if (e instanceof RequestFailedException) { console.error(e.statusCode); // HTTP status, if applicable console.error(e.graphQLErrors); // GraphQL errors array, if applicable console.error(e.code); // "HTTP_ERROR" | "REQUEST_FAILED" } }
const mm = new MonarchMoney({
sessionFile: ".mm/mm_session.json", // session file path timeout: 10, // API timeout in seconds token: "pre-existing-token", // skip login retry: { maxRetries: 3, // retry on 429/5xx (default: 3, set 0 to disable) baseDelayMs: 500, // base delay with exponential backoff + jitter }, rateLimit: { requestsPerSecond: 10, // token-bucket throttle (default: 0 = unlimited) }, });
mm.setTimeout(30); // change timeout later
Retry automatically handles transient failures (429 Too Many Requests, 500, 502, 503, 504) with exponential backoff and jitter. The Retry-After header is respected on 429 responses.
getTransactions() returns a single page. For large datasets, use the auto-pagination helpers:
// Async generator — yields one page at a time (memory-efficient)
for await (const page of mm.getTransactionPages({ startDate: "2025-01-01", endDate: "2025-12-31" })) { for (const tx of page) { console.log(tx.merchant?.name, tx.amount); } }
// Or collect everything into a flat array const all = await mm.getAllTransactions({ startDate: "2025-01-01", endDate: "2025-12-31", pageSize: 100, // transactions per page (default: 100) }); console.log(${all.length} total transactions);
Both methods accept the same filter options as getTransactions() (date range, category, account, tags, etc.).
Track account refresh progress with the onProgress callback:
await mm.requestAccountsRefreshAndWait({
timeout: 300, delay: 10, onProgress: ({ completed, total, elapsedMs }) => { console.log(${completed}/${total} accounts refreshed (${(elapsedMs / 1000).toFixed(0)}s)); }, });
This package includes a built-in Model Context Protocol server with 30 tools, making your Monarch Money data accessible to AI assistants like Claude Desktop, Cursor, and any MCP-compatible client.
mm.token.claude_desktop_config.json):{
"mcpServers": { "monarch-money": { "command": "npx", "args": ["@hakimelek/monarchmoney"], "env": { "MONARCH_TOKEN": "your-token-here" } } } }
Or run it directly:
MONARCH_TOKEN=your-token npx @hakimelek/monarchmoney
Read (18 tools): get_accounts, get_account_holdings, get_account_history, get_account_type_options, get_recent_account_balances, get_aggregate_snapshots, get_institutions, get_budgets, get_subscription_details, get_transactions, get_transactions_summary, get_transaction_details, get_transaction_categories, get_transaction_category_groups, get_transaction_tags, get_cashflow, get_cashflow_summary, get_recurring_transactions
Write (12 tools): create_transaction, update_transaction, delete_transaction, create_manual_account, update_account, delete_account, refresh_accounts, is_refresh_complete, set_budget_amount, create_transaction_tag, set_transaction_tags, create_transaction_category
Every tool has typed parameters with descriptions, so AI agents know exactly what arguments to pass.
src/
index.ts — public exports client.ts — MonarchMoney class with all API methods mcp.ts — MCP server (30 tools for AI agents) errors.ts — error classes (MonarchMoneyError hierarchy) endpoints.ts — API URL constants queries.ts — all GraphQL query/mutation strings types.ts — TypeScript interfaces for all API responses
npm test # run tests once
npm run test:watch # run tests in watch mode npm run test:coverage # run with coverage report
Tests use [Vitest](https:/
ตัดมาแค่ช่วงต้น อ่านต่อใน repo