[Epic] Agent-driven interaction (chat in PWA + MCP for external clients) #47

Open
opened 2026-06-14 19:50:54 +00:00 by james · 0 comments
Owner

Make Carol agent-friendly. A user can hold a text conversation with an agent inside the PWA that reads and modifies their data on confirm, and external coding assistants (Claude Code, opencode, custom MCP clients) can connect to Carol with a per-user token to do the same.

Two surfaces, one shared underlying capability:

  • In-app: text chat panel in the PWA, talking to a built-in agent that has tool access to the user's own data.
  • External: a streamable-HTTP MCP server endpoint that any external agent runtime can connect to with a Personal Access Token scoped to a specific Carol user.

Both surfaces share the same tool definitions, the same per-user auth discipline (no agent can ever see another user's data — enforced at the repository layer, not at the tool layer), the same write-confirmation policy, and the same audit trail.

Decisions baked in

  • Both built-in PWA agent and external MCP — not BYOA-only and not built-in-only.
  • Text first; voice is a linked-but-deferred ticket inside this epic.
  • All writes require confirmation. Write tools return a proposed change rather than mutating. The PWA renders a diff and applies on confirm; MCP clients see write requests via the standard MCP tool-call confirmation flow.
  • Streamable HTTP MCP only — single endpoint, no local stdio bridge.

Linked tickets

  • ADR: agent runtime architecture (provider strategy, streaming, conversation persistence schema, write-confirmation handoff)
  • Personal Access Tokens
  • ADR: tool surface granularity and naming
  • Domain tool surface (read + write tools across all domain entities, single registry shared by PWA agent and MCP server)
  • MCP server endpoint (/api/mcp, streamable HTTP, PAT-authed)
  • Built-in chat UI (streaming chat panel, per-user persisted conversations, write-tool confirmations rendered inline)
  • Audit log + undo
  • External-agent setup docs (Claude Code, opencode, generic MCP)
  • (deferred) Voice I/O — layered onto the chat panel later

Cross-epic dependencies

The domain tool surface needs the domain entities to exist. That depends on epics #4 (Career data: Profile, Skills, Education, Jobs, Contracts, Projects) and #5 (Network: Organizations, People, Notes). Tooling and infrastructure tickets (ADRs, PAT, MCP endpoint, chat UI scaffolding) can proceed in parallel with the feature epics; the tool registry fills in entity-by-entity as the repository layers land.

Exit criteria

  • A user opens the PWA, types "draft a paragraph summary of my recent contracting work and add a note about last week's call with Sam to Sam's profile" — the agent answers and, on confirm, writes the note.
  • A user pastes a Carol-issued PAT into Claude Code's MCP config and asks Claude to "look at my recent jobs and draft a one-paragraph experience summary for my resume" — Claude reads via MCP and produces the summary.
  • A second user signing in on the same instance sees none of the first user's data through either surface, and a PAT for user A cannot read user B's data.
  • Every agent-driven write is captured in the audit log with before/after state and is undoable from the UI.
Make Carol agent-friendly. A user can hold a text conversation with an agent inside the PWA that reads and modifies their data on confirm, and external coding assistants (Claude Code, opencode, custom MCP clients) can connect to Carol with a per-user token to do the same. Two surfaces, one shared underlying capability: - **In-app**: text chat panel in the PWA, talking to a built-in agent that has tool access to the user's own data. - **External**: a streamable-HTTP MCP server endpoint that any external agent runtime can connect to with a Personal Access Token scoped to a specific Carol user. Both surfaces share the same tool definitions, the same per-user auth discipline (no agent can ever see another user's data — enforced at the repository layer, not at the tool layer), the same write-confirmation policy, and the same audit trail. ## Decisions baked in - **Both** built-in PWA agent and external MCP — not BYOA-only and not built-in-only. - **Text first**; voice is a linked-but-deferred ticket inside this epic. - **All writes require confirmation.** Write tools return a *proposed* change rather than mutating. The PWA renders a diff and applies on confirm; MCP clients see write requests via the standard MCP tool-call confirmation flow. - **Streamable HTTP MCP only** — single endpoint, no local stdio bridge. ## Linked tickets - ADR: agent runtime architecture (provider strategy, streaming, conversation persistence schema, write-confirmation handoff) - Personal Access Tokens - ADR: tool surface granularity and naming - Domain tool surface (read + write tools across all domain entities, single registry shared by PWA agent and MCP server) - MCP server endpoint (`/api/mcp`, streamable HTTP, PAT-authed) - Built-in chat UI (streaming chat panel, per-user persisted conversations, write-tool confirmations rendered inline) - Audit log + undo - External-agent setup docs (Claude Code, opencode, generic MCP) - *(deferred)* Voice I/O — layered onto the chat panel later ## Cross-epic dependencies The domain tool surface needs the domain entities to exist. That depends on epics #4 (Career data: Profile, Skills, Education, Jobs, Contracts, Projects) and #5 (Network: Organizations, People, Notes). Tooling and infrastructure tickets (ADRs, PAT, MCP endpoint, chat UI scaffolding) can proceed in parallel with the feature epics; the tool registry fills in entity-by-entity as the repository layers land. ## Exit criteria - A user opens the PWA, types "draft a paragraph summary of my recent contracting work and add a note about last week's call with Sam to Sam's profile" — the agent answers and, on confirm, writes the note. - A user pastes a Carol-issued PAT into Claude Code's MCP config and asks Claude to "look at my recent jobs and draft a one-paragraph experience summary for my resume" — Claude reads via MCP and produces the summary. - A second user signing in on the same instance sees none of the first user's data through either surface, and a PAT for user A cannot read user B's data. - Every agent-driven write is captured in the audit log with before/after state and is undoable from the UI.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
james/carol#47
No description provided.