You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "ASF GitHub Bot (Jira)" <ji...@apache.org> on 2026/10/24 04:25:00 UTC
[jira] [Commented] (GROOVY-12487) Add an optional MCP server
[ https://issues.apache.org/jira/browse/GROOVY-12487?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18131294#comment-18131294 ]
ASF GitHub Bot commented on GROOVY-12487:
-----------------------------------------
daniellansun opened a new pull request, #3021:
URL: https://github.com/apache/groovy/pull/3021
https://issues.apache.org/jira/browse/GROOVY-12487
> Add an optional MCP server
> --------------------------
>
> Key: GROOVY-12487
> URL: https://issues.apache.org/jira/browse/GROOVY-12487
> Project: Groovy
> Issue Type: New Feature
> Reporter: Daniel Sun
> Priority: Major
>
> An agent needs to ask the Groovy compiler about source without running that source. {{groovy-mcp}} is an optional subproject that speaks the Model Context Protocol (MCP) over stdio. It calls the existing {{GroovyLanguageEngine}} in {{groovy-lsp}}. It is not a second compiler, and it is not part of {{groovy-all}}.
> h3. Launch
> {noformat}
> groovymcp [--stdio] [--root DIR] [--classpath PATH] [--version] [--help]
> {noformat}
> * {{--stdio}} is accepted and changes nothing. Stdio is the only transport.
> * {{--root}} confines every {{path}} argument to that directory. The directory is not scanned. Without it, {{path}} is rejected and in-memory {{text}} still works.
> * {{--classpath}} is the compile classpath. It is fixed at launch. A tool call cannot change it, and the server reports the entry count, not the paths.
> * {{--help}} wins over later arguments and exits 0. {{--version}} prints {{groovy-mcp}} and the implementation version.
> Stdout is the protocol stream. Server logs go to stderr. {{main}} redirects incidental standard output to stderr only while the process is serving, and restores it afterwards.
> h3. Protocol
> One JSON-RPC 2.0 message is one UTF-8 line. A JSON array (a batch) is rejected. CRLF is one line; the CR is not part of the payload and does not count toward the message cap.
> Supported protocol versions are {{2025-11-25}}, {{2025-06-18}}, {{2025-03-26}}, and {{2024-11-05}}. A supported version is echoed. Any other non-empty version is answered as {{2025-11-25}}.
> A session must {{initialize}}, then send {{notifications/initialized}}, before tools, resources, or prompts answer. {{ping}} is allowed earlier. A second {{initialize}} is an error. Requests before the session is ready return {{-32002}}.
> * A tool mistake, including an unknown tool, is a successful response with {{isError}} set. The unknown-tool text is the constant {{unknown tool}}. The name from the request is not repeated.
> * An unknown resource, an unknown prompt, or an argument value that is not an object returns {{-32602}}.
> * An unexpected failure is {{-32603}} with the message {{Internal error}}. The log records the exception class and a short message, not the source text.
> * {{notifications/cancelled}} is ignored. The session handles one request at a time, and a compile is not interrupted.
> Tool input and output schemas use JSON Schema 2020-12. Each tool has a title and an {{outputSchema}}. A successful {{structuredContent}} matches that schema. A failed call's {{structuredContent}} is an {{error}} string.
> h3. What the server exposes
> Thirteen read-only tools wrap the engine: diagnostics, describe, definition, implementations, references, symbols, complete, signatures, tokens, format, organize-imports, rename, and close. Format, organize-imports, and rename return edits. They do not write files. An empty rename means the compiler did not prove the binding.
> Positions are 0-based UTF-16 and are passed through unchanged.
> Source is passed in one of three ways:
> * {{text}} keeps the source in a {{groovy-buffer}} URI. The default is {{groovy-buffer:snippet}}. {{text}} may also carry a {{uri}} of that scheme. It is not attached to a file URI.
> * {{path}} reads one file under {{--root}}.
> * {{uri}} addresses a buffer that is already open. A file URI must stay inside the root, including the path after symbolic links are resolved.
> {{text}} together with {{path}} is rejected, and so is {{path}} together with {{uri}}.
> Three JSON resources list the lexer keywords, the default imports, and the server limits. The keyword list and the default imports come from the compiler. Two prompts, {{explain-groovy}} and {{review-groovy}}, tell the model to use those tools and not to run the source. The server does not treat the prompt text as instructions to itself.
> h3. Limits and safety
> Defaults are 2 MiB for one message, 512 Ki characters of source, and 512 Ki characters of result JSON. Oversized tool JSON is replaced with an error result. Client strings that must be quoted are shortened, and control characters are replaced.
> There is no evaluate tool. Grab and ASTTest stay disabled. The process does not walk a workspace, invoke Gradle or Maven, or download dependencies. Sampling, elicitation, tasks, and HTTP transports are not implemented. The module does not depend on an MCP library or an LLM client library. JSON is parsed and written with {{groovy.json}}.
> h3. Build
> The module is optional. Binary-compatibility checks are off until a release has published a baseline jar, as with {{groovy-lsp}}. The jar's main class is {{org.apache.groovy.mcp.GroovyMcpLauncher}}. The binary distribution ships the jar, {{groovymcp}}, and {{groovymcp.bat}}. Both scripts are force-added because {{bin/}} is ignored, the same way {{groovylsp}} is tracked. The user guide is included from the binary documentation.
> The public types are {{GroovyMcpServer}}, {{GroovyMcpLauncher}}, and {{McpServerConfig}}. Types under {{org.apache.groovy.mcp.internal}} are not a supported API.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)