A safety layer proxy for Estonian e-Financials (e-arveldaja) API that allows AI agents to freely read bookkeeping data while capturing all write operations for human approval.
Key Principle: AI agents can READ and PROPOSE changes, but cannot EXECUTE changes without human approval.
- Read-Only by Default: AI agents can freely query all data (accounts, journals, transactions, invoices)
- Write Protection: All POST/PATCH/PUT/DELETE operations are captured and queued for approval
- Beautiful UI: Web interface with specialized visualization for double-entry bookkeeping
- MCP Server: AI assistants can interact through Model Context Protocol
- Audit Trail: Complete history of all proposed and executed changes
- Secure: HMAC-SHA-384 authentication compatible with e-Financials API
Overview of company info, account balances, and all pending changes with their status.
Detailed view of journal entries awaiting approval, showing account codes, names, and debit/credit amounts.
npm installCreate a .env file:
API_KEY_ID=your_api_key_id
API_KEY_PUBLIC=your_api_key_public
API_KEY_PASSWORD=your_api_key_password
API_BASE_URL=https://demo-rmp-api.rik.ee/v1
PORT=3000npm run build
npm run devThe server will start on port 3000 (or PORT env var).
Access points:
- Web UI: http://localhost:3000/review
- Health check: http://localhost:3000/health
- USAGE.md - Complete usage guide for humans (installation, configuration, common tasks, troubleshooting)
- AGENTS.md - Instructions for AI assistants working with this project
- API Documentation - API reference below
AI Agent/Client → Proxy → [If GET] → e-Financials API
→ [If WRITE] → SQLite Queue → Web UI → User Approval
↓
[If Approved] → e-Financials API
- Read Operations (
GETrequests): Pass through directly to the e-Financials API - Write Operations (
POST/PUT/PATCH/DELETE): Captured in SQLite, queued for approval - Human Review: Use the web UI at
/reviewto approve or reject changes - Execution: Only approved changes are sent to the actual e-Financials API
Open http://localhost:3000/review to:
- See all pending changes with journal entry visualization
- Approve or reject individual changes
- Approve or reject entire changesets
- Delete individual changesets or bulk-delete filtered changesets
- View executed changes and their results
AI assistants use the MCP server to interact safely:
Reading data:
query_api with endpoint: "/accounts"
Proposing changes:
propose_change:
endpoint: "/journals"
method: "POST"
body: {
"no": "J-2024-001",
"effective_date": "2024-01-15",
"description": "Office supplies",
"transactions": [
{"debit_account": "5140", "credit_account": "1020", "amount": "125.50"}
]
}
description: "Record office supplies purchase"
Checking status:
list_pending_changes
See AGENTS.md for complete AI assistant guidelines.
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"arveldaja": {
"command": "node",
"args": ["/full/path/to/arveldaja-proxy/dist/mcp-server.js"],
"env": {
"API_KEY_ID": "your_api_key_id",
"API_KEY_PUBLIC": "your_api_key_public",
"API_KEY_PASSWORD": "your_api_key_password"
}
}
}
}Reading:
query_api- Query any e-Financials endpoint
Proposing:
propose_change- Propose changes (captured, not executed)
Checking:
list_pending_changes- See awaiting changeslist_changesets- View all changesetsget_changeset_details- Review specific changeset
GET /proxy/v1/*- Forward read requests to e-FinancialsPOST/PATCH/PUT/DELETE /proxy/v1/*- Capture write requests
Example:
# Read accounts (passes through)
curl http://localhost:3000/proxy/v1/accounts
# Create journal (captured)
curl -X POST http://localhost:3000/proxy/v1/journals \
-H "Content-Type: application/json" \
-d '{
"no": "J-001",
"effective_date": "2024-01-15",
"description": "Test entry",
"transactions": [
{"debit_account": "5140", "credit_account": "1020", "amount": "100.00"}
]
}'GET /api/changes- List all changesGET /api/changes/:id- Get specific changePOST /api/changes/:id/approve- Approve and executePOST /api/changes/:id/reject- Reject changeGET /api/changesets- List changesetsGET /api/changesets/:id- Get changeset with changesPOST /api/changesets/:id/approve- Approve all in changesetDELETE /api/changesets/:id- Delete one changeset and its captured changesDELETE /api/changesets- Delete all changesets (optional?status=pending|approved|rejected)GET /api/stats- Get statistics
- For
/journalswrites, the proxy converts simplifiedtransactionsto APIpostings. - If a journal payload contains
descriptionbut notitle, the proxy automatically setstitle = descriptionso the journal description is visible in e-Financials.
GET /review- Review interfaceGET /health- Health check
npm run build # Compile TypeScript
npm run dev # Run with hot reload
npm start # Run production build
npm run mcp # Run MCP server
npm run lint # Run ESLint
npm run typecheck # Run TypeScript checksrc/
├── index.ts # Main Express server
├── mcp-server.ts # MCP server for AI agents
├── db/
│ └── index.ts # SQLite database operations
├── middleware/
│ └── capture.ts # Request interception middleware
├── routes/
│ ├── api.ts # Change management API
│ ├── changesets.ts # Changeset management API
│ └── company.ts # Company info aggregation
└── utils/
├── auth.ts # HMAC-SHA-384 signing
└── executor.ts # Execute approved changes
- API Credentials: Stored in environment variables, never exposed
- Approval Required: All writes require explicit human approval
- Audit Trail: Complete history stored in SQLite
- No Secrets Logged: Credentials never appear in logs
MIT License - see LICENSE file for details.
- Documentation: See USAGE.md and AGENTS.md
- Issues: https://github.com/yourusername/arveldaja-proxy/issues

