Live site: incomegraph.net
Income Graph turns a pile of income streams into a picture of where the money goes. Add each source (a retainer, a SaaS subscription, a one-time project), set its price, customers and billing period (recurring, metered or one-time), then attach the fees and costs that apply to it. The page draws revenue flowing through fees and costs into profit, with the margin and yearly totals updating as you type.
It also takes goals. Set a target revenue or target profit and the graph shows how far the current mix is from it. Each graph can be shared by link, and the same data is available to AI agents.
Two ways to look at the money
The flow diagram has two views. Sankey shows proportional bands from sources to revenue to costs and profit. Network is a force-style node graph with animated particles along each edge. An income lens and a costs lens switch which side is emphasized, and overhead costs that are not tied to a stream are tracked separately from allocated ones.
Agent-native
The same graphs are reachable three ways: the browser editor, a versioned REST API documented by an OpenAPI spec, and a hosted Model Context Protocol (MCP) server. An agent can create a graph, add streams and costs, and read the computed profit without touching the UI. The page in the screenshot is a “Freelance studio” graph built entirely through MCP calls, and the neighboring tabs are built through REST.
Tech stack
- Languages: JavaScript (about 48% of the repo), Go (about 36%), HTML, Shell, CSS and a Makefile
- Frontend: Hugo static site with vanilla JavaScript modules (no framework) and D3 with
d3-sankeyfor the charts; dark mode, local-first storage with versioned schemas, and optional cloud sync - Backend: twelve Go Lambda functions on
provided.al2023behind an API Gateway HTTP API, each its own Go module (graphs, nodes, edges, sharing, collaboration, API keys, billing, a Stripe webhook, a custom authorizer, an inbound mail forwarder, a REST handler and the MCP server) - Data and auth: DynamoDB tables, Amazon Cognito user pool, SES for email
- Billing: Stripe subscriptions with plan gating checked server-side
- Infrastructure as code: AWS SAM / CloudFormation, with the site served from S3 behind CloudFront and ACM certificates
- API contract: OpenAPI 3 spec and a JSON Schema for the graph format, validated in both the Go services and the browser, and rendered as the public developer docs
- Observability: OpenTelemetry tracing in every Go service
- Testing: Go tests, Jest with jsdom, and Playwright end-to-end specs; LocalStack for running Cognito and DynamoDB locally
- Delivery: GitHub Actions with OIDC into AWS, a gate that requires green CI on the released commit, a production smoke test after each deploy, and rollback to the previous release on failure
- Tooling: Taskfile, tmuxinator dev session, pre-commit hooks (gitleaks, linting, vulnerability scan), ADRs for design decisions, and CLAUDE.md for agent-driven development