Skip to main content
Glama
ide-instructions-refactor.md10.2 kB
# IDE Integration Instructions Refactor ## Status: ✅ Complete This document describes the refactoring of IDE integration instructions to improve code maintainability and add URL state persistence. ## Problem Statement The previous implementation had several issues: 1. **Code Duplication**: IDE instructions split between `stdio-setup.tsx` and `remote-setup.tsx`, making it hard to maintain consistency 2. **Hard to Add New IDEs**: Required editing two separate, unrelated files for each new IDE 3. **Lost State**: When switching between Cloud/Stdio modes, the IDE selection was not preserved 4. **No URL Persistence**: Couldn't share direct links to specific IDE instructions ## Solution Overview ### Key Improvements 1. **Code Co-location**: Single file per IDE containing both stdio and cloud instructions 2. **URL State Persistence**: Use URL params (`?ide=claude-code&transport=cloud`) to preserve state 3. **Better Developer Experience**: Adding a new IDE now requires creating one file instead of editing two 4. **UI Unchanged**: Kept current transport-first hierarchy (minimal user-facing changes) ## Implementation Details ### New File Structure ``` components/fragments/ ├── instructions/ (new directory) │ ├── claude-code.tsx # All Claude Code instructions │ ├── cursor.tsx # All Cursor instructions │ ├── vscode.tsx # All VSCode instructions │ ├── codex-cli.tsx # All Codex CLI instructions │ ├── amp.tsx # All Amp instructions │ ├── gemini.tsx # All Gemini CLI instructions │ ├── opencode.tsx # All OpenCode instructions │ ├── warp.tsx # All Warp instructions │ ├── windsurf.tsx # All Windsurf instructions │ └── zed.tsx # All Zed instructions ├── stdio-setup.tsx (modified) ├── remote-setup.tsx (modified) ├── install-tabs.tsx (modified) └── getting-started.tsx (modified) ``` ### Component Pattern Each IDE instruction component follows this pattern: ```typescript interface InstructionProps { transport: 'cloud' | 'stdio'; } export function ClaudeCodeInstructions({ transport }: InstructionProps) { if (transport === 'cloud') { // Cloud/remote setup instructions with OAuth return <CloudInstructions />; } // Stdio setup instructions with CLI command return <StdioInstructions />; } ``` **Benefits:** - All Claude Code instructions (both transports) in one file - Easy to maintain - single source of truth for each IDE - Clear ownership - one file per IDE ### URL State Management Added URL-based state persistence in `getting-started.tsx`: ```typescript // Read initial state from URL parameters const [stdio, setStdio] = useState(() => { const params = new URLSearchParams(window.location.search); return params.get("transport") === "stdio"; }); const [selectedIde, setSelectedIde] = useState(() => { const params = new URLSearchParams(window.location.search); return params.get("ide") || "claude-code"; }); // Update URL when IDE or transport changes useEffect(() => { const params = new URLSearchParams(window.location.search); params.set("ide", selectedIde); params.set("transport", stdio ? "stdio" : "cloud"); window.history.pushState({}, "", `?${params.toString()}#getting-started`); }, [selectedIde, stdio]); ``` **URL Format:** - `?ide=claude-code&transport=cloud` - Cloud instructions for Claude Code - `?ide=cursor&transport=stdio` - Stdio instructions for Cursor **Default Values:** - `ide=claude-code` (most popular) - `transport=cloud` (recommended for new users) ### InstallTabs Component Enhancement Extended `install-tabs.tsx` to support both numeric index and string ID-based tab control: ```typescript export default function InstallTabs({ // Existing props for backward compatibility current, onChange, // New props for string-based control selectedTab, onTabChange, }: { current?: number; onChange?: (next: number) => void; selectedTab?: string; onTabChange?: (tabId: string) => void; }) { // Support both control methods let active: number; if (typeof current === "number") { active = current; } else if (selectedTab) { const index = items.findIndex((el) => el.props.id === selectedTab); active = index >= 0 ? index : internal; } else { active = internal; } // Call appropriate callback const setActive = React.useCallback((next: number) => { const tabId = items[next]?.props.id; if (selectedTab && onTabChange && tabId) { onTabChange(tabId); // String-based control } else { onChange?.(next); // Numeric control } }, [selectedTab, onTabChange, onChange, items]); } ``` ## Files Created ### New IDE Instruction Components (10 files) 1. `packages/mcp-cloudflare/src/client/components/fragments/instructions/claude-code.tsx` 2. `packages/mcp-cloudflare/src/client/components/fragments/instructions/cursor.tsx` 3. `packages/mcp-cloudflare/src/client/components/fragments/instructions/vscode.tsx` 4. `packages/mcp-cloudflare/src/client/components/fragments/instructions/codex-cli.tsx` 5. `packages/mcp-cloudflare/src/client/components/fragments/instructions/amp.tsx` 6. `packages/mcp-cloudflare/src/client/components/fragments/instructions/gemini.tsx` 7. `packages/mcp-cloudflare/src/client/components/fragments/instructions/opencode.tsx` 8. `packages/mcp-cloudflare/src/client/components/fragments/instructions/warp.tsx` 9. `packages/mcp-cloudflare/src/client/components/fragments/instructions/windsurf.tsx` 10. `packages/mcp-cloudflare/src/client/components/fragments/instructions/zed.tsx` ## Files Modified ### 1. `stdio-setup.tsx` **Changes:** - Added imports for all IDE instruction components - Added `StdioSetupTabsProps` interface with `selectedIde` and `onIdeChange` props - Replaced inline Tab content with `<IDEInstructions transport="stdio" />` - Removed unused imports **Before:** ```typescript <Tab id="claude-code" title="Claude Code"> <ol> <li>Run <code>npx @sentry/mcp-server</code></li> {/* ... inline instructions */} </ol> </Tab> ``` **After:** ```typescript <Tab id="claude-code" title="Claude Code"> <ClaudeCodeInstructions transport="stdio" /> </Tab> ``` ### 2. `remote-setup.tsx` **Changes:** - Added imports for all IDE instruction components - Added `RemoteSetupTabsProps` interface - Replaced inline Tab content with `<IDEInstructions transport="cloud" />` - Removed unused variable declarations ### 3. `getting-started.tsx` **Changes:** - Added URL-based state management for `ide` parameter - Modified `stdio` state to read from URL (`transport` param) - Added `useEffect` to update URL when IDE or transport changes - Passed `selectedIde` and `setSelectedIde` props to both tab components ### 4. `install-tabs.tsx` **Changes:** - Added `selectedTab?: string` and `onTabChange?: (tabId: string) => void` props - Modified active index calculation to support both numeric and string-based control - Updated `setActive` callback to call `onTabChange` with tab ID string - Maintained backward compatibility with existing numeric index usage ## Adding a New IDE With this refactor, adding a new IDE is now a simple 3-step process: ### Step 1: Create IDE Instruction Component Create `packages/mcp-cloudflare/src/client/components/fragments/instructions/new-ide.tsx`: ```typescript interface NewIDEInstructionsProps { transport: "cloud" | "stdio"; } export function NewIDEInstructions({ transport }: NewIDEInstructionsProps) { if (transport === "cloud") { return ( <ol> <li>Cloud setup instructions...</li> </ol> ); } return ( <ol> <li>Stdio setup instructions...</li> </ol> ); } ``` ### Step 2: Import in stdio-setup.tsx ```typescript import { NewIDEInstructions } from "./instructions/new-ide"; // Add to StdioSetupTabs: <Tab id="new-ide" title="New IDE"> <NewIDEInstructions transport="stdio" /> </Tab> ``` ### Step 3: Import in remote-setup.tsx ```typescript import { NewIDEInstructions } from "./instructions/new-ide"; // Add to RemoteSetupTabs: <Tab id="new-ide" title="New IDE"> <NewIDEInstructions transport="cloud" /> </Tab> ``` ### Step 4: Add Icon (Optional) If the IDE needs an icon, add it to the `iconsByID` mapping in `install-tabs.tsx`: ```typescript const iconsByID: Record<string, React.ReactNode> = { // ... existing icons "new-ide": <NewIDEIcon />, }; ``` **That's it!** All instructions for the new IDE live in one file, making it easy to maintain. ## Benefits Summary ### For Developers - ✅ **Easier IDE Management**: Create one file instead of editing two separate files - ✅ **Better Code Organization**: All IDE instructions co-located - ✅ **Reduced Duplication**: Single source of truth per IDE - ✅ **Clearer Ownership**: One file per IDE makes changes obvious ### For Users - ✅ **URL Sharing**: Can share links like `?ide=cursor&transport=stdio` - ✅ **State Preservation**: IDE selection maintained when switching Cloud ↔ Stdio - ✅ **Familiar UI**: No changes to the existing interface - ✅ **All Existing Features**: Deep links, code snippets, keyboard navigation still work ## Testing Checklist - ✅ URL persistence works correctly - ✅ State persists when switching transport within an IDE - ✅ All 10 IDE instructions render correctly - ✅ Deep link buttons work (Cursor, VSCode) - ✅ Keyboard navigation still works - ✅ Mobile responsive design maintained - ✅ Accessibility maintained (screen readers, ARIA) ## Migration Notes This refactor is **100% backward compatible**: - InstallTabs still supports numeric index control (used elsewhere) - No breaking changes to component APIs - All existing functionality preserved - UI remains identical to users ## Future Improvements Potential future enhancements: 1. **Analytics**: Track which IDE/transport combinations are popular 2. **IDE Detection**: Auto-detect user's IDE and pre-select it (if worth complexity) 3. **Favorites**: Allow users to mark favorite IDEs for quick access

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/getsentry/sentry-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server