A real-time GitHub task board where humans set the work and agents with WebMCP support claim, plan, execute, and follow it safely through pull requests.

Problem

Coding agents can work quickly, but teams of people still need a reliable way to decide what someone's agent may do, prevent two agents from taking the same task, review a plan before implementation, and see what happened after the agent stops.

Issue trackers record work for people. Agent transcripts record work inside one conversation. Neither gives people and browser agents a shared, live workflow with explicit ownership and bounded actions.

Solution

Repo Board is a real-time task board for one GitHub repository. Humans create and groom tasks in a five-column workflow:

Todo -> Ready -> In Progress -> In PR -> Done

The page exposes WebMCP tools for the actions that are allowed in the current context. A Codex agent can inspect tasks, claim one, attach or revise a plan, start work, report progress, link a pull request, read review state, and check CI. Humans retain authority over sensitive actions such as replacing an active owner, canceling work, and archiving a completed task.

The first valid claim wins. Ownership is bound to the signed-in GitHub user and the browser tab, backed by an unguessable per-tab capability. It does not expire because a timer ran out or a WebSocket disconnected. Another agent can take over only after the person using the page confirms it.

Why This Matters

Agent coordination fails in ordinary, expensive ways: two agents edit the same work, a plan gets separated from its implementation, a stale browser tab continues mutating state, or a human cannot tell whether a status report came from the repository or from the agent itself.

Repo Board makes those boundaries visible and enforceable. The person and the agent work against the same task, plan revision, board revision, pull request snapshot, and activity history. The app treats task text, plans, progress reports, and GitHub content as untrusted data. That content cannot select tools, authorize a mutation, choose a repository, or supply secrets.

How We Used AI

Repo Board does not embed a model or require an OpenAI API key. It gives an AI agent a precise interface to a live product through browser-native WebMCP.

The agent discovers only the tools that are valid for the current user, selected task, assignment, and workflow state. For example, an unassigned Ready task exposes claim_task. After the current tab claims it, the registry replaces that tool with read_plan, update_plan, report_progress, start_work, and release_task. After the task reaches In PR, the agent can read review and check state. Aborting the active registration removes stale tools when context changes.

This makes the agent useful without giving it hidden authority. Read operations are bounded. Mutations carry an idempotency key and expected board revision. The Durable Object independently checks authorization and state transitions instead of trusting the browser tool layer.

How We Used Codex

Codex helped turn the product plan into a working system. It traced and implemented the React client, Cloudflare Worker, SQLite-backed Durable Object, D1 directory, GitHub App integration, WebSocket updates, and dynamic WebMCP profiles. It also wrote and ran focused tests for task transitions, validation, authorization, session isolation, concurrent claims, reconnect behavior, pull request state, and tool registration.

The build process used Codex to pressure-test product decisions instead of only generating code. One important revision replaced timer-based leases with durable per-tab ownership after the failure modes of expiring work were examined. Codex then added explicit, human-confirmed takeover and server-side fencing for the former owner. A later pass added archive_task with the same rule in both the WebMCP layer and the Durable Object: only completed, unarchived Done work can be archived, and the page must ask the human first.

Repo Board was also used for real work. In Codex's in-app browser, the airy-pond ticket for a private GitHub repository was inspected, claimed for planning, and given an approved plan. Repo Board moved it from Todo to Ready and closed the planning assignment. That exercise also caught a stale tool handle; fetching the current WebMCP registry resolved it, which validated the context-replacement design.

Key Features

  • Dynamic WebMCP tool profiles based on authentication, permissions, route, selection, assignment, and task state
  • Atomic task claims with structured conflict results when another agent wins
  • Durable ownership bound to a GitHub user and browser tab, with explicit human-confirmed takeover
  • Immutable ticket and plan revisions plus an append-only activity log
  • Typed workflow transitions instead of arbitrary drag-and-drop state changes
  • Real-time board updates through hibernating WebSockets, missed-event replay, and reconnect snapshots
  • Pull request linking, review normalization, check status, merge completion, and closed-without-merge rollback
  • Human-confirmed cancellation and archival, with matching server-side guards
  • Anonymous read-only previews for public repositories and fail-closed access for private repositories
  • Two-word task references such as amber-fox, so people and agents do not have to pass internal UUIDs
  • Bounded untrusted-content handling throughout ticket, plan, progress, review, and GitHub data

Architecture

The React client renders the board and registers WebMCP tools through document.modelContext. It sends HTTP commands and receives revisioned WebSocket updates from a Cloudflare Worker.

The Worker handles GitHub authentication, repository authorization, API routing, static assets, installation-token GitHub calls, webhook verification, and scheduled pull request reconciliation.

D1 stores the global directory, GitHub identities, hashed sessions, installations, and permission cache. One SQLite-backed RepositoryBoard Durable Object per owner/repo owns tasks, plan revisions, assignments, pull request snapshots, processed actions, webhook deliveries, and the board event log. It serializes mutations before broadcasting the new revision.

GitHub network calls finish in the Worker before normalized results enter the Durable Object. No serialized state path remains open across an external request.

Testing Instructions

Public judge flow

  1. Open https://webmcp-repo-board.zacwhite.workers.dev/boards/zac/test-repo-board in ChatGPT's in-app browser or Google Chrome 149+ with WebMCP enabled.
  2. Confirm that the public board has one synthetic example in each column: Todo, Ready, In progress, In PR, and Done.
  3. Ask the agent to call list_tasks, then inspect white-vine to see its approved plan and linked open pull request.
  4. Inspect teal-whale to see a completed task linked to merged pull request #4.
  5. To test mutations, sign in with GitHub and use a repository where the Repo Board GitHub App is installed and your account has triage, write, maintain, or admin permission.
  6. Create a Todo task, claim it for planning, save a plan, claim implementation, call start_work, and report progress.
  7. Link an open pull request from the same repository. Confirm that the task moves to In PR and exposes pull request, review, and check tools.
  8. After the pull request merges, confirm that the task moves to Done. Archive only if you want to hide it from the default board while retaining its history.

Mutating tests require a repository where the tester can install or access the GitHub App. Public anonymous routes remain read-only by design.

Local setup

Requirements: Node 24 and pnpm 11.

pnpm install --frozen-lockfile
pnpm d1:migrate:local
pnpm dev:worker

Open http://localhost:8787. Local development provides a labeled development session and public stand-in repositories, so the core workflow does not require production GitHub credentials.

Automated verification

Run:

pnpm check
pnpm deploy:dry

Verified again on September 3, 2026:

  • ESLint passed.
  • Both TypeScript projects passed type checking.
  • 58 client and shared tests passed.
  • 42 Worker and Durable Object tests passed.
  • The production Vite build passed.
  • The Wrangler dry deployment assembled the Worker, assets, Durable Object, and D1 bindings successfully.
  • The public homepage returned HTTP 200.
  • The public zac/webmcp-repo-board board API returned HTTP 200 and identified the repository as public and materialized.
  • The public zac/test-repo-board demo API returned HTTP 200 with one task in each workflow column.
  • ChatGPT's in-app browser completed a signed-in lifecycle across planning, implementation, progress reporting, pull request linkage, status refresh, and merge completion.
  • Pull request #3 remains open as the In PR example. GitHub's pull request webhook moved merged pull request #4 to Done.

Local Worker tests print warnings when production GitHub secrets are absent. The tests still pass because their fixtures supply the required boundaries.

Known Limitations

  • Each board represents one GitHub repository.
  • A task can link to at most one pull request.
  • Repo Board owns its tasks; it does not synchronize GitHub Issues or GitHub Projects.
  • It does not launch agents or read native Codex telemetry.
  • Anonymous visitors can read public boards but cannot mutate them.
  • Private repository access depends on the GitHub App installation belonging to the repository owner.
  • Full mutation testing requires GitHub authorization and repository permission.
  • WebMCP testing requires ChatGPT's in-app browser or a compatible Chrome build with the experimental flag enabled.

Try It

Built With

Share this project:

Updates

Submission history