Skip to content

Commit 5e85433

Browse files
committed
mcp-improvements
1 parent 782764a commit 5e85433

10 files changed

Lines changed: 216 additions & 76 deletions

‎framework/docs/FRAMEWORK_GUIDE.md‎

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,12 @@ Runs **in Node.js** during build (via `vite.framework-dev.config.js` `closeBundl
679679
680680
### MCP `coursecode_lint` — Build-Time Only
681681
682-
The MCP `coursecode_lint` tool runs the build linter (config validation, CSS class verification, structure checks). It does NOT include runtime errors. For runtime errors and contrast warnings, use `coursecode_errors` (lightweight — just errors and console logs) or `coursecode_state` (full state snapshot including errors).
682+
The MCP `coursecode_lint` tool runs the static/build-time linter (config validation, CSS class verification, structure checks). It does **not** inspect the running preview and does **not** include live runtime, browser console, or Vite build-watch diagnostics.
683+
684+
Use:
685+
- `coursecode_lint` for static preflight validation after source/config edits
686+
- `coursecode_errors` for the live "what is broken right now?" preview rollup
687+
- `coursecode_state` when you also need current slide, TOC, engagement, LMS state, and diagnostics
683688
684689
### Shared Rules (`lib/validation-rules.js`)
685690
@@ -861,16 +866,18 @@ The MCP server runs a **persistent headless Chrome** internally via `puppeteer-c
861866
862867
### Preview Server Ownership
863868
864-
The MCP does **not** start or manage the preview server. The preview must be running before using runtime tools:
869+
The MCP does **not** start or manage the preview server. Runtime tools connect to an already-running preview server.
865870
866-
- **Human**: run `coursecode preview` (or `npm run preview`) in a terminal
867-
- **AI agent**: use your terminal/command execution tool to run `npm run preview`
871+
- If preview is already running for the current project, use it. Do **not** start a second preview server.
872+
- If preview is not running, start it in a terminal with `coursecode preview`.
873+
- For framework development from this repo, use `npm run preview`.
874+
- AI agents may start preview only via their terminal/command execution tool, and only after confirming preview is not already running or after a runtime MCP tool reports that preview is not running.
868875
869876
If the preview is not running, runtime tools fail fast with a clear error message.
870877
871878
### Setup
872879
873-
1. Start the preview server externally (see above)
880+
1. Make sure the preview server is running externally (see above)
874881
2. Add to IDE MCP config:
875882
876883
```json
@@ -887,8 +894,8 @@ If the preview is not running, runtime tools fail fast with a clear error messag
887894
888895
| Tool | Purpose | Returns |
889896
|------|---------|--------|
890-
| `coursecode_state` | Full course snapshot | `{slide, toc, interactions, engagement, lmsState, apiLog, errors, frameworkLogs, consoleLogs}` |
891-
| `coursecode_errors` | Errors + console logs only | `{errors, consoleLogs, count, clean}` — same error sources as `coursecode_state`, without the state payload |
897+
| `coursecode_state` | Full course snapshot + live diagnostics | `{slide, toc, interactions, engagement, lmsState, apiLog, diagnostics, issues, errors, frameworkLogs, consoleLogs}` |
898+
| `coursecode_errors` | Live diagnostic rollup only | `{build, runtime, framework, console, issues, errors, count, clean}` — same diagnostic sources as `coursecode_state`, without the state payload |
892899
| `coursecode_navigate` | Go to slide by ID | `{slide, interactions, engagement, accessibility}` |
893900
| `coursecode_interact` | Set response + evaluate | `{interactionId, response}` → `{correct, score, feedback}` |
894901
| `coursecode_screenshot` | Visual capture (JPEG) | Optional `slideId` to navigate first, `fullPage` for scroll capture |
@@ -933,7 +940,7 @@ MCP Server (IDE) ──puppeteer──▶ Headless Chrome ──HTTP──▶ Pr
933940
└── Course iframe (CourseCodeAutomation API)
934941
```
935942

936-
- **Preview not running?** → Tools return clear error: "Start preview server first"
943+
- **Preview not running?** → Tools return a clear error. Start preview externally in a terminal, then retry.
937944
- **Chrome not found?** → Install Google Chrome or set `CHROME_PATH` env var
938945

939946
### Pre-Release Responsive Checks (Framework)

‎framework/docs/USER_GUIDE.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ Once connected, your AI assistant gains these capabilities:
297297
| `coursecode_screenshot` | Take a screenshot of any slide |
298298
| `coursecode_interact` | Answer an interaction and check if it's correct |
299299
| `coursecode_reset` | Clear progress and restart the course |
300-
| `coursecode_lint` | Check for errors (bad CSS classes, missing components, config issues) |
300+
| `coursecode_errors` | Check live preview diagnostics (build, runtime, framework, and console issues) |
301+
| `coursecode_lint` | Run static preflight checks (bad CSS classes, missing components, config issues) |
301302
| `coursecode_component_catalog` | Browse available UI components (tabs, accordion, cards, etc.) |
302303
| `coursecode_interaction_catalog` | Browse available interaction types (multiple choice, drag-drop, etc.) |
303304
| `coursecode_css_catalog` | Browse available CSS classes by category |
@@ -306,7 +307,7 @@ Once connected, your AI assistant gains these capabilities:
306307
| `coursecode_workflow_status` | Get guidance on what to do next based on your project's current state |
307308
| `coursecode_build` | Build the course for LMS deployment |
308309

309-
> **Note:** The preview server must be running before using runtime tools like `coursecode_state`, `coursecode_screenshot`, or `coursecode_navigate`. Start it with `coursecode preview` in a terminal.
310+
> **Note:** The preview server must be running before using runtime tools like `coursecode_state`, `coursecode_errors`, `coursecode_screenshot`, or `coursecode_navigate`. If preview is not already running for this project, start it with `coursecode preview` in a terminal. Do not start a second preview server if one is already running.
310311
311312
### How the Workflow Changes
312313

‎framework/js/automation/api-interactions.js‎

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import interactionRegistry from '../managers/interaction-registry.js';
88
import { courseConfig } from '../../../course/course-config.js';
9-
import { recordInteractionResult } from '../components/interactions/interaction-base.js';
9+
import { getInteractionState, recordInteractionResult } from '../components/interactions/interaction-base.js';
1010
import { logger } from '../utilities/logger.js';
1111

1212
/**
@@ -18,11 +18,26 @@ export function createInteractionMethods(logTrace) {
1818
return {
1919
listInteractions() {
2020
const interactions = interactionRegistry.getAll();
21-
const simplifiedList = interactions.map(i => ({
22-
id: i.id,
23-
type: i.type,
24-
description: i.description
25-
}));
21+
const simplifiedList = interactions.map(i => {
22+
const savedState = getInteractionState(i.id);
23+
let response = savedState?.response;
24+
25+
if (response === undefined && typeof i.instance?.getResponse === 'function') {
26+
try {
27+
response = i.instance.getResponse();
28+
} catch {
29+
response = undefined;
30+
}
31+
}
32+
33+
return {
34+
id: i.id,
35+
type: i.type,
36+
description: i.description,
37+
hasResponse: response !== null && response !== undefined && response !== '',
38+
isChecked: savedState?.submitted === true
39+
};
40+
});
2641
logTrace('listInteractions', { count: simplifiedList.length });
2742
return simplifiedList;
2843
},
@@ -33,10 +48,23 @@ export function createInteractionMethods(logTrace) {
3348
throw new Error(`CourseCodeAutomation: Interaction "${interactionId}" not found on the current slide`);
3449
}
3550
logTrace('getInteractionMetadata', { interactionId });
51+
const savedState = getInteractionState(entry.id);
52+
let response = savedState?.response;
53+
54+
if (response === undefined && typeof entry.instance?.getResponse === 'function') {
55+
try {
56+
response = entry.instance.getResponse();
57+
} catch {
58+
response = undefined;
59+
}
60+
}
61+
3662
return {
3763
id: entry.id,
3864
type: entry.type,
39-
description: entry.description
65+
description: entry.description,
66+
hasResponse: response !== null && response !== undefined && response !== '',
67+
isChecked: savedState?.submitted === true
4068
};
4169
},
4270

‎lib/headless-browser.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ class HeadlessBrowser {
358358

359359
// Navigate to specific slide if requested
360360
if (slideId) {
361-
await this.evaluate((id) => {
362-
window.CourseCodeAutomation.goToSlide(id);
361+
await this.evaluate(async (id) => {
362+
await window.CourseCodeAutomation.goToSlide(id);
363363
}, slideId);
364364
// Wait for slide transition
365365
await new Promise(resolve => setTimeout(resolve, 500));

‎lib/mcp-prompts.js‎

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const TOOLS = [
2020
// --- Runtime Tools (require headless browser) ---
2121
{
2222
name: 'coursecode_state',
23-
description: `Get course state, runtime errors, and warnings in one call. This is the primary tool for checking errors.
23+
description: `Get course state and live preview diagnostics in one call.
2424
2525
Returns:
2626
- slide: current slide ID (string)
@@ -29,12 +29,15 @@ Returns:
2929
- engagement: slide engagement {complete, percentage, requirements}
3030
- lmsState: LMS data {score, completion, success, bookmark, format, objectives, state}
3131
- apiLog: last 20 LMS API calls [{timestamp, method, args, result}]
32-
- errors: runtime errors/warnings [{type, message, hint, isWarning}]
32+
- diagnostics: live issue rollup with build, runtime, framework, console, issues, count, clean
33+
- issues/errors: flat live issue list [{source, severity, isWarning, type, message, hint?}]
34+
- runtimeErrors: runtime/debug-panel errors and warnings only
35+
- buildErrors/buildWarnings: backward-compatible build-watch aliases
3336
- frameworkLogs: structured framework log events [{level, domain, operation, message, stack?, timestamp}]
3437
- consoleLogs: browser console warnings/errors [{type, text, time}]
3538
3639
Use this first to understand the course state before taking actions.
37-
For error checking only (after file edits), prefer coursecode_errors — same error sources, smaller payload.
40+
For checking what is broken after file edits, prefer coursecode_errors — same live diagnostic sources, smaller payload.
3841
Requires preview server to be running.`,
3942
inputSchema: {
4043
type: 'object',
@@ -48,15 +51,23 @@ Requires preview server to be running.`,
4851
},
4952
{
5053
name: 'coursecode_errors',
51-
description: `Get runtime errors and warnings from the live preview. Uses the same error sources as coursecode_state (preview server errors + browser console) but without the heavyweight state payload.
54+
description: `Get all current live preview diagnostics without the heavyweight course state payload.
55+
56+
This is the primary "what is broken right now?" tool after edits. It aggregates:
57+
- build: Vite/build-watch errors and warnings from the running preview server
58+
- runtime: stub LMS/debug-panel errors and warnings
59+
- framework: CourseCode logger warnings/errors
60+
- console: browser console warnings/errors
61+
62+
This is different from coursecode_lint, which is a static/build-time linter and does not inspect the running preview.
5263
5364
Returns:
54-
- errors: [{type, message, hint?, isWarning?}] — preview server errors and warnings
55-
- consoleLogs: [{type, text, time}] — browser console warnings/errors
56-
- count: total number of errors + console logs
57-
- clean: true if no errors, warnings, or console issues
65+
- build/runtime/framework/console: grouped diagnostics by source
66+
- issues/errors: flat list [{source, severity, isWarning, type, message, hint?}] for agents
67+
- count: total issue count
68+
- clean: true if no live issues were found
69+
- runtimeErrors/frameworkLogs/consoleLogs: source-specific aliases
5870
59-
Use after making file changes to check for breakage without the overhead of coursecode_state.
6071
Requires preview server to be running.`,
6172
inputSchema: {
6273
type: 'object',
@@ -378,16 +389,16 @@ Use to discover available interactions before creating assessments.`,
378389
},
379390
{
380391
name: 'coursecode_lint',
381-
description: `Run the course linter and get structured results.
392+
description: `Run the static course linter and get structured results.
382393
383-
Always runs build-time lint (config, CSS classes, structure). Does NOT include runtime errors — use coursecode_state for runtime errors and contrast warnings when the preview server is running.
394+
This is a preflight/static validation tool for config, source structure, CSS class names, and schema rules. It does NOT inspect the running preview and does NOT include live runtime, browser console, or Vite build-watch diagnostics. Use coursecode_errors for the live "what is broken right now?" view when preview is running.
384395
385396
Returns:
386397
- errors: [{slideId?, rule, message, severity, hint?}]
387398
- warnings: [{slideId?, rule, message, severity, hint?}]
388399
- passed: boolean
389400
390-
Build-time rules (always checked):
401+
Static rules (always checked):
391402
- undefined-css-class: hallucinated or stale class names (with fix suggestions)
392403
- unknown-component: unregistered data-component types
393404
- requirement-missing-component: engagement requirement without matching component
@@ -396,7 +407,7 @@ Build-time rules (always checked):
396407
- assessment-id-mismatch: config ID doesn't match assessment ID
397408
- invalid-gating: bad gating condition configuration
398409
399-
Use AFTER making changes to validate the course.`,
410+
Use after making source/config changes as a fast static check. Then use coursecode_errors against the running preview for live diagnostics.`,
400411
inputSchema: {
401412
type: 'object',
402413
properties: {},
@@ -764,12 +775,16 @@ All runtime tools (state, navigate, interact, screenshot, viewport, reset) execu
764775
765776
### Preview Server Ownership
766777
- The MCP does NOT start or manage the preview server
767-
- The preview must be started externally: run \`coursecode preview\` in a terminal (human) or via a terminal/command execution tool (AI agent)
768-
- If preview is not running, runtime tools will fail with a clear error message
778+
- Before using runtime tools, check whether preview is already running for this project
779+
- If preview is already running, use it; do not start a second preview server
780+
- If preview is not running, start it externally in a terminal: run \`coursecode preview\` (or \`npm run preview\` for framework development)
781+
- AI agents may start preview only via a terminal/command execution tool, and only after a runtime tool reports that preview is not running
769782
- The headless browser auto-reconnects when Vite rebuilds (file changes)
770783
771784
### Navigation API
772-
- coursecode_state → get slim TOC with slide IDs, current slide, interactions, engagement, lmsState, apiLog, errors, frameworkLogs, consoleLogs
785+
- coursecode_state → get slim TOC with slide IDs, current slide, interactions, engagement, lmsState, apiLog, diagnostics, frameworkLogs, consoleLogs
786+
- coursecode_errors → get live diagnostics only (build/runtime/framework/console); use this after edits
787+
- coursecode_lint → run static preflight lint only; it is not a live preview diagnostic
773788
- coursecode_navigate(slideId) → go to any slide instantly by ID
774789
- coursecode_viewport(breakpoint or {width,height}) → set viewport for responsive testing (persists until changed)
775790
- coursecode_screenshot(slideId) → navigate + capture in one call (quality modes only, never changes viewport)

0 commit comments

Comments
 (0)