Self-hostable, open-source personal finance app (AGPLv3)
Drift inferred · capture-to-capture
No drift recorded — single capability capture; advisories appear once its surface changes.
transport streamable-http · http counts 17 tools · 0 res
· 0 prompts
permission surface via code analysis
tools
-
get_account_summary
-
get_budget
-
get_dashboard_summary
-
get_holdings
-
get_income_vs_expense
-
get_net_worth_history
-
get_portfolio_summary
-
get_spending_report
-
get_transactions
-
get_upcoming_bills
-
list_accounts
-
list_categories
-
mark_transaction_transfer
-
set_budget_category
-
show_financial_dashboard
-
sync_accounts
-
update_transaction_category
prompt-surface
shipped agent-instruction files + hidden-content / dangerous-code findings —
quoted from the analyzed source
analyzed commit c38e990 · analyzer v33 · 17h ago
skills & prompt files 7
- agent-rules KenTaniguchi-R-ledgr-c38e990/AGENTS.md
- agent-rules KenTaniguchi-R-ledgr-c38e990/CLAUDE.md
- skill KenTaniguchi-R-ledgr-c38e990/ledgr-plugin/skills/budget-check/SKILL.md
- skill KenTaniguchi-R-ledgr-c38e990/ledgr-plugin/skills/monthly-review/SKILL.md
- skill KenTaniguchi-R-ledgr-c38e990/ledgr-plugin/skills/net-worth-tracking/SKILL.md
- skill KenTaniguchi-R-ledgr-c38e990/ledgr-plugin/skills/savings-analysis/SKILL.md
- skill KenTaniguchi-R-ledgr-c38e990/ledgr-plugin/skills/subscription-audit/SKILL.md
danger signals1
- dynamic code execution new Function() KenTaniguchi-R-ledgr-c38e990/src/lib/theme.test.ts :154
new Function(THEME_INIT)();
evidence-backed
findings quoted directly from the published source artifact — not inferred
code files: 566
filesystem 7
- fs (weak) KenTaniguchi-R-ledgr-c38e990/e2e/health.spec.ts :1
import { readFileSync } from "node:fs"; - fs (weak) KenTaniguchi-R-ledgr-c38e990/next.config.ts :1
import { readFileSync } from "node:fs"; - fs (weak) KenTaniguchi-R-ledgr-c38e990/scripts/install-migrate-deps.mjs :1
import { readFileSync } from "node:fs"; - fs (weak) KenTaniguchi-R-ledgr-c38e990/scripts/migrate.mjs :1
import { readFileSync } from "node:fs"; - fs KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/apps/build.ts :2
import { readFileSync, writeFileSync, mkdirSync } from "fs"; - fs KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/apps/register.ts :2
import { readFileSync } from "fs"; - fs (weak) KenTaniguchi-R-ledgr-c38e990/tests/unit/ensure-secrets.test.ts :3
import { mkdtempSync, rmSync, readFileSync, writeFileSync, existsSync } from "node:fs";
shell / exec 2
- shell (weak) KenTaniguchi-R-ledgr-c38e990/scripts/install-migrate-deps.mjs :2
import { execFileSync } from "node:child_process"; - shell (weak) KenTaniguchi-R-ledgr-c38e990/tests/unit/ensure-secrets.test.ts :2
import { spawnSync } from "node:child_process";
network 7
- net KenTaniguchi-R-ledgr-c38e990/src/app/api/mcp/route.ts :34
return mcpHandler.fetch(request, { - net KenTaniguchi-R-ledgr-c38e990/src/components/organisms/command-palette.tsx :73
const res = await fetch(`/api/search?q=${encodeURIComponent(trimmed)}`); - net KenTaniguchi-R-ledgr-c38e990/src/components/organisms/dashboard-grid.tsx :89
const res = await fetch(`/api/dashboard/spending?month=${month}`); - net KenTaniguchi-R-ledgr-c38e990/src/components/organisms/import-wizard.tsx :50
const res = await fetch("/api/import", { method: "POST", body: formData }); - net KenTaniguchi-R-ledgr-c38e990/src/components/organisms/net-worth-hero.tsx :85
const res = await fetch(`/api/dashboard/net-worth?range=${next}`); - net KenTaniguchi-R-ledgr-c38e990/src/lib/favicon.ts :19
const res = await fetch(`https://www.google.com/s2/favicons?domain=${domain}&sz=128`, { - net KenTaniguchi-R-ledgr-c38e990/src/lib/simplefin/client.ts :28
// attack, since `fetch()` re-resolves DNS independently when it
secrets 10
- secrets KenTaniguchi-R-ledgr-c38e990/src/lib/ai/config.ts :9
const apiKey = process.env.AI_API_KEY; - secrets (weak) KenTaniguchi-R-ledgr-c38e990/src/lib/encryption.test.ts :7
process.env.ENCRYPTION_KEY = randomBytes(32).toString("hex"); - secrets KenTaniguchi-R-ledgr-c38e990/src/lib/encryption.ts :30
if (!process.env.ENCRYPTION_KEY) { - secrets (weak) KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/auth/token.test.ts :5
process.env.ENCRYPTION_KEY ??= "test-key-for-jwt-signing-32chars!!"; - secrets KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/auth/token.ts :6
const key = process.env.ENCRYPTION_KEY; - secrets KenTaniguchi-R-ledgr-c38e990/src/lib/plaid/client.ts :13
const secret = process.env.PLAID_SECRET; - secrets (weak) KenTaniguchi-R-ledgr-c38e990/tests/integration/demo-mode.test.ts :10
process.env.ENCRYPTION_KEY = - secrets (weak) KenTaniguchi-R-ledgr-c38e990/tests/integration/mcp-spec-compliance.test.ts :88
process.env.ENCRYPTION_KEY ??= "test-key-for-jwt-signing-32chars!!"; - secrets (weak) KenTaniguchi-R-ledgr-c38e990/tests/integration/oauth.test.ts :21
process.env.ENCRYPTION_KEY ??= "test-key-for-jwt-signing-32chars!!"; - secrets (weak) KenTaniguchi-R-ledgr-c38e990/tests/integration/rotate-encryption-keys.test.ts :17
process.env.ENCRYPTION_KEY = randomBytes(32).toString("hex");
database 4
- db (weak) KenTaniguchi-R-ledgr-c38e990/scripts/ensure-app-role.mjs :1
import pg from "pg"; - db (weak) KenTaniguchi-R-ledgr-c38e990/scripts/migrate.mjs :7
import pg from "pg"; - db KenTaniguchi-R-ledgr-c38e990/src/db/index.ts :4
import { Pool } from "pg"; - db (weak) KenTaniguchi-R-ledgr-c38e990/tests/integration/setup.ts :3
import { Pool } from "pg";
tool registrations 17
- show_financial_dashboard KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/apps/register.ts :45
- list_accounts KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/accounts.ts :9
- get_account_summary KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/accounts.ts :42
- get_budget KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/budgets.ts :12
- set_budget_category KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/budgets.ts :66
- list_categories KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/categories.ts :9
- update_transaction_category KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/categories.ts :26
- get_dashboard_summary KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/dashboard.ts :40
- get_net_worth_history KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/dashboard.ts :65
- get_portfolio_summary KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/investments.ts :9
- get_holdings KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/investments.ts :34
- get_upcoming_bills KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/recurring.ts :9
show 5 more
- get_spending_report KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/reports.ts :10
- get_income_vs_expense KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/reports.ts :52
- sync_accounts KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/sync.ts :13
- get_transactions KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/transactions.ts :11
- mark_transaction_transfer KenTaniguchi-R-ledgr-c38e990/src/lib/mcp/tools/transactions.ts :60
install hooks 1
- prepare KenTaniguchi-R-ledgr-c38e990/package.json :30
simple-git-hooks
declared dependencies 62
- @modelcontextprotocol/server@2.0.0
- @ai-sdk/anthropic@^4.0.42
- @ai-sdk/google@^4.0.51
- @ai-sdk/openai@^4.0.47
- @ai-sdk/openai-compatible@^3.0.37
- @ai-sdk/react@^4.0.82
- @base-ui/react@^1.7.0
- @better-auth/passkey@^1.7.1
- ai@^7.0.79
- better-auth@^1.7.1
- class-variance-authority@^0.7.1
- clsx@^2.1.1
show 28 more
- cmdk@^1.1.1
- d3-sankey@^0.12.3
- drizzle-orm@^0.45.2
- jose@^6.2.10
- lucide-react@^1.34.0
- next@16.3.3
- node-cron@^4.6.0
- papaparse@^5.7.0
- pg@^8.23.0
- plaid@^43.0.0
- react@19.2.8
- react-dom@19.2.8
- react-grid-layout@^2.2.4
- react-plaid-link@^4.1.1
- recharts@^3.10.1
- shadcn@^4.19.0
- tailwind-merge@^3.6.0
- tw-animate-css@^1.4.0
- uuid@^14.0.2
- zod@^4.4.3
- @fast-check/vitest@^0.4.1
- @playwright/test@^1.62.1
- @stryker-mutator/core@^9.6.1
- @stryker-mutator/typescript-checker@^9.6.1
- @stryker-mutator/vitest-runner@^9.6.1
- @tailwindcss/postcss@^4.3.3
- @testcontainers/postgresql@^12.1.0
- @testing-library/react@^16.3.2
22 more not shown — this panel samples each group; the count above is the real total.