Switch MCP implementation to modelcontextprotocol/go-sdk (#22859)

This commit is contained in:
andig 2025-08-10 11:14:36 +02:00 • committed by GitHub
parent 11e7c13f01
commit 7990146bb3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 58 additions and 84 deletions

View file

@ -1,15 +0,0 @@
package mcp
import "github.com/evcc-io/evcc/util"
type logger struct {
log *util.Logger
}
func (l *logger) Infof(format string, v ...any) {
l.log.TRACE.Printf(format, v...)
}
func (l *logger) Errorf(format string, v ...any) {
l.log.WARN.Printf(format, v...)
}

View file

@ -10,10 +10,10 @@ import (
"strings"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/openapi-mcp/pkg/openapi2mcp"
openapi2mcp "github.com/evcc-io/openapi-mcp"
"github.com/getkin/kin-openapi/openapi3"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
"github.com/modelcontextprotocol/go-sdk/jsonschema"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
//go:embed openapi.json
@ -39,9 +39,7 @@ func NewHandler(host http.Handler, baseUrl, basePath string) (http.Handler, erro
ops := openapi2mcp.ExtractOpenAPIOperations(doc)
srv := server.NewMCPServer("evcc", util.Version,
server.WithLogging(),
)
srv := mcp.NewServer(&mcp.Implementation{Name: "evcc", Version: util.Version}, nil)
openapi2mcp.RegisterOpenAPITools(srv, ops, doc, &openapi2mcp.ToolGenOptions{
NameFormat: nameFormat(log),
@ -55,24 +53,24 @@ func NewHandler(host http.Handler, baseUrl, basePath string) (http.Handler, erro
RequestHandler: requestHandler(host),
})
srv.AddTool(mcp.NewTool("docs",
mcp.WithDescription("Documentation"),
), docsTool)
mcp.AddTool(srv, &mcp.Tool{
Name: "docs",
Description: "Documentation",
InputSchema: emptySchema(),
}, docsTool)
srv.AddPrompt(mcp.NewPrompt("create-charge-plan",
mcp.WithPromptDescription("Create an optimized charge plan for a loadpoint or vehicle"),
mcp.WithArgument("loadpoint",
mcp.ArgumentDescription("The loadpoint to create the charge plan for"),
),
mcp.WithArgument("vehicle",
mcp.ArgumentDescription("The vehicle to create the charge plan for"),
),
), promptHandler())
srv.AddPrompt(&mcp.Prompt{
Name: "create-charge-plan",
Description: "Create an optimized charge plan for a loadpoint or vehicle",
Arguments: []*mcp.PromptArgument{
{Name: "loadpoint", Description: "The loadpoint to create the charge plan for"},
{Name: "vehicle", Description: "The vehicle to create the charge plan for"},
},
}, promptHandler())
handler := server.NewStreamableHTTPServer(srv,
server.WithEndpointPath(basePath),
server.WithLogger(&logger{log}),
)
handler := mcp.NewStreamableHTTPHandler(func(*http.Request) *mcp.Server {
return srv
}, nil)
return handler, nil
}
@ -111,3 +109,10 @@ func requestHandler(handler http.Handler) func(req *http.Request) (*http.Respons
return resp, nil
}
}
func emptySchema() *jsonschema.Schema {
return &jsonschema.Schema{
Type: "object",
Properties: map[string]*jsonschema.Schema{},
}
}

View file

@ -8,35 +8,35 @@ import (
"html/template"
"github.com/Masterminds/sprig/v3"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
//go:embed prompt.tpl
var prompt string
func promptHandler() server.PromptHandlerFunc {
func promptHandler() mcp.PromptHandler {
tmpl := template.Must(template.New("out").Funcs(sprig.FuncMap()).Parse(prompt))
return func(ctx context.Context, req mcp.GetPromptRequest) (*mcp.GetPromptResult, error) {
// tmpl, err := template.New("out").Funcs(sprig.FuncMap()).Parse(prompt)
// if err != nil {
// return nil, fmt.Errorf("error parsing template: %v", err)
// }
return func(ctx context.Context, ss *mcp.ServerSession, params *mcp.GetPromptParams) (*mcp.GetPromptResult, error) {
out := new(bytes.Buffer)
if err := tmpl.Execute(out, req.Params.Arguments); err != nil {
return nil, fmt.Errorf("failed executing template: %v", err)
if err := tmpl.Execute(out, params.Arguments); err != nil {
return &mcp.GetPromptResult{
Messages: []*mcp.PromptMessage{
{
Role: "assistant",
Content: &mcp.TextContent{
Text: fmt.Sprintf("The was an error parsing the request: %v", err),
},
},
},
}, nil
}
return &mcp.GetPromptResult{
Messages: []mcp.PromptMessage{
Messages: []*mcp.PromptMessage{
{
Role: mcp.RoleAssistant,
Content: mcp.TextContent{
Type: "text",
Text: out.String(),
},
Role: "assistant",
Content: &mcp.TextContent{Text: out.String()},
},
},
}, nil

View file

@ -3,13 +3,18 @@ package mcp
import (
"context"
"github.com/mark3labs/mcp-go/mcp"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
func docsTool(_ context.Context, _ mcp.CallToolRequest) (*mcp.CallToolResult, error) {
func docsTool(_ context.Context, _ *mcp.ServerSession, _ *mcp.CallToolParams) (*mcp.CallToolResult, error) {
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewResourceLink("https://docs.evcc.io", "evcc-docs", "evcc documentation", "text/html"),
&mcp.ResourceLink{
URI: "https://docs.evcc.io",
Name: "evcc-docs",
Title: "evcc documentation",
MIMEType: "text/html",
},
},
}, nil
}