Skip to content

Feat/vscode support#9

Draft
iTubeGamer wants to merge 1 commit intoexcalidraw:mainfrom
iTubeGamer:feat/vscode-support
Draft

Feat/vscode support#9
iTubeGamer wants to merge 1 commit intoexcalidraw:mainfrom
iTubeGamer:feat/vscode-support

Conversation

@iTubeGamer
Copy link
Copy Markdown

feat: VS Code host support

Add support for MCP App hosts that don't offer fullscreen mode (VS Code, etc.), while keeping full Excalidraw editing capabilities through an inline editor.

Problem

The Excalidraw MCP App was built exclusively for Claude Desktop's fullscreen mode. In VS Code's Copilot Chat, which only supports inline display mode:

  • The fullscreen button appeared briefly then disappeared (flicker)
  • Diagrams were not interactive — no way to edit them
  • Scrolling through chat re-fired ontoolinput/ontoolresult events, causing unnecessary re-renders
  • Diagram state leaked across chats via a shared localStorage fallback key

Before / After

excalidraw-mcp-vscode-issues.mp4
fixed.mp4

Changes

Inline editing mode (src/mcp-app.tsx, src/global.css)

When fullscreen is unavailable, an Edit button replaces the Fullscreen button. Clicking it opens an Excalidraw editor overlaid on top of the SVG preview — same editing experience, no fullscreen required.

  • SVG stays in the DOM during editing (visibility: hidden) so VS Code can measure iframe content height correctly
  • Editor container uses absolute positioning to overlay the preview area
  • Toolbar adapts per host: Claude gets [Export] [Fullscreen], VS Code gets [Export] [Edit]

Replay deduplication (src/mcp-app.tsx)

VS Code replays ontoolinput + ontoolresult whenever a widget scrolls into view. Without dedup, this caused re-renders and flicker. Fixed by:

  • Tracking last processed input via ref — skip if elements string matches
  • Tracking last checkpoint ID — skip ontoolresult if checkpoint hasn't changed

Host detection & defaults (src/mcp-app.tsx)

  • canFullscreen defaults to false (was true), preventing the fullscreen button from flashing on hosts that don't support it
  • onhostcontextchanged reads availableDisplayModes to set canFullscreen, with an else fallback to false
  • Storage key only set when toolCallId is present — no more "default" fallback that caused cross-chat diagram sharing

Export without fullscreen (src/mcp-app.tsx)

Extracted exportElements() as a standalone function using serializeAsJSON directly, so Export works without needing the Excalidraw imperative API (which requires the editor to be mounted).

Technical notes

  • No streaming in VS Code: Investigation confirmed VS Code fires zero ontoolinputpartial events. The streaming draw-on animation only works in Claude Desktop. This is a host limitation, not fixable from the widget side.
  • React hooks order: All hooks (useCallback for toggleInlineEdit, toggleFullscreen) are placed before early returns to avoid hooks-order violations that caused black-box rendering.
  • No changes to server.ts or tool definitions: This is purely a widget-side change.

@antonpk1
Copy link
Copy Markdown
Collaborator

Thanks for the thorough investigation — the VS Code replay dedup and canFullscreen detection are spot on.

I wonder if we can simplify the approach though. Instead of an overlay editor with show/hide toggling, what if we just mount the Excalidraw editor inline when fullscreen isn't available? So instead of SVG preview + Edit button + overlay CSS, it's just: no fullscreen → editor is the view. One code path, no !important overrides.

Also please rebase on latest main — I've since added dist/ to .gitignore so those changes will drop out.

Would you be open to trying that simpler approach? Happy to create a PR myself as well if that's easier.

When the host doesn't report fullscreen in availableDisplayModes, mount the
Excalidraw editor directly as the primary view instead of SVG-only preview.
One code path, no overlay or mode toggling.

Changes:
- Detect canFullscreen from host context availableDisplayModes
- Size inline editor via containerDimensions.maxHeight (fallback 500px)
- Deduplicate ontoolinput/ontoolresult replays (VS Code scroll behavior)
- Show toolbar only when fullscreen is available
- Rename .fullscreen-btn to .toolbar-btn, add flex layout to .toolbar
@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 12, 2026

Someone is attempting to deploy a commit to the Excalidraw Team on Vercel.

A member of the Team first needs to authorize it.

@iTubeGamer iTubeGamer marked this pull request as draft February 12, 2026 15:53
@iTubeGamer
Copy link
Copy Markdown
Author

Always displaying the inline-editing mode kind of works, but has the drawdown that you can't scroll in the vs code chat very good, because you will scroll inside the excalidraw editor instead (scroll in scroll). Allowing to enter and exit the editing mode fixed this.

But i can't get the contianer to stay at a 4/3 aspect ratio while resizing the vs code chat without keeping the svg in the backgound for measurement. Feel free to give it a try yourself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants