Conversation
pkg/cmd/mcpserver/main.go
Outdated
| } | ||
|
|
||
| func ValidatePlugin(ctx context.Context, req *mcp.CallToolRequest, input Input) (*mcp.CallToolResult, Output, error) { | ||
| return nil, Output{}, nil |
There was a problem hiding this comment.
We have to do same stuffs we do in plugincheck2/main.go (reading archive, checksum, etc.) Maybe extract those into separate package and reuse it.
abbd531 to
8b5e130
Compare
pkg/service/validator.go
Outdated
| @@ -0,0 +1,228 @@ | |||
| package service | |||
There was a problem hiding this comment.
Extracted from plugincheck2/main.go.
scripts/install-mcp.sh
Outdated
| echo -e "${YELLOW}Warning: $INSTALL_DIR is not in your PATH${NC}" | ||
| echo "Add the following to your ~/.bashrc or ~/.zshrc:" | ||
| echo "" | ||
| echo " export PATH=\"\$HOME/.local/bin:\$PATH\"" |
There was a problem hiding this comment.
.local/bin exists both on macos and linux
pkg/utils/utils.go
Outdated
|
|
||
| // HasProperArchiveStructure checks if the archive has the proper structure: | ||
| // single top-level directory containing plugin.json | ||
| func HasProperArchiveStructure(archiveDir string) bool { |
There was a problem hiding this comment.
plugincheck2 used to check this using GetIdAndVersion from quickmeta and if it returns error it would add an invalid structure report to the result.
1fd98f8 to
8ef2faf
Compare
| } | ||
|
|
||
| func main() { | ||
| if err := run(); err != nil { |
There was a problem hiding this comment.
https://grafana.com/blog/how-i-write-http-services-in-go-after-13-years/ -> func main() only calls run()
academo
left a comment
There was a problem hiding this comment.
I would like you to reconsider the approach for the mcp server
the validator already supports outputting as json, could you invoke the validator binary here and parse the output instead?
here are my two concerns with this approach:
- single source of truth: now we are effectively creating two different software that embed the same engine. I much rather prefer we keep a single entry point (the validator cli binary) and make MCP just another user, like for example github actions is an user of the validator, and ci-workflows, and the community pipeline.
We don't need to create separate binaries for those cases because we have a common serialized output any user can read.
- updates: this binary will be out of date very quickly. instead we can have this wrapper checking the latest version (once a day?), downloading it and executing it to get the json output.
I don't see a mechanism to update mcp servers, they need to auto-update. People that use the validator mainly use it via docker or npx that always pulls the latest version (except NPM when it wants to be a pain)
my bottom line: we can make this wrapper simply call npx or docker or yarn dlx or similar (support several fallbacks) and parse the json output.
fd63cb4 to
e98427b
Compare
|
|
||
| func TestValidatePlugin_InvalidZip(t *testing.T) { | ||
| // Skip if neither docker nor npx is available (e.g., in CI/CD) | ||
| if !isDockerAvailable() && !isNpxAvailable() { |
There was a problem hiding this comment.
We are running the tests locally. In CI it will be skipped due to docker and npx not present.
There was a problem hiding this comment.
Validator itself is tested in https://github.com/grafana/plugin-validator/blob/main/pkg/cmd/plugincheck2/main_test.go
There was a problem hiding this comment.
So we run the tests using mage -v build:ci inside a container which uses goalpine(Dockerfile) thus no docker or npm. I have created a new job inside the test.yml of the github workflows.
adcd348 to
f23a7f9
Compare
| type Diagnostics map[string][]Diagnostic | ||
|
|
||
| // Severity constants | ||
| const ( |
There was a problem hiding this comment.
can we import the types from the existing definitions instead of re-defining them here?
There was a problem hiding this comment.
I wanted the binary for MCP to pretty thin and no dependency on the analysis package.
There was a problem hiding this comment.
So the docker build can be also minimal.
scripts/install-mcp.sh
Outdated
| @@ -0,0 +1,86 @@ | |||
| #!/bin/bash | |||
There was a problem hiding this comment.
most MCP servers I see run from npx or docker.
We should publish this validator MCP in NPM just like we do with the validator. instead of throwing a bash file to execute and auto-detec people's setup
It requires a bit more of setup but it removes all the complications of this script failing on edge cases.
we can also publish it as a docker image which is another popular way of running mcp servers
| plugincheck2 -sourceCodeUri [source_code_location/] [plugin_archive.zip] | ||
| ``` | ||
|
|
||
| ### MCP Server (for AI assistants) |
There was a problem hiding this comment.
consider this will be what we ask people to do to install our MCP server the instructions are far off.
Most people that want to install an mcp server expect instructions to tell them something like:
modify your mcp.json file and add
{
"mcpServers": {
"grafana-plugin-validator": {
"command": "npx",
"args": ["-y", "@grafana/plugin-validator-mcp"]
}
}
}
|
@academo addressed the feedbacks - It is definitely on the right direction 👏 . Except, do not redefine types that are already available - decoupling from the |
There was a problem hiding this comment.
Pull request overview
This PR adds Model Context Protocol (MCP) server support to the plugin-validator, allowing AI assistants (like Claude, Cline, etc.) to validate Grafana plugins programmatically. The MCP server is a Go binary that wraps the plugin-validator CLI and exposes it via the MCP protocol, communicating over stdin/stdout. The implementation supports both Docker and npx execution methods, with Docker preferred when available.
Changes:
- Added MCP server implementation (
pkg/cmd/mcpserver/main.go) that wraps the plugin-validator CLI via Docker or npx - Created NPM package wrapper to download and execute platform-specific MCP server binaries
- Added separate release workflows and configurations for MCP releases (tagged as
mcp/v*)
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/cmd/mcpserver/main.go | Core MCP server implementation that executes plugin-validator via Docker or npx |
| pkg/cmd/mcpserver/main_test.go | Integration tests for MCP server with valid/invalid plugin archives |
| mcp-package/index.js | NPM wrapper that downloads and executes platform-specific binaries |
| mcp-package/package.json | NPM package configuration with binary wrapper metadata |
| mcp-package/Dockerfile | Docker image for running the MCP server |
| mcp-package/README.md | Documentation with configuration examples for various MCP clients |
| .goreleaser.mcp.yaml | Goreleaser configuration for building MCP server binaries |
| .github/workflows/release-mcp.yml | Workflow to release MCP server to GitHub, NPM, and Docker Hub |
| .github/workflows/do-release-mcp.yml | Manual workflow to trigger MCP version bumps and releases |
| .github/workflows/release.yml | Updated tag filter to prevent MCP tags from triggering main releases |
| go.mod | Added MCP SDK dependency |
| go.sum | Updated dependency checksums |
| README.md | Added link to MCP server documentation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
7f1d1b1 to
947a09d
Compare
Exposes plugin-validator CLI as MCP server. Tool:
validate_plugin