From 6b73a4b84b44c32011d1a44d85c239621e44d034 Mon Sep 17 00:00:00 2001 From: snider Date: Wed, 31 Dec 2025 14:12:44 +0000 Subject: [PATCH] feat: Add MCP (Model Context Protocol) server integration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Integrate gin-mcp to expose mining API endpoints as MCP tools, enabling AI assistants like Claude, Cursor, and Continue to interact directly with the mining dashboard. - Add gin-mcp dependency - Initialize MCP server in SetupRoutes - Mount at /api/v1/mining/mcp - Automatically converts 40 API routes to MCP tools AI assistants can now connect via SSE to discover and call mining API operations programmatically. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- go.mod | 2 ++ go.sum | 6 ++++++ pkg/mining/service.go | 12 ++++++++++++ 3 files changed, 20 insertions(+) diff --git a/go.mod b/go.mod index aec5672..88e1ba5 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( github.com/Snider/Enchantrix v0.0.2 // indirect github.com/bytedance/sonic v1.14.0 // indirect github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/ckanthony/gin-mcp v0.0.0-20251107113615-3c631c4fa9f4 // indirect github.com/cloudflare/circl v1.6.1 // indirect github.com/cloudwego/base64x v0.1.6 // indirect github.com/ebitengine/purego v0.9.0 // indirect @@ -59,6 +60,7 @@ require ( github.com/quic-go/qpack v0.5.1 // indirect github.com/quic-go/quic-go v0.54.0 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.9 // indirect github.com/tklauser/go-sysconf v0.3.15 // indirect github.com/tklauser/numcpus v0.10.0 // indirect diff --git a/go.sum b/go.sum index 375a50c..53e93b8 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQ github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/ckanthony/gin-mcp v0.0.0-20251107113615-3c631c4fa9f4 h1:V0tltxRKT8DZRXcn2ErLy4alznOBzWWmx4gnQbic9jE= +github.com/ckanthony/gin-mcp v0.0.0-20251107113615-3c631c4fa9f4/go.mod h1:eaCpaNzFM2bfCUXMPxbLFwI/ar67gAaVTNrltASGeoc= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= @@ -120,6 +122,8 @@ github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA= github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= @@ -128,6 +132,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -179,6 +184,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/pkg/mining/service.go b/pkg/mining/service.go index 4b2f0d4..6589d15 100644 --- a/pkg/mining/service.go +++ b/pkg/mining/service.go @@ -18,6 +18,7 @@ import ( "github.com/Snider/Mining/docs" "github.com/Snider/Mining/pkg/logging" "github.com/adrg/xdg" + ginmcp "github.com/ckanthony/gin-mcp" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" @@ -42,6 +43,7 @@ type Service struct { SwaggerUIPath string rateLimiter *RateLimiter auth *DigestAuth + mcpServer *ginmcp.GinMCP } // APIError represents a structured error response for the API @@ -430,6 +432,16 @@ func (s *Service) SetupRoutes() { swaggerURL := ginSwagger.URL(fmt.Sprintf("http://%s%s/doc.json", s.DisplayAddr, s.SwaggerUIPath)) s.Router.GET(s.SwaggerUIPath+"/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, swaggerURL, ginSwagger.InstanceName(s.SwaggerInstanceName))) + + // Initialize MCP server for AI assistant integration + // This exposes API endpoints as MCP tools for Claude, Cursor, etc. + s.mcpServer = ginmcp.New(s.Router, &ginmcp.Config{ + Name: "Mining API", + Description: "Mining dashboard API exposed via Model Context Protocol (MCP)", + BaseURL: fmt.Sprintf("http://%s", s.DisplayAddr), + }) + s.mcpServer.Mount(s.APIBasePath + "/mcp") + logging.Info("MCP server enabled", logging.Fields{"endpoint": s.APIBasePath + "/mcp"}) } // handleGetInfo godoc