Switch MCP implementation to modelcontextprotocol/go-sdk (#22859)
This commit is contained in:
parent
11e7c13f01
commit
7990146bb3
6 changed files with 58 additions and 84 deletions
|
|
@ -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...)
|
||||
}
|
||||
|
|
@ -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{},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue