CodeMirror MCP icon

CodeMirror MCP

Advanced CodeMirror extension implementing Model Context Protocol for intelligent resource mentions, prompt commands, and AI-assisted coding

View Source

CodeMirror MCP

CodeMirror MCP is a sophisticated extension that brings Model Context Protocol capabilities directly into CodeMirror editors. It enables intelligent resource mentions, prompt commands, and seamless AI-assisted coding experiences within any application using CodeMirror.

Features

  • Resource Mentions: Intelligent @-mentions for files, functions, and documentation
  • Prompt Commands: Built-in slash commands for AI interactions
  • Syntax Awareness: Context-aware suggestions based on current code
  • Live Preview: Real-time preview of referenced resources
  • Auto-completion: Smart completion for MCP resources and commands
  • Multi-language Support: Works with all CodeMirror language modes
  • Customizable UI: Flexible theming and UI customization options
  • Performance Optimized: Efficient handling of large codebases

Installation

NPM

npm install codemirror-mcp
# or
yarn add codemirror-mcp

CDN

<script src="https://unpkg.com/codemirror-mcp@latest/dist/codemirror-mcp.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/codemirror-mcp@latest/dist/codemirror-mcp.css">

Getting Started

Basic Setup

import { EditorView } from '@codemirror/view';
import { EditorState } from '@codemirror/state';
import { mcpExtension } from 'codemirror-mcp';

// Create MCP-enabled editor
const editor = new EditorView({
  state: EditorState.create({
    doc: 'console.log("Hello, MCP!");',
    extensions: [
      mcpExtension({
        serverUrl: 'http://localhost:3000/mcp',
        apiKey: 'your-api-key',
        enableResourceMentions: true,
        enablePromptCommands: true
      })
    ]
  }),
  parent: document.getElementById('editor')
});

Advanced Configuration

import { mcpExtension, MCPTheme } from 'codemirror-mcp';

const mcpConfig = {
  // Server configuration
  server: {
    url: 'http://localhost:3000/mcp',
    headers: {
      'Authorization': 'Bearer your-token',
      'X-API-Key': 'your-api-key'
    },
    timeout: 5000
  },
  
  // Resource mentions configuration
  resourceMentions: {
    enabled: true,
    trigger: '@',
    maxSuggestions: 10,
    debounceMs: 300,
    categories: ['files', 'functions', 'classes', 'documentation']
  },
  
  // Prompt commands configuration
  promptCommands: {
    enabled: true,
    trigger: '/',
    commands: {
      'explain': {
        description: 'Explain selected code',
        icon: '💡',
        shortcut: 'Cmd+E'
      },
      'refactor': {
        description: 'Refactor selected code',
        icon: '🔧',
        shortcut: 'Cmd+R'
      },
      'generate': {
        description: 'Generate code from description',
        icon: '✨',
        shortcut: 'Cmd+G'
      }
    }
  },
  
  // UI customization
  ui: {
    theme: MCPTheme.dark,
    position: 'floating', // 'floating' | 'inline' | 'sidebar'
    animation: true,
    showIcons: true,
    showShortcuts: true
  }
};

const editor = new EditorView({
  state: EditorState.create({
    extensions: [mcpExtension(mcpConfig)]
  }),
  parent: document.getElementById('editor')
});

Resource Mentions

File References

// Type @ to trigger file mentions
// Example: @src/utils/helpers.js

// Configure file mention behavior
const mcpConfig = {
  resourceMentions: {
    files: {
      enabled: true,
      extensions: ['.js', '.ts', '.jsx', '.tsx', '.py', '.java'],
      excludePaths: ['node_modules', '.git', 'dist'],
      showPreview: true,
      previewLines: 10
    }
  }
};

Function and Class References

// Reference functions and classes
// Example: @calculateTotal() or @UserModel

const mcpConfig = {
  resourceMentions: {
    symbols: {
      enabled: true,
      types: ['function', 'class', 'interface', 'type'],
      showSignature: true,
      showDocumentation: true
    }
  }
};

Documentation References

// Reference documentation
// Example: @docs/api/authentication

const mcpConfig = {
  resourceMentions: {
    documentation: {
      enabled: true,
      sources: [
        { name: 'Internal Docs', url: '/docs' },
        { name: 'API Docs', url: '/api-docs' },
        { name: 'README', url: '/README.md' }
      ],
      showSummary: true
    }
  }
};

Prompt Commands

Built-in Commands

// /explain - Explain selected code
// /refactor - Refactor code
// /generate - Generate code from description
// /document - Generate documentation
// /test - Generate unit tests
// /optimize - Optimize performance

// Usage in editor:
// Select code and type /explain
// Or type /generate followed by description

Custom Commands

const mcpConfig = {
  promptCommands: {
    commands: {
      'translate': {
        description: 'Translate code to another language',
        icon: '🌍',
        handler: async (context) => {
          const { selection, language } = context;
          const response = await mcpClient.callTool('code_translator', {
            code: selection,
            targetLanguage: language
          });
          return response.content[0].text;
        },
        parameters: [
          {
            name: 'language',
            type: 'select',
            options: ['python', 'java', 'javascript', 'rust']
          }
        ]
      },
      'review': {
        description: 'Perform code review',
        icon: '👀',
        handler: async (context) => {
          const response = await mcpClient.callTool('code_reviewer', {
            code: context.selection,
            checkList: ['security', 'performance', 'style']
          });
          return response.content[0].text;
        }
      }
    }
  }
};

Integration Examples

React Integration

import React, { useEffect, useRef } from 'react';
import { EditorView } from '@codemirror/view';
import { EditorState } from '@codemirror/state';
import { javascript } from '@codemirror/lang-javascript';
import { mcpExtension } from 'codemirror-mcp';

function MCPCodeEditor({ value, onChange, mcpConfig }) {
  const editorRef = useRef(null);
  const viewRef = useRef(null);
  
  useEffect(() => {
    if (!editorRef.current) return;
    
    const state = EditorState.create({
      doc: value,
      extensions: [
        javascript(),
        mcpExtension(mcpConfig),
        EditorView.updateListener.of((update) => {
          if (update.docChanged) {
            onChange(update.state.doc.toString());
          }
        })
      ]
    });
    
    viewRef.current = new EditorView({
      state,
      parent: editorRef.current
    });
    
    return () => {
      viewRef.current?.destroy();
    };
  }, []);
  
  return <div ref={editorRef} className="mcp-code-editor" />;
}

export default MCPCodeEditor;

Vue Integration

<template>
  <div ref="editorContainer" class="mcp-editor"></div>
</template>

<script>
import { EditorView } from '@codemirror/view';
import { EditorState } from '@codemirror/state';
import { mcpExtension } from 'codemirror-mcp';

export default {
  name: 'MCPEditor',
  props: {
    modelValue: String,
    mcpConfig: Object
  },
  emits: ['update:modelValue'],
  mounted() {
    this.initEditor();
  },
  beforeUnmount() {
    this.editor?.destroy();
  },
  methods: {
    initEditor() {
      const state = EditorState.create({
        doc: this.modelValue,
        extensions: [
          mcpExtension(this.mcpConfig),
          EditorView.updateListener.of((update) => {
            if (update.docChanged) {
              this.$emit('update:modelValue', update.state.doc.toString());
            }
          })
        ]
      });
      
      this.editor = new EditorView({
        state,
        parent: this.$refs.editorContainer
      });
    }
  }
};
</script>

Svelte Integration

<script>
  import { onMount, onDestroy } from 'svelte';
  import { EditorView } from '@codemirror/view';
  import { EditorState } from '@codemirror/state';
  import { mcpExtension } from 'codemirror-mcp';
  
  export let value = '';
  export let mcpConfig = {};
  
  let editorContainer;
  let editor;
  
  onMount(() => {
    const state = EditorState.create({
      doc: value,
      extensions: [
        mcpExtension(mcpConfig),
        EditorView.updateListener.of((update) => {
          if (update.docChanged) {
            value = update.state.doc.toString();
          }
        })
      ]
    });
    
    editor = new EditorView({
      state,
      parent: editorContainer
    });
  });
  
  onDestroy(() => {
    editor?.destroy();
  });
</script>

<div bind:this={editorContainer} class="mcp-svelte-editor"></div>

Theming and Customization

Custom Themes

/* Custom MCP theme */
.cm-mcp-mention {
  background: #e3f2fd;
  color: #1976d2;
  border-radius: 4px;
  padding: 2px 6px;
  font-weight: 500;
}

.cm-mcp-command {
  background: #f3e5f5;
  color: #7b1fa2;
  border-radius: 4px;
  padding: 2px 6px;
  font-style: italic;
}

.cm-mcp-popup {
  background: white;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  max-height: 300px;
  overflow-y: auto;
}

.cm-mcp-suggestion {
  padding: 8px 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
}

.cm-mcp-suggestion:hover {
  background: #f5f5f5;
}

.cm-mcp-suggestion.selected {
  background: #e3f2fd;
}

Dark Theme Support

import { mcpExtension, MCPTheme } from 'codemirror-mcp';

const editor = new EditorView({
  state: EditorState.create({
    extensions: [
      mcpExtension({
        ui: {
          theme: MCPTheme.dark,
          customCSS: {
            popup: 'background: #2d2d2d; color: white;',
            mention: 'background: #3f51b5; color: white;',
            command: 'background: #9c27b0; color: white;'
          }
        }
      })
    ]
  })
});

API Reference

MCPExtension Options

interface MCPExtensionOptions {
  server: {
    url: string;
    headers?: Record<string, string>;
    timeout?: number;
  };
  resourceMentions?: {
    enabled: boolean;
    trigger: string;
    maxSuggestions: number;
    debounceMs: number;
    categories: string[];
  };
  promptCommands?: {
    enabled: boolean;
    trigger: string;
    commands: Record<string, CommandDefinition>;
  };
  ui?: {
    theme: MCPTheme;
    position: 'floating' | 'inline' | 'sidebar';
    animation: boolean;
    showIcons: boolean;
    showShortcuts: boolean;
  };
}

Events

// Listen to MCP events
editor.dom.addEventListener('mcp:mention', (event) => {
  console.log('Resource mentioned:', event.detail);
});

editor.dom.addEventListener('mcp:command', (event) => {
  console.log('Command executed:', event.detail);
});

editor.dom.addEventListener('mcp:error', (event) => {
  console.error('MCP error:', event.detail);
});

Use Cases

  • Code Editors: Enhance code editors with AI-powered assistance
  • Documentation Platforms: Create interactive documentation with live code examples
  • Educational Tools: Build coding tutorials with contextual help
  • Code Review Tools: Add AI-assisted code review capabilities
  • IDE Extensions: Integrate MCP into existing development environments

Performance Considerations

  • Debouncing: Automatic debouncing for API calls to prevent excessive requests
  • Caching: Intelligent caching of resource metadata and suggestions
  • Lazy Loading: Load resources only when needed
  • Virtual Scrolling: Efficient rendering of large suggestion lists
  • Memory Management: Proper cleanup of event listeners and DOM elements
Sponsored
Algolia Inc logo

Algolia Inc

Supporting the MCP ecosystem with cutting-edge tools and services

Try Algolia MCP