https://github.com/me-shaon/pulsedeck
PulseDeck — the reporting inbox for your AI agents.
https://github.com/me-shaon/pulsedeck
ai-agents automation dashboard
Last synced: 5 days ago
JSON representation
PulseDeck — the reporting inbox for your AI agents.
- Host: GitHub
- URL: https://github.com/me-shaon/pulsedeck
- Owner: me-shaon
- License: agpl-3.0
- Created: 2026-06-20T16:31:33.000Z (18 days ago)
- Default Branch: main
- Last Pushed: 2026-06-30T16:34:56.000Z (8 days ago)
- Last Synced: 2026-06-30T18:19:01.727Z (8 days ago)
- Topics: ai-agents, automation, dashboard
- Language: TypeScript
- Homepage: https://pulsedeck.app
- Size: 2.3 MB
- Stars: 7
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
Awesome Lists containing this project
README
**A self-hosted dashboard for your AI agents' output.**
Agents, scripts, and automations send their reports to PulseDeck. You get one clean, searchable place to read them — instead of digging through Slack, email, and terminal logs.
[](./LICENSE)



[Quick start](#quick-start) · [What you get](#what-you-get) · [Connect an agent](#connect-an-agent) · [Documentation](#documentation)
---
## Quick start
You need [Docker](https://docs.docker.com/get-docker/) and `make` (plus
`openssl`, preinstalled on macOS/Linux).
```bash
git clone https://github.com/me-shaon/pulsedeck.git pulsedeck && cd pulsedeck
make setup # creates .env and generates strong secrets (idempotent)
docker compose up # or `make up` to build + run detached
```
`make setup` is required: the stack refuses to boot without a real
`AUTH_SECRET`/`POSTGRES_PASSWORD`, so it can never run on a known value.
Open **http://localhost:3000**, create your account and workspace, and you're running.
### See it with live data
Want to watch it fill up? Run the built-in demo agent — it sends realistic reports every 30 seconds:
1. In the app, go to **Sources → Add source** and copy the registration token (`reg_…`).
2. Run the demo agent:
```bash
pnpm --filter @pulsedeck/demo dev --url http://localhost:3000 --token reg_xxxxx
```
Charts, streams, and the live feed start populating right away.
> **Heads up:** the demo agent runs with Node 22+ and pnpm on your host — it's a
> workspace package, not part of the Docker image. If you set up with Docker and
> don't have Node/pnpm, either install them or skip the demo; PulseDeck itself
> runs fine without it.
> **Port already taken?** Override it inline, e.g. `WEB_PORT=8080 docker compose up`.
> Defaults: web `3000`, api `3001`, postgres `5432`.
### Run without Docker
Manual setup for local development and production (no Docker required)
PulseDeck is a standard pnpm monorepo. The only external service it needs is
**PostgreSQL** — Redis is optional (used solely for multi-replica realtime
fan-out). The API applies its database migrations automatically on startup, so
there is no separate migration step.
#### Prerequisites
- **Node.js 22+**
- **pnpm 9.15+** — `corepack enable && corepack prepare pnpm@9.15.0 --activate`
- **PostgreSQL 16+** — running and reachable
#### 1. Install dependencies
```bash
git clone https://github.com/me-shaon/pulsedeck.git pulsedeck && cd pulsedeck
pnpm install --frozen-lockfile
```
#### 2. Create the database
```bash
psql -U postgres -c "CREATE USER pulsedeck WITH PASSWORD 'pulsedeck';"
psql -U postgres -c "CREATE DATABASE pulsedeck OWNER pulsedeck;"
# Postgres 15+ locks down the public schema — grant it explicitly:
psql -U postgres -d pulsedeck -c "GRANT ALL ON SCHEMA public TO pulsedeck;"
```
#### 3. Configure the API
The API reads its config from `apps/api/.env` (real environment variables always
win). Create it with at least the two required values:
```bash
cat > apps/api/.env <<'EOF'
DATABASE_URL=postgres://pulsedeck:pulsedeck@localhost:5432/pulsedeck
AUTH_SECRET=replace-with-32+-random-chars # e.g. `openssl rand -base64 48`
EOF
```
All other options (retention, OAuth, signup mode, …) are documented in
[`.env.example`](./.env.example). Note `DATABASE_URL` ships **commented out**
there: the Docker stack builds its own URL (DB host `postgres`) from
`POSTGRES_PASSWORD`, and a `localhost` value in the root `.env` would break it.
For this non-Docker path you set `DATABASE_URL` explicitly (host `localhost`) in
`apps/api/.env`, as above.
#### 4a. Local development (hot reload)
```bash
pnpm dev
```
This starts the API on **:3001** and the web dev server on **:3000** (Vite
proxies `/api` → the API, keeping cookies first-party). Migrations run on API
start. Open **http://localhost:3000**.
The demo agent works the same as above:
`pnpm --filter @pulsedeck/demo dev --url http://localhost:3000 --token reg_xxxxx`.
#### 4b. Production
**Build everything:**
```bash
pnpm build
```
This emits the API bundle to `apps/api/dist` and the static web bundle to
`apps/web/dist`.
**Start the API** (it applies pending migrations, then listens):
```bash
cd apps/api
NODE_ENV=production \
DATABASE_URL=postgres://pulsedeck:pulsedeck@localhost:5432/pulsedeck \
AUTH_SECRET=your-32+-char-secret \
BETTER_AUTH_URL=https://your.domain \
PORT=3001 \
node dist/index.js
```
Keep it alive with a process manager (systemd, pm2, …). `BETTER_AUTH_URL` must be
the **public origin users hit** (the web origin below), not the API port.
**Serve the web bundle.** `apps/web/dist` is static files. The SPA calls `/api`
on its own origin, so put a reverse proxy in front that serves the static files
**and** forwards `/api` to the API. Example nginx (mirrors the bundled
[`apps/web/nginx.conf`](./apps/web/nginx.conf)):
```nginx
server {
listen 80;
server_name your.domain;
root /path/to/pulsedeck/apps/web/dist;
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:3001; # keeps the /api prefix
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Server-Sent Events (live updates): flush immediately, don't time out.
proxy_set_header Connection '';
proxy_buffering off;
proxy_read_timeout 1h;
}
location / {
try_files $uri $uri/ /index.html; # SPA client-side routing
}
}
```
Caddy alternative (`Caddyfile`):
```caddyfile
your.domain {
root * /path/to/pulsedeck/apps/web/dist
handle /api/* {
reverse_proxy 127.0.0.1:3001
}
handle {
try_files {path} /index.html
file_server
}
}
```
Put TLS in front (Caddy does this automatically; for nginx use certbot) and set
`BETTER_AUTH_URL=https://your.domain` to match.
---
## What you get
- **One inbox for every agent** — reports land organized into categories and streams, newest first.
- **Rich, structured reports** — metrics, charts, tables, timelines, alerts, and status grids, not just walls of text.
- **Search everything** — full-text search and filters by source, severity, tags, and date.
- **Custom dashboards** — drag-and-drop widgets to build the view you want.
- **Teams** — multiple workspaces, roles, and invite links.
- **Live updates** — new reports appear instantly, no refresh needed.
- **Yours to host** — one command, only needs PostgreSQL. No SaaS lock-in.
---
## Connect an agent
Any agent that can make an HTTP request can send reports — no SDK or special library needed. Register once to get an API key, then `POST` your reports.
The **Add source** page in the app gives you a ready-to-paste setup prompt. For the full API, see the [documentation](#documentation).
Want a working example? [`packages/demo`](./packages/demo) is a complete reference agent you can read and copy.
---
## Email & password reset
Out of the box PulseDeck sends no email — invite links surface in the app, and the
**Forgot password?** flow shows a warning that email isn't configured. To enable
password-reset delivery (and emailed invites), point PulseDeck at an SMTP server:
```bash
EMAIL_PROVIDER=smtp
EMAIL_FROM="PulseDeck "
SMTP_HOST=smtp.yourprovider.com
SMTP_PORT=587 # 587 STARTTLS (default) or 465 with SMTP_SECURE=true
SMTP_USER=...
SMTP_PASS=...
```
Once `EMAIL_PROVIDER=smtp` and `SMTP_HOST` are set, the admin banner in **Settings**
disappears and reset links are delivered by email. Any standard SMTP provider works
(Mailgun, Postmark, SES SMTP, Resend SMTP, your own server, etc.). See
[`.env.example`](./.env.example) for all options.
---
## Documentation
Detailed guides — configuration, deployment, the full agent API, and development setup — live on the docs site:
📖 **[PulseDeck Documentation](https://pulsedeck.app/docs)**
Quick links for now:
- **Configure** — all options live in [`.env.example`](./.env.example).
- **Develop** — `make dev` runs the whole stack in Docker with hot reload. `make help` lists every command.
- **Contribute** — see [`CONTRIBUTING.md`](./CONTRIBUTING.md).
---
## License
PulseDeck is licensed under the **GNU AGPL v3** — see [`LICENSE`](./LICENSE). Contributions require agreement to the [CLA](./CONTRIBUTING.md). Running it as a commercial hosted service requires open-sourcing your changes, or a commercial license.
---

**PulseDeck** — a home for your agents' reports.
Self-hosted · Open source · AGPL v3