Skip to content

Tutor & MCP Apps prototype - #74649

Draft
breville wants to merge 6 commits into
stagingfrom
ai-tutor-mcp-demo
Draft

Tutor & MCP Apps prototype#74649
breville wants to merge 6 commits into
stagingfrom
ai-tutor-mcp-demo

Conversation

@breville

@breville breville commented Aug 14, 2026

Copy link
Copy Markdown
Member

[written by Claude]

This adds a demo page at /ai_tutorial_demo (signed-in users) exploring a new shape of guided lesson: an AI tutor chats with the student on the left, and brings up interactive activities on the right — a bar chart, a multiple-choice question, and a small code editor — deciding what to show and when based on what the student does. The lesson it teaches is how to calculate an average.

The point of the demo is the architecture as much as the page. Each widget is a self-contained MCP server following the MCP Apps spec (the standard Anthropic and OpenAI ship for embedding interactive UI in AI hosts). The AI learns what widgets exist entirely from metadata the servers advertise, and the widgets report student actions back through the same protocol. The servers run in-page for the demo, but nothing about the page knows that — any of them could move behind a remote URL, which is the path to third parties building labs that plug into our tutor.

Example

Open the page signed in. The tutor greets you and puts up an editable bar chart, and asks you to eyeball the average. Drag a bar — the tutor sees the change and moves to a multiple-choice check. Answer it and the tutor opens a code editor with a starter average function. Press Run and the tutor reads your console output and responds. An "MCP activity" log at the bottom right shows the actual protocol traffic (tool discovery, template fetches, tool calls) for anyone curious about the plumbing.

Screenshot 2026-08-14 at 1 36 30 PM

Screenshot 2026-08-14 at 1 40 19 PM

How it works

  • Each widget is an MCP server (official TypeScript SDK) exposing a tool plus a ui:// HTML template. The page's host runtime discovers tools with tools/list, prefetches templates, and renders them in sandboxed iframes that speak the MCP Apps postMessage protocol. Student actions flow back as ui/update-model-context events.
  • Widget iframes run with sandbox="allow-scripts" and a no-network content-security policy. Student code in the editor widget executes inside that sandbox.
  • Chat turns go through the AI gateway (Gemini 2.5 Flash). The gateway has no native tool-calling API, so the agent loop renders the discovered tool metadata into the system prompt and receives tool calls via structured output. The chat UI reuses the aichat component library pieces.

Testing

  • Unit tests cover the MCP discovery/call path (test/unit/aiTutorialDemo/).
  • Playwright pass with a scripted model exercising all three widgets end to end, plus a live-model pass.
  • Known demo limitations, noted in code: one widget on screen at a time, and an infinite loop in student code hangs the tab (a worker with a timeout is the production fix).

🤖 Generated with Claude Code

breville and others added 3 commits August 14, 2026 15:05
AI chat on the left teaches averages; the model drives three widgets on
the right (bar chart, multiple choice, JS editor) over real MCP: each
widget is an in-page MCP server advertising tools plus a ui:// HTML
template per the MCP Apps extension, rendered in a sandboxed iframe
speaking the spec's postMessage JSON-RPC. The host discovers everything
from tools/list. Completions go through the AI gateway; tool calls are
encoded via structured output since the gateway has no native tool API.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Found in browser testing: the shared widget CSP (script-src
'unsafe-inline') blocked new Function, so student code never ran. Only
the code widget gets 'unsafe-eval'; the network stays blocked for all
widgets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Chart, then multiple choice, then the code editor, one interaction
each; the mean-line chart replay moves to the wrap-up. The prompt now
tells the model to advance after a single interaction per widget.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@breville breville changed the title MCP prototype Tutor & MCP prototype Aug 14, 2026
@breville breville added the AI generated This PR has been substantially generated using AI. label Aug 14, 2026
Live-model run produced starterCode with newlines flattened to spaces,
which both wraps badly and breaks the code (a // comment swallows the
rest of the line). The editor now scrolls horizontally instead of
wrapping, and the tool description plus the interaction contract tell
the model to encode line breaks as \n in argumentsJson.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@breville
breville marked this pull request as draft August 14, 2026 17:17
user-select: none on the svg, and preventDefault when a drag grabs a
bar so the browser never starts a selection that could extend into
surrounding text.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@breville breville changed the title Tutor & MCP prototype Tutor & MCP Apps prototype Aug 14, 2026
The post-tool-call loop iteration existed so the model could retry a
failed call, but it also let an eager model chain chart, question, and
editor with no student input between them. Now a call that renders a
widget breaks the loop; only failed calls (nothing on screen) get
another model call within the cap. The interaction contract tells the
model the turn ends there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI generated This PR has been substantially generated using AI.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant