Finance Toolkit
500+ transparent financial methods calculated from raw statements, not third-party endpoints.
คำอธิบายจากผู้ทำ (ภาษาอังกฤษตามต้นฉบับ)
Default-deny action registry, append-only spend ledger, and human sign-off audit trail (MCP tools).
สามเรื่องนี้ไม่รวมเป็นคะแนนเดียว เพราะความเห็น การวัด และความนิยม เป็นคนละเรื่องกัน
ตัวนี้ยังไม่ได้เรียบเรียงเป็นภาษาไทย ด้านล่างคือข้อเท็จจริงที่เราอ่านจาก registry
เลือกโปรแกรม AI ที่คุณใช้ แล้วคัดลอกค่าตั้งไปวาง
ต้องเตรียมก่อน
คุณใช้แอปไหน
เลือกแอปด้านบน เราจำไว้ให้ ครั้งหน้าปุ่มจะขึ้นว่า “ติดตั้งลง …”
เปิด Claude Desktop → Settings → Developer → Edit Config แล้ววางค่านี้ในไฟล์ claude_desktop_config.json
{
"mcpServers": {
"rails": {
"command": "uvx",
"args": [
"rails-mcp"
]
}
}
}พิมพ์คำสั่งนี้ใน Terminal
claude mcp add rails -- uvx rails-mcpวางในไฟล์ .cursor/mcp.json ของโปรเจกต์ หรือ ~/.cursor/mcp.json
{
"mcpServers": {
"rails": {
"command": "uvx",
"args": [
"rails-mcp"
]
}
}
}เบราว์เซอร์จะถามก่อนเปิดแอป จากนั้นแอปแสดงค่าตั้งให้ตรวจแล้วกดยืนยัน ช่อง key เว้นว่างไว้ให้คุณใส่เอง
วางในไฟล์ .vscode/mcp.json ของโปรเจกต์
{
"servers": {
"rails": {
"type": "stdio",
"command": "uvx",
"args": [
"rails-mcp"
]
}
}
}เบราว์เซอร์จะถามก่อนเปิดแอป จากนั้นแอปแสดงค่าตั้งให้ตรวจแล้วกดยืนยัน ช่อง key เว้นว่างไว้ให้คุณใส่เอง
ตัวนี้รันในเครื่องคุณ แต่ ChatGPT ต่อได้เฉพาะ server บนอินเทอร์เน็ต ลองเลือกแอปอื่น
ตัวเลือกเก็บในคุกกี้บนเครื่องนี้ ไม่ต้องมีบัญชี
ค่าตั้งนี้สร้างจากข้อมูลใน registry ของผู้ทำ ถ้าไม่ตรงกับ README ให้เชื่อ README
รันในเครื่องคุณ รายการเครื่องมือจะขึ้นในแอป AI หลังติดตั้ง
เราตรวจจากข้อมูลที่ใครก็เปิดดูได้ ยังไม่ได้อ่านโค้ด ข้อที่ไม่เกี่ยวกับตัวนี้ไม่นับในตัวหาร · ตรวจเมื่อ 7 พ.ย. 2569
ชื่อใน registry ยืนยันด้วยบัญชี GitHub jaimenbell ซึ่งเป็นเจ้าของ repo
ยังไม่ได้อ่านข้อมูล repo จาก GitHub
ยังไม่ได้อ่านข้อมูล repo จาก GitHub
ตัวนี้รันบนเครื่องคุณ ไม่มี endpoint บนอินเทอร์เน็ต
ตัวนี้รันบนเครื่อง ใช้ค่าที่ตั้งในเครื่องแทน
รันในเครื่องคุณ เราอ่านรายการเครื่องมือได้เฉพาะตัวที่มี endpoint บนอินเทอร์เน็ต
เทียบกับทุก server ที่ยังใช้งานในหมวดนี้ทั้งทะเบียน ดาวนับเฉพาะเมื่อผู้ลงทะเบียนเป็นเจ้าของ repo
จากการตรวจเบื้องต้นของเรา ผ่าน 1 จาก 1 ข้อที่ตรวจได้ เรายังไม่ได้อ่านโค้ด ก่อนใส่กุญแจหรือ token ให้ดูว่า server ขอสิทธิ์อะไร และเลือกกุญแจที่ทำได้เท่าที่จำเป็น
registry ไม่ได้ระบุว่าต้องใช้กุญแจ แต่บางตัวจะขอให้ล็อกอินตอนใช้ครั้งแรก
รันบนเครื่องของคุณ โปรแกรม AI จะเปิด server ขึ้นมาเองเมื่อใช้ ข้อมูลไม่ต้องผ่านเซิร์ฟเวอร์ของผู้ทำ (ยกเว้นตัวที่ไปเรียกบริการออนไลน์ต่อ)
repo บน GitHub มีการแก้โค้ดล่าสุด – และส่งรุ่นล่าสุด (0.1.0) เข้า registry 4 เดือนที่ผ่านมา
โปรแกรมที่รองรับ MCP เช่น Claude Desktop, Claude Code, Cursor และ VS Code ตัวนี้ต้องมี Python (uv) ในเครื่องด้วย
ในหมวดเดียวกันมี Finance Toolkit, SolidInvoice, Korea Tax Calculator
server หมวดเดียวกันจากผู้ทำคนอื่น เรียงตามดาว
อ่านการ์ด:★ ดาว GitHubiสามเสา: รีวิว · ผลตรวจ · การใช้งานiอัปเดต = วันที่ส่งรุ่นล่าสุดเข้า registryi
500+ transparent financial methods calculated from raw statements, not third-party endpoints.
Create and send invoices and quotes, manage clients, and track payments in SolidInvoice.
Korean tax calculation and tax-audit judgment MCP: 96 tools with statutory citations.
ส่วนนี้คัดจาก repo ของผู้ทำตามต้นฉบับ PopNx MCP ไม่ได้ตรวจหรือรับรองเนื้อหา ตัด HTML รูปภาพ และสคริปต์ออกแล้ว ลิงก์จะพาออกนอกเว็บ
A self-hosted, caller-configured default-deny action registry + append-only spend ledger + CLI-only sign-off audit trail, exposed as MCP tools. Different category from this author's other six MCP servers (mcp-factory, rag-mcp, bus-mcp, desktop-mcp, github-mcp, discord-mcp) -- those are devtools ("connect an agent to X"); this one is governance and safety: "stop an agent from doing something irreversible without a human noticing."
Ported and generalized from a live internal registry (shared/rails/, 31 tests, running against a real multi-bot fleet since 2026-07-06) -- this pattern shipped internally before it shipped publicly.
Is:
action_type strings as unconditionally GATED (default-deny), registered or not.enforcement_layer, enforcement_pointer, ceremony) -- informational, never permissive.Is NOT:
classify_action returning GATED does not block anything by itself. You still wire it into your own PreToolUse hook, permission deny-list, or CI gate -- rails-mcp gives you the schema and the audit trail, not the interceptor. record_spend_intent records intent to spend; it never calls a vendor, a paid API, or a broker, and nothing here stops an over-budget spend from happening.classify_action(action_type) always returns "GATED" -- registered or not, whatever config was loaded, no argument or config field can change it. This is the whole product. A config-driven fail-open knob would defeat the entire pitch, so classify() (rails_mcp/registry.py) takes only an action_type argument: there is no parameter through which a caller could ever make it return anything permissive. is_action_registered answers a separate, purely informational question -- "do I know something about this action-type's enforcement?" -- and never feeds back into the GATED verdict.
pip install rails-mcp
Add to your Claude Desktop/Code MCP config:
{
"mcpServers": { "rails-mcp": { "command": "rails-mcp" } } }
No console script on PATH? Fall back to "command": "python", "args": ["-m", "rails_mcp"].
By default the registry loads empty (honest-empty, not fail-open -- classify_action is still unconditionally GATED for everything). Point it at your own action-type config:
{
"mcpServers": { "rails-mcp": { "command": "rails-mcp", "env": { "RAILS_MCP_CONFIG_PATH": "C:\\path\\to\\rails.config.yaml" } } } }
See examples/rails.config.example.yaml (or .example.json) for the config shape.
All six are read-mostly -- none of them can write to the sign-off ledger.
| Tool | Purpose |
|---|---|
classify_action(action_type) | Default-deny verdict: always "GATED". Implemented in rails_mcp/registry.py::classify, tested in tests/test_registry.py + tests/test_server.py. |
is_action_registered(action_type) | Whether the loaded registry has an entry, plus enforcement_layer/enforcement_pointer/ceremony when present. rails_mcp/routes.py::is_action_registered, tested in tests/test_routes.py. |
get_rails_hash() | 12-hex sha256 digest of the loaded registry + entry count -- the value a human sign-off records. rails_mcp/registry.py::rails_hash, tested in tests/test_registry.py. |
get_signoff_state() | Current active human sign-off, or null. Read-only. rails_mcp/registry.py::load_signoff_state, tested in tests/test_registry.py + tests/test_routes.py. |
record_spend_intent(amount_usd, vendor, purpose, actor) | Append one spend-intent record. Never calls a vendor or paid API. rails_mcp/spend_ledger.py::record_spend_intent, tested in tests/test_spend_ledger.py. |
evaluate_budget(limit_usd, window_days=30.0) | Rolling-window spend total vs. limit. Never raises. rails_mcp/spend_ledger.py::evaluate_budget, tested in tests/test_spend_ledger.py. |
append_signoff -- the function that records a human blessing the registry's current hash -- is deliberately not an MCP tool, and never will be. It is exposed only as a CLI command a human runs by hand:
rails-mcp sign --operator "jaime" --note "reviewed 2026-07-16 config"
Why: the boundary exists to prevent an agent holding only this server's MCP tool connection from self-approving an irreversible action. If append_signoff were reachable as an MCP tool, any agent holding this server's connection could sign its own registry -- silently defeating the one thing the boundary exists to enforce. This mirrors the internal design rule the original shared/rails/ implementation was built around: the lane that builds the auditor never signs the registry it ships. An auditor that can also sign isn't an auditor.
**What this boundary does *not* prove:** the sign-off ledger has no cryptographic tamper-evidence and no binding to a real human identity -- its integrity rests entirely on filesystem ACLs and the self-hosted deployment model, not on cryptography. An agent (or anyone) with shell or file-write access to the ledger's path can run rails-mcp sign itself, or hand-append a forged {"type": "signoff", ...} JSONL line straight into the file -- the ledger has no way to tell that apart from a real CLI invocation. The MCP-only boundary stops the narrower case of an agent that has *only* this server's MCP tool connection; it is not proof that a human reviewed anything, and shouldn't be read as one.
This boundary is enforced structurally, not just by convention:
rails_mcp/server.py and rails_mcp/routes.py never import or call append_signoff, anywhere -- proven by an AST-based check (not a naive string grep, which would false-positive on this very explanation appearing in their docstrings) in tests/test_server.py::test_append_signoff_unreachable_via_any_mcp_tool.sign/append_signoff/revoke_signoff tool exists, checked in tests/test_server.py::test_all_six_rails_tools_registered.test_no_registered_tool_can_create_a_signoff_record).run_server.py (the entrypoint ~/.claude.json invokes) imports only rails_mcp.server, never rails_mcp.cli -- so even the process that serves MCP tools has no code path to the sign subcommand.| Var | Default | Purpose |
|---|---|---|
RAILS_MCP_CONFIG_PATH | unset | Path to your rails.config.{yaml,yml,json}. Unset = honest-empty registry (nothing registered, classify_action still unconditionally GATED). |
RAILS_MCP_SIGNOFF_LEDGER_PATH | ./rails_data/signoff.jsonl | Where the append-only sign-off ledger lives. |
RAILS_MCP_SPEND_LEDGER_PATH | ./rails_data/spend.jsonl | Where the append-only spend-intent ledger lives. |
actions:
deploy_prod: enforcement_layer: "L1" enforcement_pointer: "CI gate requires a passing e2e suite + a manual approve step" ceremony: "operator hand"
Or the more compact 3-element form (matches the internal registry's native shape):
actions:
deploy_prod: ["L1", "CI gate requires a passing e2e suite + a manual approve step", "operator hand"]
JSON works identically ({"actions": {"deploy_prod": [...]}}). See examples/ for full examples of both.
enforcement_layer should be honest, not aspirational -- "prose" (no structural rail exists yet, just a doc) is a legitimate, correct value. Rounding a "prose" entry up to "L1" because it feels better defeats the entire point of an honest registry.
.venv/Scripts/python.exe -m pytest -q
CI (.github/workflows/ci.yml) runs this suite on every push/PR and fails the build if the Tests badge above drifts from what the suite actually reports -- see scripts/check_readme_counts.py.
106 tests, all hermetic (every ledger/config path goes through tmp_path + an autouse env-isolation fixture in tests/conftest.py; nothing touches a real ./rails_data/). No network, no live-smoke gate needed -- this server has no external API to fake.
tests/test_registry.py (24) -- the ported + generalized registry logic: default-deny property tests, immutability, hash determinism, sign-off ledger fold/append/load, structural no-shell-out proof.tests/test_spend_ledger.py (14) -- ported near-verbatim from the internal suite: append/load roundtrips, budget window math, naive- datetime honest-degrade, structural no-effector proof.tests/test_config.py (18) -- new: env-var resolution, YAML/JSON loading in both entry shapes, honest-empty-when-unconfigured, loud failure on an explicit missing path.tests/test_routes.py (14) -- the MCP tool surface's business logic, exercised directly.tests/test_server.py (17) -- tool registration, passthrough correctness, and the CLI-only sign-off structural + behavioral proof.tests/test_cli.py (8) -- the serve/sign subcommands, including that sign is genuinely append-only and prints a human-readable confirmation.tests/test_check_readme_counts.py (11) -- this CI gate's own TDD suite: parse-claimed, parse-actual, compare, and main() end-to-end against match/drift/missing fixtures.python -m venv .venv
.venv/Scripts/python.exe -m pip install -e ".[test]"
Registered in ~/.claude.json under mcpServers.rails-mcp as a stdio server invoking run_server.py by absolute path (no cwd needed -- the entrypoint adds its own directory to sys.path), OR via the rails-mcp console script once installed from PyPI.
.venv/Scripts/python.exe scripts/list_tools.py
Prints the six registered tool names with no transport started.
The closest prior art is not a hosted dead-man's-switch product -- that's a different problem ("is the operator still alive and watching"). The closer comparisons, once actually verified:
spend_ledger.py sตัดมาแค่ช่วงต้น อ่านต่อใน repo