Files
amcs/cmd/amcs-cli/cmd/sse.go
Hein 3dfed9c986
Some checks failed
CI / build-and-test (push) Failing after -32m50s
fix(observability): include MCP session ID in access logs
* Add function to extract MCP session ID from request headers and query parameters
* Update access log to include MCP session ID
fix(cli): simplify project lookup logic
* Refactor project retrieval to prefer GUID lookup when input is a valid UUID
* Introduce separate functions for fetching projects by GUID and name
2026-04-21 23:04:46 +02:00

90 lines
2.3 KiB
Go

package cmd
import (
"context"
"fmt"
"strings"
"github.com/modelcontextprotocol/go-sdk/mcp"
"github.com/spf13/cobra"
)
var sseCmd = &cobra.Command{
Use: "sse",
Short: "Run a stdio MCP bridge backed by a remote AMCS server using SSE transport (widely supported by hosted MCP clients)",
RunE: func(cmd *cobra.Command, _ []string) error {
ctx := cmd.Context()
if err := requireServer(); err != nil {
return err
}
client := mcp.NewClient(&mcp.Implementation{Name: "amcs-cli", Version: "0.0.1"}, nil)
transport := &mcp.SSEClientTransport{
Endpoint: sseEndpointURL(),
HTTPClient: newHTTPClient(),
}
verboseLogf("connecting to SSE endpoint %s", sseEndpointURL())
remote, err := client.Connect(ctx, transport, nil)
if err != nil {
return fmt.Errorf("connect to AMCS SSE endpoint: %w", err)
}
defer func() { _ = remote.Close() }()
verboseLogf("connected to SSE endpoint %s", sseEndpointURL())
tools, err := remote.ListTools(ctx, nil)
if err != nil {
return fmt.Errorf("load remote tools: %w", err)
}
server := mcp.NewServer(&mcp.Implementation{
Name: "amcs-cli",
Title: "AMCS CLI Bridge (SSE)",
Version: "0.0.1",
}, nil)
for _, tool := range tools.Tools {
remoteTool := tool
server.AddTool(&mcp.Tool{
Name: remoteTool.Name,
Description: remoteTool.Description,
InputSchema: remoteTool.InputSchema,
OutputSchema: remoteTool.OutputSchema,
Annotations: remoteTool.Annotations,
}, func(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) {
return remote.CallTool(ctx, &mcp.CallToolParams{
Name: req.Params.Name,
Arguments: req.Params.Arguments,
})
})
}
session, err := server.Connect(ctx, &mcp.StdioTransport{}, nil)
if err != nil {
return fmt.Errorf("start stdio bridge: %w", err)
}
defer func() { _ = session.Close() }()
verboseLogf("sse stdio bridge ready")
verboseLogf("waiting for MCP commands on stdin")
<-ctx.Done()
return nil
},
}
func sseEndpointURL() string {
base := strings.TrimRight(strings.TrimSpace(cfg.Server), "/")
if strings.HasSuffix(base, "/mcp") {
base = strings.TrimSuffix(base, "/mcp")
}
if strings.HasSuffix(base, "/sse") {
return base
}
return base + "/sse"
}
func init() {
rootCmd.AddCommand(sseCmd)
}