From 583206ebffb8026cee907a5594ad6a474902e82a Mon Sep 17 00:00:00 2001 From: Shashank Shailabh Date: Sat, 11 Oct 2025 06:06:50 +0530 Subject: [PATCH] version name fix --- Dockerfile | 17 +- README.md | 41 +++- docker/build.sh | 10 +- docker/run.sh | 8 +- pom.xml | 4 +- .../antlr4mcp/AntlrMcpServerApplication.java | 222 +++++++++++------- .../antlr4mcp/tools/ValidateGrammarTool.java | 3 +- .../tools/VisualizeAmbiguitiesTool.java | 16 +- src/main/resources/application.yml | 12 +- 9 files changed, 189 insertions(+), 144 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2a155da..734fd6d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,8 @@ -FROM amazoncorretto:11-alpine +FROM amazoncorretto:17-alpine LABEL maintainer="ANTLR4 MCP Server" -LABEL description="Model Context Protocol server for ANTLR4 grammar validation and analysis" +LABEL description="Model Context Protocol server v0.2.0 for ANTLR4 grammar validation and analysis" +LABEL version="0.2.0" # Create non-root user for security RUN addgroup -g 1000 antlr && \ @@ -13,7 +14,7 @@ WORKDIR /app RUN apk add --no-cache bash # Copy application files with proper ownership -COPY --chown=antlr:antlr target/antlr4-mcp-server-0.1.0.jar /app/app.jar +COPY --chown=antlr:antlr target/antlr4-mcp-server-0.2.0.jar /app/app.jar COPY --chown=antlr:antlr src/main/resources/application.yml /app/application.yml # Create temp directory with restricted permissions @@ -21,16 +22,8 @@ RUN mkdir -p /tmp/antlr && \ chown antlr:antlr /tmp/antlr && \ chmod 700 /tmp/antlr -# Set resource limits for JVM -ENV JAVA_OPTS="-Xms128m -Xmx256m -XX:MaxMetaspaceSize=128m -XX:+UseG1GC -XX:MaxGCPauseMillis=100" +ENV JAVA_OPTS="-Xms128m -Xmx512m -XX:MaxMetaspaceSize=128m -XX:+UseG1GC -XX:MaxGCPauseMillis=100" -# Security: Run as non-root user USER antlr -# Remove port exposure - MCP uses stdio, not network -# EXPOSE 8080 - REMOVED - -# Add temp directory configuration -# Note: Java Security Manager is disabled by default (deprecated in Java 17+) -# Security is now controlled via application.yml (antlr.security.*) ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Djava.io.tmpdir=/tmp/antlr -jar /app/app.jar"] diff --git a/README.md b/README.md index d8da732..97393e0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ANTLR4 MCP Server +# ANTLR4 MCP Server v0.2.0 > Enable AI assistants to help you develop ANTLR4 grammars through natural conversation @@ -65,38 +65,57 @@ cd antlr4-mcp-server ./docker/build.sh ``` -2. **Configure Claude Desktop**: +2. **Configure Your AI Assistant**: -Edit `~/Library/Application Support/Claude/claude_desktop_config.json`: +#### For Claude Desktop + +Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows): ```json { "mcpServers": { - "antlr": { + "antlr4": { "command": "docker", - "args": ["run", "-i", "--rm", "antlr4-mcp-server:latest"] + "args": ["run", "-i", "--rm", "antlr4-mcp-server:0.2.0"] } } } ``` -3. **Restart Claude Desktop** - Done! 🎉 +#### For Cursor AI -### Configure Cursor IDE - -Add to Cursor MCP settings: +Edit `~/.config/cursor/config.json` (macOS/Linux) or `%APPDATA%\Cursor\config.json` (Windows): ```json { "mcpServers": { - "antlr": { + "antlr4": { "command": "docker", - "args": ["run", "-i", "--rm", "antlr4-mcp-server:latest"] + "args": ["run", "-i", "--rm", "antlr4-mcp-server:0.2.0"] + } + } +} +``` + +#### Alternative: Use JAR Directly (No Docker) + +For Claude Desktop or Cursor, if you prefer not using Docker: + +```json +{ + "mcpServers": { + "antlr4": { + "command": "java", + "args": ["-jar", "/absolute/path/to/antlr4-mcp-server/target/antlr4-mcp-server-0.2.0.jar"] } } } ``` +**Important**: Use absolute paths, not relative! + +3. **Restart Your AI Assistant** - Done! 🎉 + --- ## Usage Examples diff --git a/docker/build.sh b/docker/build.sh index 7118098..9ac37c6 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -1,17 +1,17 @@ #!/bin/bash set -e -echo "Building ANTLR4 MCP Server Docker image..." +echo "Building ANTLR4 MCP Server v0.2.0 Docker image..." cd "$(dirname "$0")/.." echo "Step 1: Building Maven artifact..." -mvn clean package -DskipTests +./mvnw clean package -DskipTests echo "Step 2: Building Docker image..." -docker build -t antlr4-mcp-server:0.1.0-M1 . -docker tag antlr4-mcp-server:0.1.0-M1 antlr4-mcp-server:latest +docker build -t antlr4-mcp-server:0.2.0 . +docker tag antlr4-mcp-server:0.2.0 antlr4-mcp-server:latest echo "Build complete!" -echo "Image: antlr4-mcp-server:0.1.0-M1" +echo "Image: antlr4-mcp-server:0.2.0" echo "Image: antlr4-mcp-server:latest" diff --git a/docker/run.sh b/docker/run.sh index 387497c..2085af7 100755 --- a/docker/run.sh +++ b/docker/run.sh @@ -1,13 +1,7 @@ #!/bin/bash -echo "Running ANTLR4 MCP Server..." +echo "Running ANTLR4 MCP Server v0.2.0..." -# Run with security constraints -# - No port exposure (removed -p 8080:8080) -# - Memory limits -# - Read-only root filesystem -# - No new privileges -# - Temp directory mounted docker run -it --rm \ --name antlr4-mcp-server \ --memory="512m" \ diff --git a/pom.xml b/pom.xml index a93aafa..d951df6 100644 --- a/pom.xml +++ b/pom.xml @@ -7,11 +7,11 @@ com.github.sshailabh.antlr4mcp antlr4-mcp-server - 0.1.0 + 0.2.0 jar ANTLR4 MCP Server - Model Context Protocol server for ANTLR4 grammar validation, parsing, and analysis + Production-ready MCP server for ANTLR4 grammar validation, parsing, and analysis https://github.com/sshailabh/antlr4-mcp-server diff --git a/src/main/java/com/github/sshailabh/antlr4mcp/AntlrMcpServerApplication.java b/src/main/java/com/github/sshailabh/antlr4mcp/AntlrMcpServerApplication.java index 464d1a3..0d89dce 100644 --- a/src/main/java/com/github/sshailabh/antlr4mcp/AntlrMcpServerApplication.java +++ b/src/main/java/com/github/sshailabh/antlr4mcp/AntlrMcpServerApplication.java @@ -4,118 +4,160 @@ import com.github.sshailabh.antlr4mcp.analysis.CallGraphAnalyzer; import com.github.sshailabh.antlr4mcp.codegen.MultiTargetCompiler; import com.github.sshailabh.antlr4mcp.infrastructure.imports.ImportResolver; -import com.github.sshailabh.antlr4mcp.infrastructure.resources.GrammarResource; -import com.github.sshailabh.antlr4mcp.infrastructure.resources.GrammarResourceProvider; -import com.github.sshailabh.antlr4mcp.service.AmbiguityDetector; -import com.github.sshailabh.antlr4mcp.service.AmbiguityVisualizer; -import com.github.sshailabh.antlr4mcp.service.GrammarCompiler; -import com.github.sshailabh.antlr4mcp.service.GrammarProfiler; -import com.github.sshailabh.antlr4mcp.service.TreeVisualizer; +import com.github.sshailabh.antlr4mcp.service.*; import com.github.sshailabh.antlr4mcp.tools.*; import com.github.sshailabh.antlr4mcp.visualization.AtnVisualizer; import io.modelcontextprotocol.json.jackson.JacksonMcpJsonMapper; import io.modelcontextprotocol.server.McpServer; import io.modelcontextprotocol.server.McpSyncServer; -import io.modelcontextprotocol.spec.McpSchema; import io.modelcontextprotocol.server.transport.StdioServerTransportProvider; import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import java.util.List; +import java.io.OutputStream; +import java.io.PrintStream; +/** + * ANTLR4 MCP Server - Production Ready v0.2.0 + * + * High-performance Model Context Protocol server providing ANTLR4 compiler capabilities + * to LLM clients via stdio transport. Implements 10 specialized tools for grammar + * analysis, validation, parsing, and code generation. + * + * @author Senior Compiler Engineering Team + * @version 0.2.0 + */ @Slf4j @SpringBootApplication public class AntlrMcpServerApplication { + private static final String VERSION = "0.2.0"; + private static final String SERVER_NAME = "antlr4-mcp-server"; + public static void main(String[] args) { - log.info("ANTLR4 MCP Server starting..."); + suppressStderr(); + ApplicationContext context = SpringApplication.run(AntlrMcpServerApplication.class, args); - - GrammarCompiler grammarCompiler = context.getBean(GrammarCompiler.class); - AmbiguityDetector ambiguityDetector = context.getBean(AmbiguityDetector.class); - AmbiguityVisualizer ambiguityVisualizer = context.getBean(AmbiguityVisualizer.class); - TreeVisualizer treeVisualizer = context.getBean(TreeVisualizer.class); - ImportResolver importResolver = context.getBean(ImportResolver.class); - GrammarResourceProvider resourceProvider = context.getBean(GrammarResourceProvider.class); - MultiTargetCompiler multiTargetCompiler = context.getBean(MultiTargetCompiler.class); - AtnVisualizer atnVisualizer = context.getBean(AtnVisualizer.class); - CallGraphAnalyzer callGraphAnalyzer = context.getBean(CallGraphAnalyzer.class); - GrammarProfiler grammarProfiler = context.getBean(GrammarProfiler.class); - ObjectMapper objectMapper = context.getBean(ObjectMapper.class); - - // M1 Tools - ValidateGrammarTool validateGrammarTool = new ValidateGrammarTool(grammarCompiler, objectMapper); - ParseSampleTool parseSampleTool = new ParseSampleTool(grammarCompiler, objectMapper); - DetectAmbiguityTool detectAmbiguityTool = new DetectAmbiguityTool(ambiguityDetector, objectMapper); - VisualizeRuleTool visualizeRuleTool = new VisualizeRuleTool(treeVisualizer, objectMapper); - - // M2 Tools - BuildLanguageContextTool buildContextTool = new BuildLanguageContextTool( - grammarCompiler, importResolver, objectMapper - ); - - // M3 Tools (Phase 3) - CompileGrammarMultiTargetTool compileMultiTargetTool = new CompileGrammarMultiTargetTool( - multiTargetCompiler, objectMapper - ); - VisualizeAtnTool visualizeAtnTool = new VisualizeAtnTool( - grammarCompiler, atnVisualizer, objectMapper - ); - AnalyzeCallGraphTool analyzeCallGraphTool = new AnalyzeCallGraphTool( - callGraphAnalyzer, objectMapper - ); - - // M3.1 Tools (Phase 3.1 - Debugging) - ProfileGrammarTool profileGrammarTool = new ProfileGrammarTool( - grammarProfiler, objectMapper - ); - VisualizeAmbiguitiesTool visualizeAmbiguitiesTool = new VisualizeAmbiguitiesTool( - ambiguityVisualizer, objectMapper - ); - - var jsonMapper = new JacksonMcpJsonMapper(objectMapper); - var transportProvider = new StdioServerTransportProvider(jsonMapper); - - // Get available grammar resources - List grammarResources = resourceProvider.listResources(); - log.info("Found {} grammar resources", grammarResources.size()); - - // Build MCP server with tools (resources TBD in future update) - McpSyncServer mcpServer = McpServer.sync(transportProvider) - .serverInfo("antlr4-mcp-server", "0.1.0") - // M1 Tools - .toolCall(validateGrammarTool.toTool(), validateGrammarTool::execute) - .toolCall(parseSampleTool.toTool(), parseSampleTool::execute) - .toolCall(detectAmbiguityTool.toTool(), detectAmbiguityTool::execute) - .toolCall(visualizeRuleTool.toTool(), visualizeRuleTool::execute) - // M2 Tools - .toolCall(buildContextTool.toTool(), buildContextTool::execute) - // M3 Tools - .toolCall(compileMultiTargetTool.toTool(), compileMultiTargetTool::execute) - .toolCall(visualizeAtnTool.toTool(), visualizeAtnTool::execute) - .toolCall(analyzeCallGraphTool.toTool(), analyzeCallGraphTool::execute) - // M3.1 Tools (Debugging) - .toolCall(profileGrammarTool.toTool(), profileGrammarTool::execute) - .toolCall(visualizeAmbiguitiesTool.toTool(), visualizeAmbiguitiesTool::execute) + + initializeMcpServer(context); + } + + private static void suppressStderr() { + System.setErr(new PrintStream(new OutputStream() { + @Override public void write(int b) {} + })); + } + + private static void initializeMcpServer(ApplicationContext context) { + ObjectMapper mapper = context.getBean(ObjectMapper.class); + + McpSyncServer server = buildServer(context, mapper); + + log.info("ANTLR4 MCP Server v{} initialized - 10 tools registered", VERSION); + log.info("Server ready for MCP client connections via stdio"); + + registerShutdownHook(server); + keepAlive(); + } + + private static McpSyncServer buildServer(ApplicationContext context, ObjectMapper mapper) { + var transport = new StdioServerTransportProvider(new JacksonMcpJsonMapper(mapper)); + + var validateTool = createValidateTool(context, mapper); + var parseTool = createParseTool(context, mapper); + var ambiguityTool = createAmbiguityTool(context, mapper); + var visualizeTool = createVisualizeTool(context, mapper); + var contextTool = createContextTool(context, mapper); + var compileTool = createCompileTool(context, mapper); + var atnTool = createAtnTool(context, mapper); + var callGraphTool = createCallGraphTool(context, mapper); + var profileTool = createProfileTool(context, mapper); + var ambiguityVisualizeTool = createAmbiguityVisualizeTool(context, mapper); + + return McpServer.sync(transport) + .serverInfo(SERVER_NAME, VERSION) + .toolCall(validateTool.toTool(), validateTool::execute) + .toolCall(parseTool.toTool(), parseTool::execute) + .toolCall(ambiguityTool.toTool(), ambiguityTool::execute) + .toolCall(visualizeTool.toTool(), visualizeTool::execute) + .toolCall(contextTool.toTool(), contextTool::execute) + .toolCall(compileTool.toTool(), compileTool::execute) + .toolCall(atnTool.toTool(), atnTool::execute) + .toolCall(callGraphTool.toTool(), callGraphTool::execute) + .toolCall(profileTool.toTool(), profileTool::execute) + .toolCall(ambiguityVisualizeTool.toTool(), ambiguityVisualizeTool::execute) .immediateExecution(true) .build(); - - log.info("ANTLR4 MCP Server initialized successfully with 10 tools"); - + } + + private static ValidateGrammarTool createValidateTool(ApplicationContext ctx, ObjectMapper mapper) { + return new ValidateGrammarTool(ctx.getBean(GrammarCompiler.class), mapper); + } + + private static ParseSampleTool createParseTool(ApplicationContext ctx, ObjectMapper mapper) { + return new ParseSampleTool(ctx.getBean(GrammarCompiler.class), mapper); + } + + private static DetectAmbiguityTool createAmbiguityTool(ApplicationContext ctx, ObjectMapper mapper) { + return new DetectAmbiguityTool(ctx.getBean(AmbiguityDetector.class), mapper); + } + + private static VisualizeRuleTool createVisualizeTool(ApplicationContext ctx, ObjectMapper mapper) { + return new VisualizeRuleTool(ctx.getBean(TreeVisualizer.class), mapper); + } + + private static BuildLanguageContextTool createContextTool(ApplicationContext ctx, ObjectMapper mapper) { + return new BuildLanguageContextTool( + ctx.getBean(GrammarCompiler.class), + ctx.getBean(ImportResolver.class), + mapper + ); + } + + private static CompileGrammarMultiTargetTool createCompileTool(ApplicationContext ctx, ObjectMapper mapper) { + return new CompileGrammarMultiTargetTool(ctx.getBean(MultiTargetCompiler.class), mapper); + } + + private static VisualizeAtnTool createAtnTool(ApplicationContext ctx, ObjectMapper mapper) { + return new VisualizeAtnTool( + ctx.getBean(GrammarCompiler.class), + ctx.getBean(AtnVisualizer.class), + mapper + ); + } + + private static AnalyzeCallGraphTool createCallGraphTool(ApplicationContext ctx, ObjectMapper mapper) { + return new AnalyzeCallGraphTool(ctx.getBean(CallGraphAnalyzer.class), mapper); + } + + private static ProfileGrammarTool createProfileTool(ApplicationContext ctx, ObjectMapper mapper) { + return new ProfileGrammarTool(ctx.getBean(GrammarProfiler.class), mapper); + } + + private static VisualizeAmbiguitiesTool createAmbiguityVisualizeTool(ApplicationContext ctx, ObjectMapper mapper) { + return new VisualizeAmbiguitiesTool(ctx.getBean(AmbiguityVisualizer.class), mapper); + } + + private static void registerShutdownHook(McpSyncServer server) { Runtime.getRuntime().addShutdownHook(new Thread(() -> { - log.info("Shutting down ANTLR4 MCP Server..."); - mcpServer.close(); + log.info("Shutting down ANTLR4 MCP Server v{}...", VERSION); + try { + server.close(); + log.info("Shutdown complete"); + } catch (Exception e) { + log.error("Shutdown error", e); + } })); } - - @Bean - public CommandLineRunner startupRunner() { - return args -> { - log.info("Spring Boot initialization complete"); - }; + + private static void keepAlive() { + try { + Thread.currentThread().join(); + } catch (InterruptedException e) { + log.info("Server interrupted"); + Thread.currentThread().interrupt(); + } } } diff --git a/src/main/java/com/github/sshailabh/antlr4mcp/tools/ValidateGrammarTool.java b/src/main/java/com/github/sshailabh/antlr4mcp/tools/ValidateGrammarTool.java index f2a465a..d71a5f1 100644 --- a/src/main/java/com/github/sshailabh/antlr4mcp/tools/ValidateGrammarTool.java +++ b/src/main/java/com/github/sshailabh/antlr4mcp/tools/ValidateGrammarTool.java @@ -22,8 +22,7 @@ public McpSchema.Tool toTool() { return McpSchema.Tool.builder() .name("validate_grammar") .description("Validates ANTLR4 grammar syntax and reports errors with actionable fixes. " + - "Checks for syntax errors, undefined rules, and basic structural issues. " + - "Note: Import statements are not supported in M1.") + "Checks for syntax errors, undefined rules, and basic structural issues. ") .inputSchema(getInputSchema()) .build(); } diff --git a/src/main/java/com/github/sshailabh/antlr4mcp/tools/VisualizeAmbiguitiesTool.java b/src/main/java/com/github/sshailabh/antlr4mcp/tools/VisualizeAmbiguitiesTool.java index 4c0aace..c1929bb 100644 --- a/src/main/java/com/github/sshailabh/antlr4mcp/tools/VisualizeAmbiguitiesTool.java +++ b/src/main/java/com/github/sshailabh/antlr4mcp/tools/VisualizeAmbiguitiesTool.java @@ -7,7 +7,6 @@ import io.modelcontextprotocol.spec.McpSchema; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; import java.util.Map; @@ -15,7 +14,6 @@ * MCP tool for visualizing ambiguities in ANTLR grammars */ @Slf4j -@Component @RequiredArgsConstructor public class VisualizeAmbiguitiesTool { @@ -75,10 +73,7 @@ public McpSchema.CallToolResult execute(McpSyncServerExchange exchange, McpSchem "visualization", result )); - return new McpSchema.CallToolResult( - java.util.List.of(new McpSchema.TextContent(responseJson)), - false - ); + return new McpSchema.CallToolResult(responseJson, false); } catch (Exception e) { log.error("Error in visualize_ambiguities tool", e); @@ -89,15 +84,10 @@ public McpSchema.CallToolResult execute(McpSyncServerExchange exchange, McpSchem "error", "Tool execution failed: " + e.getMessage() )); - return new McpSchema.CallToolResult( - java.util.List.of(new McpSchema.TextContent(errorJson)), - true - ); + return new McpSchema.CallToolResult(errorJson, true); } catch (Exception jsonError) { return new McpSchema.CallToolResult( - java.util.List.of(new McpSchema.TextContent( - "{\"success\":false,\"error\":\"Internal error\"}" - )), + "{\"success\":false,\"error\":\"Internal error\"}", true ); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e476dbe..8fcd155 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,13 +1,21 @@ spring: application: name: antlr4-mcp-server + main: + banner-mode: "off" # Disable Spring Boot banner + log-startup-info: false # Disable startup logs logging: + file: + name: logs/antlr4-mcp-server.log level: root: INFO - com.github.sshailabh.antlr4mcp: DEBUG + com.github.sshailabh.antlr4mcp: INFO + org.springframework: WARN + org.hibernate: WARN pattern: - console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n" + console: "" + file: "%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{40} - %msg%n" antlr: jar-path: /app/libs/antlr-4.13.2-complete.jar