Local Bank CSV Statement Analyzer & Personal Ledger.
docker run -d \
--name netly-ledger \
-p 3000:3000 \
-v ./netly-data:/app/data \
--restart unless-stopped \
ghcr.io/tian-im/netly-ledger:latestThen open http://localhost:3000 in your browser.
You can pass an initial token at startup to let your AI assistants connect automatically without needing to visit the settings dashboard first:
docker run -d \
--name netly-ledger \
-p 3000:3000 \
-v ./netly-data:/app/data \
-e MCP_INITIAL_TOKEN=your-secure-token-here \
--restart unless-stopped \
ghcr.io/tian-im/netly-ledger:latestOnce running, configure your AI client (e.g. OpenCode, Claude Code, or OpenClaw) to use the SSE endpoint:
- SSE Endpoint:
http://localhost:3000/api/mcp - Authorization Header:
Bearer your-secure-token-here
Copy the entire block below and paste it into your AI coding assistant (Claude Code, OpenCode, OpenClaw, etc.) for a fully automated installation with MCP configured:
Set up Netly Ledger on this machine and connect yourself to it via MCP:
1. Generate a secure random token and start the container:
TOKEN=$(openssl rand -hex 32)
docker run -d \
--name netly-ledger \
-p 3000:3000 \
-v ./netly-data:/app/data \
-e MCP_INITIAL_TOKEN="$TOKEN" \
--restart unless-stopped \
ghcr.io/tian-im/netly-ledger:latest
2. Wait for the container to become healthy:
until curl -sf http://localhost:3000/api/health; do sleep 2; done
3. Register yourself as an MCP client connected to Netly Ledger:
- SSE URL: http://localhost:3000/api/mcp
- Auth header: Bearer <the token from step 1>
4. Verify the connection by listing the available accounts.
Important: Open http://localhost:3000 in a browser afterwards, register a
PassKey, and you're ready to start importing bank statements.
The AI will run the commands, configure its MCP connection, and confirm everything is working — no manual config file editing needed.
# Build and start
docker compose -f docker-compose.prod.yml up -d
# View logs
docker compose -f docker-compose.prod.yml logs -f| Data | Location | Persists? |
|---|---|---|
| SQLite database | ./netly-data/netly.db |
✅ survives restarts |
| Session secret | ./netly-data/.session-secret |
✅ survives restarts |
| CSV statements | Imported into database | ✅ stored in DB |
Everything lives under a single mounted volume (./netly-data). No environment variables are required — the session secret is auto-generated on first run and the database is created automatically.
The container runs as a non-root user (UID 1001, nextjs). On Linux hosts, the bind-mounted directory must be writable by that user:
# One-time setup before first run (Linux only)
mkdir -p ./netly-data && chown 1001:1001 ./netly-dataOn macOS and Docker Desktop, this is handled automatically by the OS permission layer and is not needed.
docker compose up -d
yarn dev # or: docker compose exec web yarn devThe middleware (Edge Runtime) only validates cookie signatures via HMAC — it does not check the database for session revocation. This is an intentional tradeoff: the middleware runs in Edge Runtime where PrismaClient is unavailable.
- Logged-out cookies remain cryptographically valid for their 7-day TTL
- Middleware will allow access to page routes with a recently-logged-out cookie
- API routes and server actions still perform a full DB revocation check via
verifySessionWithDb()
For a local personal finance app, this is acceptable. The most sensitive operations (data reads/writes) are protected by API-level DB checks.
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
file:/app/data/netly.db |
SQLite database path |
SESSION_SECRET |
auto-generated (file) | Override session secret |
SESSION_SECRET_FILE |
/app/data/.session-secret |
Custom path for session secret file (entrypoint and Node.js both respect this) |
NODE_ENV |
production (Docker default) |
Environment mode |
SKIP_MIGRATIONS |
(unset) | Set to 1 to skip prisma migrate deploy on startup |
SKIP_PRISMA_GENERATE |
(unset) | Set to 1 to skip prisma generate on startup |
# Tests
yarn test # unit tests
yarn test:coverage # unit tests with coverage
yarn test:all # unit + integration tests
# Database
yarn prisma migrate dev # create/apply migrations
yarn prisma studio # browse database