Local AI Workflow Debugger & Cost Optimizer.
A lightweight, zero-code-change proxy that sits between your AI workflow tools (n8n, LangChain, custom agents) and your LLM providers (OpenAI, Anthropic, Ollama) — capturing every request's latency, tokens, and cost in real time, with a live dashboard and built-in spend guardrails.
Point baseURL at FlowPulse. That's it. No SDK, no wrapper, no vendor lock-in.
Debugging and cost-tracking AI workflows usually means digging through provider dashboards after the fact, or instrumenting every agent by hand. FlowPulse takes a different approach:
- Zero code changes — swap one URL (
baseURL), keep your existing OpenAI/Anthropic SDK calls exactly as they are. - Runs entirely on your machine — traffic passes through your own proxy; nothing is sent anywhere except the LLM provider you already use.
- See cost before it happens — Cost Guard blocks a request before it reaches the provider if it would blow your daily budget or a per-request token ceiling.
- One dashboard, every request — live KPIs, a filterable request stream, and a full request/response inspector, updated over WebSocket as requests happen.
| 🔌 Zero-code proxy | OpenAI-compatible (/v1/chat/completions) and Anthropic-native (/v1/messages) endpoints, streaming and non-streaming |
| 💰 Real-time cost tracking | Per-request input/output cost breakdown, computed from a configurable pricing table |
| ⏱️ Latency & TTFT | Measures total duration and time-to-first-token, even for streamed responses |
| 🛡️ Cost Guard | Optional daily spend cap (MAX_DAILY_COST_USD) and per-request token ceiling (MAX_TOKENS_PER_REQUEST) — both enforced before the upstream call |
| 📊 Live dashboard | Next.js + Tailwind app with KPI cards, a live request table, and status/model filters |
| 🔍 Request detail drawer | Click any request to inspect the full prompt, raw response/error JSON, sanitized headers, and cost breakdown |
| 🧩 Provider-agnostic | Works with OpenAI, Anthropic, and any OpenAI-compatible endpoint (Ollama, local model servers, etc.) |
flowchart LR
subgraph client["Your AI Workflow"]
A["n8n / LangChain / Custom Agent"]
end
subgraph flowpulse["FlowPulse (local)"]
B["Proxy — Fastify\nlocalhost:4000"]
G{{"Cost Guard"}}
D["/ws/metrics\nWebSocket"]
E["Dashboard — Next.js\nlocalhost:3000"]
end
subgraph upstream["LLM Provider"]
C[("OpenAI / Anthropic / Ollama")]
end
A -- "baseURL: localhost:4000/v1" --> B
B --> G
G -- "within budget" --> C
G -. "over budget → HTTP 429" .-> A
C -- "response" --> B
B -- "response, unchanged" --> A
B -- "metrics + cost + request/response detail" --> D
D --> E
Only two things run: the proxy (Node/Fastify) and the dashboard (Next.js). No database, no external services — metrics live in memory and stream over WebSocket as they happen.
Live dashboard — KPI cards plus a request stream mixing successful calls, a 401 from a bad key, and 429s from the Cost Guard:
Request Detail Drawer — click any row to see the exact prompt, sanitized headers, and full cost breakdown:
Cost Guard in action — a request blocked before it ever reached the provider, visible live in the stream:
Filtering — narrow the live stream to just the errors (or a specific model):
cp .env.example .env
# set UPSTREAM_BASE_URL in .env to your real provider (OpenAI, Anthropic, or a local Ollama instance)
docker compose up --buildThat's it — the proxy comes up on http://localhost:4000 and the dashboard on http://localhost:3000, wired together automatically. Stop everything with docker compose down.
1. Run the proxy
npm install
cp .env.example .env
# set UPSTREAM_BASE_URL in .env to your real provider (OpenAI, Anthropic, or a local Ollama instance)
npm startThe proxy listens on http://localhost:4000 and opens a metrics channel at ws://localhost:4000/ws/metrics.
2. Run the dashboard
cd dashboard
npm install
cp .env.local.example .env.local
npm run devOpen http://localhost:3000 (or 3001 if 3000 is taken) to watch requests, costs, and latency come in live.
In n8n, LangChain, or your own agent code, change the LLM client's baseURL — nothing else:
baseURL: http://localhost:4000/v1
For a step-by-step n8n walkthrough (HTTP Request node setup, a caveat about the native OpenAI node's custom Base URL support, a ready-to-import example workflow, and troubleshooting), see the n8n Integration Guide.
Both limits are opt-in — set them in .env to enable, leave unset to disable:
MAX_DAILY_COST_USD— total spend allowed per UTC day across all requests. Once reached, new requests are rejected withHTTP 429 — FlowPulse: Daily Cost Limit Exceededbefore they reach the provider. Resets automatically at midnight UTC.MAX_TOKENS_PER_REQUEST— maximum tokens (estimated from prompt size + requestedmax_tokens) a single request may use. Requests over the limit are rejected upfront withHTTP 429 — FlowPulse: Request Token Limit Exceeded.
Blocked requests still appear in the console log and the live dashboard, so you can see the guard working in real time.
Every request is appended as a JSON line to data/metrics.jsonl (path configurable via METRICS_LOG_PATH), so history survives a proxy restart — restart the proxy and the dashboard still shows everything from before. This also means MAX_DAILY_COST_USD can't be reset by restarting the proxy: on startup, FlowPulse re-sums today's spend from this file before serving any requests.
The dashboard loads this history on page load via GET /metrics/history (newest first, capped at 200 entries by default — pass ?limit=), then switches to the live WebSocket stream for anything after that. Note that only the summary metrics are persisted, not the full prompt/response bodies — those stay in-memory and are only available for requests captured during the current WebSocket session, via the Request Detail Drawer.
data/ is gitignored and grows unbounded (no rotation) — it's meant for local debugging, not as a production audit log. Delete the file any time to reset history.
POST /v1/chat/completions— OpenAI-compatible (OpenAI, Ollama's OpenAI-compatible mode)POST /v1/messages— Anthropic native Messages API formatGET /metrics/history— persisted request history (JSON, newest first)GET /health— health check
| Model | Input ($/1M tokens) | Output ($/1M tokens) |
|---|---|---|
| gpt-4o | $2.50 | $10.00 |
| gpt-4o-mini | $0.15 | $0.60 |
| claude-3-5-sonnet | $3.00 | $15.00 |
| llama3 (Ollama) | $0 | $0 |
Prices can be updated in src/config/pricing.js. Unrecognized models are still proxied and measured — cost is just reported as $0 with an unknown model flag until you add pricing for them.
FlowPulse/
├── src/
│ ├── index.js # Entry point (loads dotenv + starts the server)
│ ├── server.js # Fastify instance and route registration
│ ├── config/
│ │ └── pricing.js # Per-model pricing table
│ ├── services/
│ │ ├── costCalculator.js # Cost calculation engine
│ │ ├── costGuard.js # Daily budget & per-request token guardrails
│ │ ├── logger.js # Console metric logging
│ │ ├── metricsStore.js # Persists metrics to data/metrics.jsonl (survives restarts)
│ │ └── wsBroadcaster.js # /ws/metrics channel - broadcasts metrics to the dashboard
│ ├── proxy/
│ │ └── chatProxy.js # Streaming/non-streaming proxy middleware
│ └── routes/
│ └── chatCompletions.js
├── dashboard/ # Next.js + Tailwind live metrics dashboard
│ └── Dockerfile # Multi-stage build (Next.js standalone output)
├── docs/
│ ├── n8n-integration.md # n8n integration guide
│ └── screenshots/ # README images
├── examples/
│ └── n8n/
│ └── flowpulse-demo.workflow.json # Importable example n8n workflow
├── test/ # node:test suite for the proxy (see Testing below)
├── .github/workflows/ci.yml # Runs the test suite + dashboard build on every push/PR
├── Dockerfile # Proxy image
├── docker-compose.yml # Runs proxy + dashboard together
├── .env.example
└── package.json
The proxy has a node:test suite (zero extra dependencies) covering pricing/cost math, Cost Guard, persisted history, and full request/response proxying (success, upstream errors, streaming, and Cost Guard blocks) against a real mock upstream server:
npm test.github/workflows/ci.yml runs this suite plus a dashboard production build (next build, which includes type-checking and linting) on every push and pull request to main.
-
docker-compose.yml— run the proxy and dashboard with a singledocker compose up, no local Node.js install required - n8n integration guide — a walkthrough for pointing n8n's OpenAI/HTTP nodes at FlowPulse and monitoring live workflow runs
- Persisted metrics history — survives a proxy restart, see Metrics History below
- Automated tests + CI —
node:testsuite for the proxy, dashboard build check, both run in GitHub Actions
Issues and pull requests are welcome. This is an early-stage project — if you hit a rough edge or have an idea, open an issue.
MIT




