This repository has been archived on 2026-08-16. You can view files and clone it, but cannot push or open issues or pull requests.
ollie-core/pkg/mcp/transport.go

60 lines
1.6 KiB
Go

package mcp
import (
"fmt"
"os"
"os/exec"
)
// STDIOTransport launches a subprocess and connects a Client to its stdin/stdout.
type STDIOTransport struct {
command string
args []string
env map[string]string
}
// NewSTDIOTransport creates a transport that will launch the given command.
// env values may contain ${VAR} references expanded against the process environment.
func NewSTDIOTransport(command string, args []string, env map[string]string) *STDIOTransport {
return &STDIOTransport{command: command, args: args, env: env}
}
// Connect launches the subprocess and returns a connected Client.
func (t *STDIOTransport) Connect() (*Client, error) {
cmd := exec.Command(t.command, t.args...)
if len(t.env) > 0 {
cmd.Env = os.Environ()
for k, v := range t.env {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, os.ExpandEnv(v)))
}
}
stdin, err := cmd.StdinPipe()
if err != nil {
return nil, err
}
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
if err := cmd.Start(); err != nil {
return nil, err
}
client := newClientWithProcess(stdout, stdin, cmd)
// MCP initialization handshake.
if _, err := client.Call("initialize", map[string]interface{}{
"protocolVersion": "2024-11-05",
"capabilities": map[string]interface{}{},
"clientInfo": map[string]interface{}{"name": "ollie", "version": "0.1"},
}); err != nil {
return nil, fmt.Errorf("initialize: %w", err)
}
if err := client.Notify("notifications/initialized", nil); err != nil {
return nil, fmt.Errorf("notifications/initialized: %w", err)
}
return client, nil
}