中文 | English
An MCP skill that lets any MCP-capable agent framework pop up a dedicated blackboard window — the user watches the board being drawn and asks questions in the same window, powered by a single LLM throughout.
A general-purpose MCP skill providing a "study buddy" style blackboard tutoring experience:
- Agent-triggered popup: the browser window opens automatically when the tool is called
- SVG blackboard: the LLM generates SVG; the frontend renders it as strokes appearing over time
- Single LLM: no second brain anywhere — all reasoning is done by the calling framework
- LaTeX rendering: both the board and the chat area render math via KaTeX
- Streaming strokes with adjustable speed: the board fills in block by block, speed is user-controllable
- Voice input / speech output (optional): ASR / TTS configured by the user; gracefully degrades when unset
┌─────────────────────────────┐
│ Agent framework │
│ (OpenCode / QwenPaw / ...) │
└──────────┬──────────────────┘
│ MCP tool call
▼
┌─────────────────────────────┐
│ interactive-mcp (MCP) │
│ ┌─────────────────────┐ │
│ │ Broker (aiohttp) │ │
│ │ - popup + WebSocket│ │
│ │ - streaming push │ │
│ │ - ASR / TTS proxy │ │
│ └─────────────────────┘ │
└──────────┬──────────────────┘
│ WebSocket
▼
┌─────────────────────────────┐
│ Popup blackboard window │
│ - SVG board │
│ - chat area │
│ - LaTeX + TTS + ASR │
└─────────────────────────────┘
Three MCP tools form a loop:
open_tutoring(topic)
↓
show_and_wait(content) ← push board + block for user input
↓ loop
show_and_wait(content)
↓
close_tutoring()
Key design: The blocking nature of an MCP tool is used to "pause" the agent's main loop. The user's input inside the popup becomes the tool's return value, fed back to the agent. So there is only ever one LLM — the one belonging to the calling framework.
git clone https://github.com/coldcat8120/interactive-mcp.git
cd interactive-mcp
pip install -r requirements.txtExample for OpenCode (~/.config/opencode/opencode.jsonc):
Set timeout generously (e.g. 1 hour) — the tool blocks until the user finishes interacting in the popup window.
Any MCP client that supports stdio transport will work.
Found this project on ModelScope? You still need to run it locally — this is a local-only MCP server.
-
Clone the repo locally:
git clone https://github.com/coldcat8120/interactive-mcp.git cd interactive-mcp pip install -r requirements.txt -
Change the
"args"value in the MCP config shown on ModelScope to an absolute path pointing to your localserver.py:"args": ["C:\\Users\\you\\interactive-mcp\\server.py"]
-
Paste the modified config into your MCP client (Cherry Studio, Claude Desktop, Cursor, etc.).
See Installation for details.
In the agent chat, say:
Call the
open_tutoringtool ofmy-mcp, topic: Pythagorean theorem
A new browser window appears in a few seconds, and the tutoring agent starts drawing on the board.
Click ⚙️ Voice in the top-right corner of the popup to open the settings panel, which holds both ASR and TTS configuration. All settings live only in browser localStorage — when unset, features degrade gracefully instead of crashing.
Fill in any OpenAI-compatible /audio/transcriptions endpoint:
| Service | URL | Model |
|---|---|---|
| Local llama.cpp + Qwen3-ASR | http://127.0.0.1:8082 |
qwen3-asr |
| OpenAI Whisper | https://api.openai.com/v1 |
whisper-1 |
| SiliconFlow / Groq | provider base_url | provider model ID |
Local Qwen3-ASR via llama.cpp:
llama-server \
-m Qwen3-ASR-0.6B-Q8_0.gguf \
--mmproj mmproj-Qwen3-ASR-0.6B-bf16.gguf \
--port 8082The broker transcodes browser recordings to 16 kHz mono WAV via ffmpeg before forwarding, so ffmpeg must be on your system (a standalone ffprobe on Windows also works).
When unset, clicking 🎤 simply prompts and expands the settings panel — no crash.
Fill in any OpenAI-compatible /audio/speech endpoint:
| Service | URL | Model | Voice |
|---|---|---|---|
| OpenAI | https://api.openai.com/v1 |
tts-1 |
alloy / nova / … |
| SiliconFlow | https://api.siliconflow.cn/v1 |
FunAudioLLM/CosyVoice2-0.5B |
claire / … |
| Local TTS | http://127.0.0.1:8083 |
provider-dependent | provider-dependent |
Leave blank to use the browser's built-in SpeechSynthesis (limited voices but zero setup).
When a server-side TTS is configured it is used first; on failure the browser fallback takes over silently, so tutoring is never interrupted.
The conventional approach wraps an entire tutoring agent into its own process with its own LLM. Problems:
- Two brains — context is broken; the specialized agent can't see the main framework's chat history
- Prompt bloat — the general framework's prompt has to carry pedagogy, SVG rules, etc.
- Not portable — switching frameworks means rewriting everything
This project instead keeps the MCP server as a window and a pipe only; all LLM reasoning stays with the caller.
- A single LLM with full context
- Teaching constraints live in the tool descriptions, never polluting the framework prompt
- Plug-and-play with any MCP-capable framework
When an LLM generates structured graphics, SVG is the only format that simultaneously satisfies:
- Highest LLM familiarity (abundantly present in training data)
- Native browser rendering, no extra engine
- Embeds KaTeX math via
foreignObject - Text content can be stripped out for TTS
- Strokes and speech can't be perfectly synchronized: speech runs at ~5 chars/s, strokes at 100+ chars/s even at the slowest setting. Mitigated by defaulting to a slow stroke rate.
- SVG
<text>content is spoken after the element closes, not character-by-character. - Browser TTS voices are limited: only system-installed voices, quality varies. Configuring a server-side TTS is recommended.
- KaTeX doesn't handle CJK well: Chinese inside formulas needs
\text{}wrapping; the frontend auto-wraps as a fallback.
interactive-mcp/
├── server.py # MCP tool definitions (three-tool loop)
├── broker.py # Resident broker: window + WebSocket + streaming + ASR/TTS proxy
├── requirements.txt # mcp + aiohttp + httpx
├── LICENSE # MIT
├── NOTICE # Third-party licenses (KaTeX, etc.)
├── docs/
│ └── screenshot.png # screenshot
└── static/
├── index.html # board + chat + KaTeX + TTS + ASR + speed slider
└── katex/ # KaTeX assets
The underlying pattern — popup + blocking loop + structured output — is general. Swap the SVG blackboard for anything else and you get a new skill:
- Mermaid tutoring: flowcharts, sequence diagrams
- Code editor: live coding with execution
- 3D scenes: geometry and physics visualization
- Mind maps: knowledge unfolding step by step
Inspired by a real blackboard — the teacher writes while explaining, students watch while asking. A rhythm we shouldn't lose in the digital age.
This project is licensed under the MIT License.
Third-party components are documented in NOTICE (including KaTeX).

{ "mcp": { "my-mcp": { "type": "local", "command": [ "python", "/absolute/path/interactive-mcp/server.py" ], "timeout": 3600000 } } }