ruthst00 commented on issue #15591:
URL: https://github.com/apache/grails-core/issues/15591#issuecomment-6572878151
# One Potential Approach
My interpretation of this ask is: **let AI coding clients discover and use
Grails development capabilities through MCP**, rather than requiring them to
guess shell commands and parse terminal output.
This is different from adding AI features—or an MCP endpoint—to a Grails
application. Please let me know if I am misrepresenting the requirements of
this proposal.
## Recommended approach
**Build a local, opt-in MCP server as a thin adapter over existing Grails
tooling.** Start with project discovery and a small set of explicit tools, not
an unrestricted command executor.
The architecture might look like:
```text
AI coding client
│ MCP over stdio
▼
Grails development MCP server
├── Project information and conventions
├── Approved generation commands → Grails shell / Forge
└── Approved test operations → Gradle
```
No LLM provider or API key is needed on the server: the coding client
supplies the intelligence.
### 1. Keep the protocol layer separate
I would lean toward a dedicated tooling module/artifact, with a launcher
command such as:
```text
grails mcp --project /absolute/path/to/application
```
That command is a **proposed interface**, not something currently available.
A separate module would keep MCP dependencies and lifecycle management out
of normal application runtime dependencies. Use an established MCP SDK rather
than implementing JSON-RPC and protocol negotiation manually. The [official
Java SDK](https://modelcontextprotocol.io/docs/sdk) is a natural candidate;
Spring AI’s MCP support is another option to evaluate against dependency
compatibility and startup cost.
The repository already manages Spring AI through its BOM, but that alone is
not a reason to load the application AI stack into a developer tool.
### 2. Start with stdio, not an HTTP service
A local process launched by the coding client is the simplest initial
deployment:
- No listening port or remote authentication to manage.
- Explicit project directory.
- Process lifetime tied to the client.
- Straightforward IDE integration.
**Stdout would contain only MCP messages.** Banners, logging, progress
output, and child-command output would go to stderr or be captured into tool
results. This needs deliberate handling because existing CLI code is
terminal-oriented.
### 3. Expose a small, typed tool surface
A useful first release could offer:
| Capability | Suggested behavior |
|---|---|
| Project information | Report Grails version, project layout, and detected
tooling |
| Available generators | List supported generation operations and their
arguments |
| Generate an artifact | Generate an explicitly supported controller,
service, domain class, etc. |
| Run tests | Execute a bounded test operation and return a structured
summary |
Tools should have explicit input schemas and structured results—for example,
generated file paths, exit status, test counts, and bounded diagnostic output.
Version-matched documentation and Grails conventions could subsequently be
exposed as MCP resources or searchable tools. Existing agent skills would
complement this: **skills explain how to develop; MCP provides executable
capabilities.**
I would defer application startup/shutdown, arbitrary Gradle tasks, database
access, and unrestricted shell commands.
## Where existing code can be reused
There are two tooling paths to account for, however if/when [these two CLIs
are merged or
consolidated](https://github.com/apache/grails-core/issues/16348), then the
solution will need to take this into account:
- The shell CLI has command discovery, execution contexts, and Gradle
integration under [`grails-shell-cli`]( grails-core/grails-shell-cli).
- Forge has application and artefact generation under [`grails-forge`](
grails-core/grails-forge), and its launcher delegates between Forge and the
shell.
Two implementation details matter:
1. **Do not assume every discovered command should become an MCP tool.**
Shell command discovery includes extensible project/profile commands; those can
execute developer-authored code. Use an explicit allowlist and typed adapters.
2. **Avoid embedding the interactive CLI unchanged in a long-lived server.**
It has static state and console-oriented behavior. Prefer reusable services
where practical, or isolated child processes initially, with captured output
and serialized mutations per project.
Also, Forge is a separate Gradle build. The module location and dependency
direction should be settled before connecting both CLI implementations.
## Safety and testing
The server would have the developer’s filesystem permissions, so its
boundaries should be explicit:
- Confine writes to the selected workspace, accounting for symlinks.
- Refuse overwrites by default.
- Never interpolate tool input into shell command strings.
- Require explicit enablement for mutating or build-executing tools.
- Apply timeouts, cancellation, output limits, and child-process cleanup.
- Explain that running Gradle executes project code—it is not sandboxed.
Tests should exercise the **actual MCP interface**, not just handler
methods: initialization, discovery, tool calls, malformed inputs, clean stdout,
generation in temporary projects, overwrite refusal, and cancellation. Add
client setup and capability documentation to `grails-doc`.
## How we might split the work
1. **Agree on scope:** local development server, target Grails versions,
initial tools, and module ownership.
2. **Protocol foundation:** stdio launcher, project context, discovery, and
process-level tests.
3. **Generation:** a few allowlisted adapters using existing generators.
4. **Test execution:** bounded Gradle operations and structured results.
5. **Documentation/resources:** version-aware guidance and broader
capabilities.
**Recommendation:** make the first PR a small end-to-end slice—**stdio
server + project information + one generator + real MCP-client tests**. That
validates the architecture without turning this underspecified issue into a
large tooling rewrite.
## How is MCP different from using an AI API Provider (e.g., Cline) and LLM
from inside IntelliJ? What are the advantages?
They operate at different layers. **An MCP server would complement Cline in
IntelliJ, not replace it.**
One terminology distinction: Cline is the coding agent; its **API provider**
supplies the model it talks to. IntelliJ is the development environment. An MCP
server supplies additional tools and context that the agent can use.
```text
IntelliJ
└── Cline
├── API provider → model that reasons about your task
├── Built-in tools → read/edit files, search, run commands
└── Grails MCP server → Grails-specific tools and context
```
## What changes in practice?
Cline can already develop Grails applications using files, instructions, and
shell commands. **MCP does not unlock something fundamentally impossible
today.** Its potential advantage is making common Grails operations more
reliable, structured, and reusable.
For example:
| Task | Cline with normal tools | With a well-designed Grails MCP server |
|---|---|---|
| Understand the project | Read build files and infer versions/layout |
Request a consistent project summary |
| Generate a controller | Determine the correct CLI command and execute it |
Call a typed generation tool with validated arguments |
| Run relevant tests | Construct a Gradle command and interpret output |
Request a test operation and receive structured results |
| Find applicable guidance | Search documentation and choose the correct
version | Retrieve version-matched Grails guidance |
| Diagnose a failure | Read logs and test reports | Receive normalized
failures with report/file references |
These MCP capabilities are **proposed benefits**, not functionality
established by the issue.
## The main advantages
### 1. Less repeated discovery and command guessing
Without MCP, the agent repeatedly works out:
- Which Grails version is this?
- Which generator or CLI backend applies?
- What arguments does it accept?
- Which test task should run?
An MCP tool can encode that knowledge once. This is especially useful across
different Grails versions and project configurations.
However, a good `AGENTS.md` and Grails skills already address much of the
guidance side. MCP adds the most value when it provides **executable,
version-aware behavior**, not just instructions.
### 2. Structured results rather than terminal interpretation
A CLI is primarily designed for people. An MCP tool can return something
like:
```json
{
"success": true,
"generatedFiles": [
"grails-app/controllers/example/BookController.groovy",
"src/test/groovy/example/BookControllerSpec.groovy"
]
}
```
That gives the agent a clearer basis for its next action than parsing
colored terminal output.
This can reduce unnecessary file searches and model context usage, although
performance gains would need measurement.
### 3. Reuse across agents and IDEs
The same server could be used by Cline and other MCP-compatible clients.
Instead of implementing Grails integrations separately for each IDE or
agent, Grails maintains one protocol-facing integration. Client support and
approval behavior still vary.
### 4. Better-defined operations and guardrails
A generation tool can validate names, restrict destinations, refuse
overwrites, and serialize project mutations.
That is more controlled than exposing a generic “execute this command”
operation.
**But MCP is not a sandbox:** if Cline also has unrestricted terminal
access, it can bypass those tool restrictions. Build execution also runs
project-authored code regardless of whether MCP launches it.
### 5. Access to information that is awkward to obtain from source alone
This could eventually be the strongest benefit: integration with resolved
build metadata, actual generator capabilities, or explicitly enabled
development-time application information.
For example, reliably reporting resolved dependencies or registered URL
mappings can be more useful than asking the model to infer them from text.
Runtime inspection would require separate integration and careful scope; it is
not automatically provided by MCP.
## When would it *not* be worthwhile?
If the server only wraps:
```text
generate_controller → run grails create-controller
run_tests → run ./gradlew test
```
with little validation or structured output, the improvement over Cline’s
existing terminal tool is modest. It introduces another process, dependencies,
configuration, and maintenance burden.
For a developer's current workflow, **Cline + good Grails skills + existing
CLI tools may already be sufficient**.
So, the criterion for this issue might be:
> Does the server provide authoritative Grails knowledge or structured
operations that an agent cannot obtain as reliably and cheaply through its
existing tools?
If yes, MCP could meaningfully improve Grails development across clients. If
not, improving the CLI and agent skills may be the better investment.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]