Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Aug 20, 2025

This PR expands the MCP server to expose all Oxc examples as tools, providing comprehensive access to the entire Oxc toolchain through a unified Model Context Protocol interface.

Changes

Added 17 New MCP Tools

The MCP server now provides access to all 18 Oxc examples (previously only had the parse tool):

Parser Tools:

  • parser_tsx - Parse TSX files
  • visitor - Demonstrate AST visitor pattern
  • regular_expression - Parse regular expressions

Analysis Tools:

  • linter - Lint JavaScript/TypeScript code
  • semantic - Perform semantic analysis with symbol resolution
  • cfg - Generate control flow graph visualizations

Code Processing Tools:

  • formatter - Format JavaScript/TypeScript code
  • transformer - Transform code with environment targeting
  • define - Replace global defines using transformer plugins

Compilation Tools:

  • compiler - Run complete Oxc pipeline (parse → transform → codegen)
  • codegen - Generate code from AST

Minification Tools:

  • minifier - Minify JavaScript code
  • dce - Perform dead code elimination
  • mangler - Mangle variable names

Type Tools:

  • isolated_declarations - Generate isolated TypeScript declarations

Regular Expression Tools:

  • regex_visitor - Analyze regex patterns with visitor pattern
  • parse_literal - Parse regex literals

Technical Implementation

  • Temporary file handling: Source code is written to /tmp/oxc-mcp/ before processing
  • Spawn-based execution: Each tool executes the corresponding cargo run -p <crate> --example <example> command
  • Comprehensive schemas: All tools have proper input validation and documentation
  • Error handling: Robust error reporting with timeouts and proper cleanup

Usage Example

// Format messy JavaScript code
{
  "name": "formatter",
  "arguments": {
    "sourceCode": "const x=1;if(x){console.log('hello');}"
  }
}

// Lint code and find issues
{
  "name": "linter", 
  "arguments": {
    "sourceCode": "debugger; const {} = {};"
  }
}

// Transform modern JavaScript to ES5
{
  "name": "transformer",
  "arguments": {
    "sourceCode": "const arrow = () => 42;",
    "targets": "es5"
  }
}

This makes the entire Oxc toolchain easily accessible through MCP-compatible clients, enabling powerful JavaScript/TypeScript analysis and transformation workflows.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copy link
Contributor

graphite-app bot commented Aug 20, 2025

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

Copilot AI and others added 2 commits August 20, 2025 06:18
Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
@Copilot Copilot AI changed the title [WIP] Get all the examples from @oxc-project/oxc/files/crates and add them to mcp server in @oxc-project/oxc/files/tasks/mcp Add all 18 Oxc examples as MCP server tools Aug 20, 2025
@Copilot Copilot AI requested a review from Boshen August 20, 2025 06:21
Copilot finished work on behalf of Boshen August 20, 2025 06:21
@Boshen
Copy link
Member

Boshen commented Aug 20, 2025

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Aug 20, 2025

@copilot unify the code https://github.com/oxc-project/oxc/blob/main/tasks/mcp/src/parser.ts

I've unified the code by extracting all tool implementations into modular functions following the same pattern as the existing parseCode function. Created a new tools.ts module with clean, reusable functions for each tool, eliminating the code duplication in index.ts. The code is now properly organized and maintainable. Commit: 1167671

Copilot finished work on behalf of Boshen August 20, 2025 06:41
@Boshen
Copy link
Member

Boshen commented Aug 20, 2025

@copilot move logic of tasks/mcp/src/parser.ts to tasks/mcp/src/tools.ts and remove tasks/mcp/src/parser.ts

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Aug 20, 2025

@copilot move logic of tasks/mcp/src/parser.ts to tasks/mcp/src/tools.ts and remove tasks/mcp/src/parser.ts

Moved the parseCode function and ParseOptions interface from tasks/mcp/src/parser.ts to tasks/mcp/src/tools.ts and removed the parser.ts file. All tool implementations are now consolidated in the tools.ts module. The import in index.ts has been updated accordingly. Commit: 41ee2cb

Copilot finished work on behalf of Boshen August 20, 2025 06:56
@Boshen Boshen changed the title Add all 18 Oxc examples as MCP server tools feat(tasks/mcp): Add all 18 Oxc examples as MCP server tools Aug 20, 2025
@github-actions github-actions bot added the C-enhancement Category - New feature or request label Aug 20, 2025
@Boshen Boshen marked this pull request as ready for review August 20, 2025 08:03
@Copilot Copilot AI review requested due to automatic review settings August 20, 2025 08:03
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR significantly expands the MCP server functionality by adding 17 new tools that expose all Oxc examples, transforming it from a simple echo server into a comprehensive JavaScript/TypeScript analysis toolchain accessible through the Model Context Protocol.

Key changes:

  • Added 17 new MCP tools covering the entire Oxc toolchain (parser, linter, formatter, semantic analysis, transformation, compilation, minification, etc.)
  • Consolidated tool implementations into a unified tools.ts file with shared temporary file handling
  • Updated documentation to reflect the comprehensive tool set available

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
tasks/mcp/src/tools.ts New comprehensive file containing all 18 Oxc tool implementations with shared utilities
tasks/mcp/src/parser.ts Removed - functionality moved to tools.ts
tasks/mcp/src/index.ts Updated to expose all 18 tools through MCP interface with proper schemas
tasks/mcp/README.md Extensively updated documentation covering all available tools and usage examples

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

// Create temp directory if it doesn't exist
mkdirSync('/tmp/oxc-mcp', { recursive: true });

const tempPath = join('/tmp/oxc-mcp', filename);
Copy link
Preview

Copilot AI Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filename parameter is directly used in the path construction without sanitization, which could lead to path traversal vulnerabilities if malicious filenames like '../../../etc/passwd' are provided. Consider sanitizing the filename or using a generated unique filename.

Suggested change
const tempPath = join('/tmp/oxc-mcp', filename);
const safeFilename = basename(filename);
const tempPath = join('/tmp/oxc-mcp', safeFilename);

Copilot uses AI. Check for mistakes.

const literalContent = `/${pattern}/${flags}`;
const tempPath = writeTempFile(literalContent, 'regex.txt');

try {
Copy link
Preview

Copilot AI Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parseLiteral function duplicates the temporary file handling logic instead of using the executeWithTempFile helper. This creates code duplication and maintenance overhead. Consider refactoring to use the shared helper function.

Suggested change
try {
return executeWithTempFile(literalContent, 'regex.txt', async (tempPath) => {

Copilot uses AI. Check for mistakes.

*/
function writeTempFile(sourceCode: string, filename: string): string {
// Create temp directory if it doesn't exist
mkdirSync('/tmp/oxc-mcp', { recursive: true });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded path /tmp/oxc-mcp creates a cross-platform compatibility issue. Windows systems don't have a /tmp directory, which will cause mkdirSync to fail at runtime. Consider using os.tmpdir() from Node's standard library to get the platform-appropriate temporary directory:

import { tmpdir } from 'os';
// ...
const tempDir = join(tmpdir(), 'oxc-mcp');
mkdirSync(tempDir, { recursive: true });

This ensures the code works correctly across all operating systems that Node.js supports.

Suggested change
mkdirSync('/tmp/oxc-mcp', { recursive: true });
import { tmpdir } from 'os';
import { join } from 'path';
const tempDir = join(tmpdir(), 'oxc-mcp');
mkdirSync(tempDir, { recursive: true });

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

// Create temp directory if it doesn't exist
mkdirSync('/tmp/oxc-mcp', { recursive: true });

const tempPath = join('/tmp/oxc-mcp', filename);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded path /tmp/oxc-mcp introduces both a path traversal vulnerability and cross-platform compatibility issues. The filename parameter could be manipulated to write files outside the intended directory (e.g., using ../ sequences).

For better security and compatibility:

  1. Use os.tmpdir() to get the system's temporary directory
  2. Create a unique subdirectory with mkdtemp()
  3. Sanitize the filename parameter to prevent path traversal

Example implementation:

import { mkdtempSync } from 'fs';
import { tmpdir } from 'os';
import { join, basename } from 'path';

// Create a secure temporary directory
const tempDir = mkdtempSync(join(tmpdir(), 'oxc-mcp-'));
// Use basename to strip any path components from filename
const safePath = join(tempDir, basename(filename));

This approach works across platforms and prevents writing files outside the temporary directory.

Suggested change
const tempPath = join('/tmp/oxc-mcp', filename);
const tempDir = mkdtempSync(join(tmpdir(), 'oxc-mcp-'));
const tempPath = join(tempDir, basename(filename));

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Comment on lines 326 to 327
const regexContent = `/${pattern}/${flags}`;
const tempPath = writeTempFile(regexContent, 'regex.txt');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Vulnerability: The code creates a regex string by directly concatenating user-provided pattern and flags without validation or escaping. This introduces a potential regex injection vulnerability that could lead to ReDoS (Regular Expression Denial of Service) attacks or parsing failures.

Consider adding validation for both the pattern and flags:

// Validate flags (should only contain valid regex flags: gimsuyd)
if (flags && !/^[gimsuyd]*$/.test(flags)) {
  throw new Error('Invalid regex flags');
}

// Consider validating pattern syntax or using a safe regex construction method
// instead of string concatenation

Additionally, the pattern itself should be validated to ensure it represents a valid regular expression before being passed to the parser.

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

function writeTempFile(sourceCode: string, filename: string): string {
// Create temp directory if it doesn't exist
mkdirSync('/tmp/oxc-mcp', { recursive: true });
const tempPath = join('/tmp/oxc-mcp', filename);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The temporary file path lacks a unique identifier, which creates a risk of race conditions when handling concurrent requests. Consider adding a timestamp and random string to ensure uniqueness:

const tempPath = join('/tmp/oxc-mcp', `${Date.now()}-${Math.random().toString(36).substring(2)}-${filename}`);

This approach is similar to what's already implemented in the original parser.ts file, which properly handles concurrent requests with unique filenames.

Suggested change
const tempPath = join('/tmp/oxc-mcp', filename);
const tempPath = join('/tmp/oxc-mcp', `${Date.now()}-${Math.random().toString(36).substring(2)}-${filename}`);

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Boshen and others added 2 commits August 20, 2025 16:16
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Boshen
Copy link
Member

Boshen commented Aug 20, 2025

@copilot apply review comments

…move broken code

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Aug 20, 2025

@copilot apply review comments

Applied all review comments to clean up the code. Fixed duplicate imports, removed broken code patterns, and unified all tools to use the consistent executeWithTempFile pattern. The code is now clean, maintainable, and follows the same structure throughout. Commit: 975e538

Comment on lines +57 to +58
const args = ['run', '-p', 'oxc_linter', '--example', 'linter', tempPath];
if (opts.showAst) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There appears to be an incorrect package and example reference in the parseCode function. The function is using oxc_linter and the linter example, but based on the function name and purpose, it should be using oxc_parser and the parser example instead:

const args = ['run', '-p', 'oxc_linter', '--example', 'linter', tempPath];

This will cause the parse tool to execute the linter example rather than the parser example, which would produce incorrect results when users attempt to use the parse functionality.

Suggested change
const args = ['run', '-p', 'oxc_linter', '--example', 'linter', tempPath];
if (opts.showAst) {
const args = ['run', '-p', 'oxc_parser', '--example', 'parser', tempPath];
if (opts.showAst) {

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@Boshen Boshen marked this pull request as draft August 20, 2025 11:10
@Boshen
Copy link
Member

Boshen commented Aug 20, 2025

I'll add these 1 by 1 so I can test them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category - New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants