NA

nx9161/agent-progress-bar

Developer tools
0 stars 0 forks Quality 81 Trend 20MIT

Universal open-source progress bar for AI agents: live 0-100% bar, countdown, and stage ticker via an MCP connector.

Overview

An open-source (MIT), agent-agnostic progress layer: a live demo website, a progress-reporting protocol, an MCP-server "connector", an embeddable widget, and a live layer — a local event sink plus a localhost dashboard — so (ChatGPT, DeepSeek, Kimi, Claude, Gemini) can show the same live module: a 0–100% bar, a % counter, a countdown, and a stage ticker. This project does not and cannot inject a progress bar into ChatGPT, Claude, Gemini, DeepSeek, Kimi, or any other app. "Works with all AI agents" means: an open, adoptable layer that agent builders and agent harnesses wire in voluntarily. Anyone promising "a progress bar inside ChatGPT" is selling a fantasy. - A published protocol (PROTOCOL.md + protocol/schema.json) any agent can speak. - An MCP server any MCP-compatible agent connects to and reports progress through. - A local event sink: every progress report is appended to a JSONL log on your machine — no network, no accounts (see "Live layer" and "Privacy").

README

Universal Agent Progress Bar (UAPB)

An open-source (MIT), agent-agnostic progress layer: a live demo website, a progress-reporting protocol, an MCP-server “connector”, an embeddable widget, and a live layer — a local event sink plus a localhost dashboard — so any AI agent with visible thinking (ChatGPT, DeepSeek, Kimi, Claude, Gemini) can show the same live module: a 0–100% bar, a % counter, a countdown, and a stage ticker.

Live Demo

https://nx9161.github.io/agent-progress-bar/

The hard truth — read this first

We cannot modify any third-party client’s UI. This project does not and cannot inject a progress bar into ChatGPT, Claude, Gemini, DeepSeek, Kimi, or any other app. “Works with all AI agents” means: an open, adoptable layer that agent builders and agent harnesses wire in voluntarily. Anyone promising “a progress bar inside ChatGPT” is selling a fantasy.

What it IS

  • A published protocol (PROTOCOL.md + protocol/schema.json) any agent can speak.
  • An MCP server any MCP-compatible agent connects to and reports progress through.
  • A local event sink: every progress report is appended to a JSONL log on your machine — no network, no accounts (see “Live layer” and “Privacy”).
  • A localhost dashboard (agent-progress dashboard) that renders the event stream live, gated by a per-launch token.
  • An unofficial dashboard plugin for Hermes (open-source, MIT; see “Hermes plugin”).
  • A `` web component + iframe wrapper any page can embed.
  • A concept demo showing the proposed UX (simulated run — no AI connected).

What it is NOT

  • Not a plugin, extension, or patch for any closed chat client. This project now ships an unofficial dashboard plugin for Hermes — but Hermes is open-source (MIT), and the plugin is installed by the user into their own Hermes copy; it is not injected into any closed client. The hard truth above still applies to ChatGPT, Claude, Gemini, DeepSeek, Kimi, and every other closed app: nobody can inject a progress bar into those.
  • Not affiliated with or endorsed by OpenAI, Anthropic, Google, DeepSeek, Moonshot AI, or Nous Research.
  • Not a backend service (the live layer is local-only; see non-goals).

Experimental. Progress percentages and time estimates are heuristics, not guarantees. Not warranted for production agent orchestration or any time-critical use. Use at your own risk.

No telemetry, no accounts, no data leaves your machine. The MCP server keeps reports in memory with a 30-minute TTL and appends them to a local JSONL event log (~/.agent-progress/events-YYYY-MM-DD.jsonl, files 0600, 7-day retention) — it never phones home.

Quickstarts

1. Try the concept demo (everyone)

Open the self-contained demo page — no build step, no server:

node scripts/build-demo.js   # writes dist/index.html (zero dependencies)
open dist/index.html         # or serve it with any static server

Mock chat window, three-dot “Thinking…” indicator alongside (never replacing) the progress module, 15s/30s/60s presets (default 45s), compact toggle, Restart. Honesty labels on the page mark it as a simulated run.

2. Connect an agent via the MCP connector (agent builders)

cd packages/mcp-server
npm ci            # exact-pinned deps; regenerate the lockfile first: npm install
npm run build
npm start         # stdio MCP server

Or install globally: npm install -g agent-progress-mcp, then add to your MCP client’s config (Claude Desktop example):

{
  "mcpServers": {
    "agent-progress": {
      "command": "npx",
      "args": ["-y", "agent-progress-mcp"],
      "env": { "PROGRESS_TTL_MS": "1800000", "LOG_LEVEL": "info" }
    }
  }
}

Then from the agent: report_progress({task_id: "claude:my-task", percent: 42, eta_seconds: 30, stage: "Reasoning"}) → get_status({task_id: "claude:my-task"}). Full worked example in packages/mcp-server/README.md.

3. Embed the widget (web developers)

Canonical — the custom element (timer-free; you push state):


Secondary — iframe (sandboxed, origin allowlist, default deny):


See examples/embed-snippet.html for the full postMessage pattern (explicit targetOrigin — never '*').

4. Install it as an agent skill (AI agents)

skills/agent-progress/ is a ready-to-install skill in the open Agent Skills format (SKILL.md + YAML frontmatter), for Claude Code, OpenAI Codex, Cursor, VS Code + GitHub Copilot, Gemini CLI, OpenCode, and any standard-compliant harness. The skill teaches the agent when and how to report progress through the MCP server (start / step boundaries / done, honest ETAs only — null over a guess).

skills/agent-progress/install.sh          # skill -> every detected harness
skills/agent-progress/install.sh --mcp     # ...plus npm install the MCP server
skills/agent-progress/install.sh --project # repo-local install instead of global

Then register the MCP server in your client (the installer prints the config) and restart it. Manual steps and per-client config snippets: skills/agent-progress/references/install.md. Publish-ready for the skills.sh marketplace as nx9161/agent-progress (owner-gated).

5. Watch the live layer (dashboard + event log)

Once an agent reports through the MCP server, its thinking trace lands in the local event log — watch it live:

agent-progress dashboard   # binds 127.0.0.1, prints a one-launch token

The dashboard streams new events over SSE and renders them by duration tier: sub-second tasks get a mascot pulse, 1–5s runs a compact bar, longer runs the full bar + ETA + stage ticker. Every /api/* call needs the token printed in your terminal; the token dies when the dashboard process exits.

Inspect the raw log any time — it is just JSONL:

agent-progress events    # read-only inspector for the event log

Full detail in the “Live layer” section below and in packages/dashboard/README.md.

Live layer

The MCP server’s in-memory store answers get_status, but the live layer keeps the history — so any agent’s progress survives on your machine and renders live.

Event sink. Every report_progress call is appended to a local JSONL file, ~/.agent-progress/events-YYYY-MM-DD.jsonl. The directory is mode 0700, files are mode 0600, files older than 7 days are deleted automatically, and AGENT_PROGRESS_EVENTS_DIR overrides the directory. The sink stamps each record with agent (from the record, UAPB_AGENT, or the agent: prefix of task_id as fallback) and session_id (defaults to task_id) — additive labels for the dashboard, not wire fields (wire contract frozen at proto: 1; consumers ignore unknown fields — see PROTOCOL.md).

Dashboard. agent-progress dashboard serves a small web UI plus an SSE stream of new events. It binds 127.0.0.1 only (first free port 17421–17430) and gates every /api/* endpoint behind a 128-bit bearer token minted fresh on each launch — the token is printed to your terminal for you to paste into the page, is never written to disk, and dies with the process. CORS is restricted to literal loopback hosts. Single-user localhost by design: do not expose it beyond loopback. See packages/dashboard/README.md and the binding Privacy section below.

Hermes plugin (unofficial)

packages/hermes-plugin/ is an unofficial dashboard plugin for Hermes Agent (Nous Research, MIT, open-source). It consumes the same localhost SSE stream as the dashboard and renders Hermes’s self-reported progress graphically — bar, stage ticker, ETA that moves. Install it yourself into your own Hermes copy (~/.hermes/plugins/uapb-hermes-plugin/, via install.sh); Hermes self-reports through the MCP server using the skill in examples/hermes/. Nothing is injected into any closed client — the plugin exists because Hermes is open-source and the user opts in. Full instructions: packages/hermes-plugin/README.md.

Privacy

Binding. Your data lives in exactly one place and goes nowhere.

  • What is logged: progress events only — task_id, percent, stage, eta_seconds, timestamps, and the agent label (agent/session_id). Stage labels and messages are whatever your agent chose to report; keep sensitive text out of them.
  • Where: ~/.agent-progress/events-YYYY-MM-DD.jsonl on your machine.
  • Modes: directory 0700, files 0600 (owner read/write only).
  • Retention: 7 days, automatic.
  • Purge everything: rm -rf ~/.agent-progress.
  • Threat model: single-user localhost. The dashboard binds 127.0.0.1 only, gates /api/* behind a per-launch 128-bit bearer token, and restricts CORS to literal loopback hosts. There is no authentication system, no accounts, and no network — nothing is designed to be exposed beyond your machine.

Repo layout

protocol/            schema.json (machine truth) + types.ts
packages/mcp-server/ stdio MCP server: report_progress / get_status (+ local JSONL event sink)
packages/dashboard/  localhost dashboard + SSE stream (127.0.0.1, token-gated /api/*)
packages/hermes-plugin/ unofficial Hermes dashboard plugin (install via install.sh)
packages/widget/      custom element + iframe wrapper
packages/cli/        internal dev CLI: agent-progress dashboard / agent-progress events
skills/agent-progress/ installable Agent Skills package (SKILL.md, install.sh, references, tests)
packages/web/        concept demo source (demo.js is disposable in v1)
examples/            iframe embed snippet, examples/hermes/ (config + skill for Hermes self-reporting)
scripts/             zero-dep demo bundler -> dist/index.html; build-dashboard.js -> dashboard bundle
dist/                built demo page (CI-built from packages/web + packages/widget; never edit by hand)

Read PROTOCOL.md for the event shape, honesty rule (eta_seconds: null, never fabricated), and compatibility rule.

Theming

Every --uapb-* token the widget and demo page read. Set them on a wrapper (or :root) to restyle — tokens inherit into the widget’s shadow DOM. Flat solid fills are the design language: --uapb-fill is a solid color, not a gradient.

Token Default What it styles
--uapb-bg #0B0E14 Page background (demo)
--uapb-surface #141A23 Cards, buttons, panels
--uapb-border #26303D Borders
--uapb-text #E9EEF5 Primary text; widget :host color
--uapb-muted #93A0B4 Secondary text (stage, captions)
--uapb-track #232C3A Progress track
--uapb-fill #E9EEF5 Progress fill (solid)
--uapb-warn #F5A524 Reserved warning accent
--uapb-done #34D399 100% fill
--uapb-error #F87171 Error state (stage text)
--uapb-radius 10px Corner radius
--uapb-sans system sans stack Body font
--uapb-mono ui-monospace, SFMono-Regular, Menlo, monospace Numerals (% counter, countdown, eta caption)
--uapb-font var(--uapb-sans) Widget :host font

Widget states

setProgress() pushes one state update; the widget is timer-free and renders only:

bar.setProgress({
  percent: 42,        // 0–100, clamped
  etaSeconds: 30,     // null = unknown ("estimating…", never invented)
  stage: "Reasoning", // ≤120 chars; stage element title mirrors full text
  status: "running",  // started | running | paused | error | done (default "running")
  message: "...",     // ≤280 chars; shown as stage in error state
  durationMs: 41203,  // finite number -> carried on uapb-complete detail
});

Invalid status values fall back to "running" silently. All text is set via textContent — no HTML is ever injected.

Status Rendered behavior
started Normal bar. Null ETA shows “estimating…” with a subtle track sheen.
running Normal bar. Null ETA shows “estimating…” with a subtle track sheen.
paused Bar goes grayscale; stage becomes “Paused — {stage}” (or “Paused”); ETA caption reads “paused”.
error Stage shows message (or “Something went wrong”) in the error color; stage element gets role="alert" (removed in non-error states).
done 100% snap with the done-green fill.

The label attribute sets the progressbar’s aria-label (default "Agent progress"). When percent reaches 100, the widget fires a bubbling, composed uapb-complete event with detail: {durationMs} when durationMs is a finite number, else detail: {}.

Iframe path: iframe.html also accepts one-shot ?status= (one of the five enum values, others ignored) and ?label= (≤120 chars) seed params, alongside ?percent=, ?eta=, ?stage=.

Non-goals

Live backend relay, hosted multi-tenant service, auth/rate-limiting, analytics/telemetry, hosted history. (The local JSONL event sink and the unofficial Hermes dashboard plugin are the deliberate exceptions — both local-only, no network, no accounts.)

Contributing / security

  • CONTRIBUTING.md — conventional commits, PR norms, DCO-lite.
  • SECURITY.md — private vulnerability reporting via GitHub Security Advisories.

Trademark notice

ChatGPT, Claude, Gemini, DeepSeek, and Kimi are trademarks of their respective owners (OpenAI, Anthropic, Google, DeepSeek, Moonshot AI). Hermes is a trademark of Nous Research. This project is not affiliated with or endorsed by any of them.

License

MIT — see LICENSE. Copyright © 2026 Naman Parmar.

View this README on GitHub

Install

npx -y agent-progress-mcp

Configuration

{ "mcpServers": { "agent-progress": { "command": "npx", "args": ["-y", "agent-progress-mcp"], "env": { "PROGRESS_TTL_MS": "1800000", "LOG_LEVEL": "info" } } } }