### Start Stateless HTTP Example with Docker Compose Source: https://github.com/hairglasses-studio/mcpkit/blob/main/examples/stateless-http/README.md Commands to build and run the stateless HTTP example environment. ```bash cd examples/stateless-http docker compose up --build ``` -------------------------------- ### Install A2A Go SDK Source: https://github.com/hairglasses-studio/mcpkit/blob/main/_reference/a2a-go/README.md Use the go get command to add the library to your project. ```bash go get github.com/a2aproject/a2a-go/v2 ``` -------------------------------- ### Install mcpkit Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/QUICKSTART.md Install the mcpkit library and its transitive dependency mcp-go using go get. ```bash go get github.com/hairglasses-studio/mcpkit@latest ``` ```bash go get github.com/mark3labs/mcp-go@latest ``` -------------------------------- ### Install mcpkit Source: https://github.com/hairglasses-studio/mcpkit/blob/main/README.md Install the mcpkit library using go get. This command fetches the latest version of the library. ```bash go get github.com/hairglasses-studio/mcpkit@latest ``` -------------------------------- ### Configure Router Source: https://github.com/hairglasses-studio/mcpkit/blob/main/gateway/multi/README.md Sets up the router with logging, registers multiple adapters, and starts the HTTP server. ```go router := multi.NewRouter(reg, multi.WithLogger(slog.Default()), // structured logging ) router.Register(multi.NewMCPAdapter()) router.Register(multi.NewA2AAdapter()) router.Register(multi.NewOpenAIAdapter()) // Use as standard http.Handler. http.ListenAndServe(":9090", router) ``` -------------------------------- ### Clone and Build Project Source: https://github.com/hairglasses-studio/mcpkit/blob/main/js/open-multi-agent/CONTRIBUTING.md Clone the repository and build the project. Use 'make build' for building or 'go build ./...' for Go projects, 'npm install' for Node.js, and 'pip install -e .' for Python. Run tests with 'make test' or equivalent commands. ```bash git clone https://github.com/hairglasses-studio/open-multi-agent cd open-multi-agent make build # or: go build ./... / npm install / pip install -e . make test # or: go test ./... / npm test / pytest ``` -------------------------------- ### Start Development Server with Python MCP SDK Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/research/RESEARCH-DX.md Command to start a development server using the Python MCP SDK. This is typically used for local development and testing. ```bash mcp dev ``` -------------------------------- ### Install Pre-commit Hooks Source: https://github.com/hairglasses-studio/mcpkit/blob/main/js/open-multi-agent/CONTRIBUTING.md Install pre-commit hooks to automatically run vet and fast tests (Go), linting (Node.js), or ruff checks (Python) before each commit. ```bash make install-hooks ``` -------------------------------- ### Setting up a Test Server with mcptest Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/QUICKSTART.md This helper function builds a fully wired test server that mirrors the production setup. It registers tool, resource, and prompt modules before creating the MCP server and client. ```go package main import ( "testing" "github.com/hairglasses-studio/mcpkit/mcptest" "github.com/hairglasses-studio/mcpkit/prompts" "github.com/hairglasses-studio/mcpkit/registry" "github.com/hairglasses-studio/mcpkit/resources" ) // helper builds a fully wired test server matching the production setup. func newTestServer(t *testing.T) *mcptest.Client { t.Helper() toolReg := registry.NewToolRegistry() toolReg.RegisterModule(&greetModule{}) resReg := resources.NewResourceRegistry() resReg.RegisterModule(&configResourceModule{}) promptReg := prompts.NewPromptRegistry() promptReg.RegisterModule(&workflowPromptModule{}) srv := mcptest.NewServer(t, toolReg) // Wire resources and prompts to the same MCP server resReg.RegisterWithServer(srv.MCP) promptReg.RegisterWithServer(srv.MCP) return mcptest.NewClient(t, srv) } ``` -------------------------------- ### Quick Start: Setting up the Multi-Protocol Gateway Source: https://github.com/hairglasses-studio/mcpkit/blob/main/gateway/multi/README.md This Go code demonstrates how to set up the mcpkit multi-protocol gateway. It involves registering tools, creating the gateway router, registering protocol adapters (MCP, A2A, OpenAI), and serving requests on port 9090. Ensure necessary imports are included. ```go package main import ( "log" "net/http" "github.com/hairglasses-studio/mcpkit/gateway/multi" "github.com/hairglasses-studio/mcpkit/handler" "github.com/hairglasses-studio/mcpkit/registry" ) type EchoInput struct { Message string `json:"message" jsonschema:"required"` } type EchoOutput struct { Reply string `json:"reply"` } func main() { // 1. Register tools. reg := registry.NewToolRegistry() td := handler.TypedHandler[EchoInput, EchoOutput]( "echo", "Echo a message back", func(ctx context.Context, in EchoInput) (EchoOutput, error) { return EchoOutput{Reply: in.Message}, nil }, ) reg.RegisterTool(td) // 2. Create the gateway router. router := multi.NewRouter(reg) // 3. Register protocol adapters. router.Register(multi.NewMCPAdapter()) router.Register(multi.NewA2AAdapter()) router.Register(multi.NewOpenAIAdapter()) // 4. Serve — one endpoint, three protocols. log.Fatal(http.ListenAndServe(":9090", router)) } ``` -------------------------------- ### Copy Environment File Source: https://github.com/hairglasses-studio/mcpkit/blob/main/_reference/a2a-go/examples/clustermode/server/deploy/README.md Copy the example environment file to `.env` to begin configuration. This sets up the necessary variables for the Docker Compose environment. ```bash cp env.example .env ``` -------------------------------- ### Example mcpkit Project Structure Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/research/RESEARCH-DX.md Illustrates a typical project layout generated by `mcpkit init`, including directories for commands, internal tools, resources, prompts, middleware, and configuration files. ```text my-server/ cmd/ server/ # Entry point with server setup main.go internal/ tools/ # Example tool with TypedHandler hello.go hello_test.go # Test using mcptest resources/ # Example resource config.go prompts/ # Example prompt greeting.go middleware/ # Example middleware logging.go go.mod # Module with mcpkit dependency go.sum Makefile # build, test, vet, run targets .gitignore CLAUDE.md # Agent-friendly project context ``` -------------------------------- ### Dynamic Task Generation Example Source: https://github.com/hairglasses-studio/mcpkit/blob/main/ralph/RESEARCH-DAG.md Illustrates how an LLM can propose new tasks at runtime, including their dependencies and arguments. ```json { "task_id": "research", "tool_name": "search", "arguments": {"query": "..."}, "add_tasks": [ {"id": "analyze-result-1", "description": "...", "depends_on": ["research"]}, {"id": "analyze-result-2", "description": "...", "depends_on": ["research"]} ] } ``` -------------------------------- ### Implement Custom Redis Client Source: https://github.com/hairglasses-studio/mcpkit/blob/main/examples/stateless-http/README.md Example implementation of the session.RedisClient interface using the go-redis library. ```go import "github.com/redis/go-redis/v9" type GoRedisClient struct { rdb *redis.Client } func (c *GoRedisClient) Get(ctx context.Context, key string) (string, error) { val, err := c.rdb.Get(ctx, key).Result() if err == redis.Nil { return "", session.ErrNotFound } return val, err } func (c *GoRedisClient) Set(ctx context.Context, key, value string, ttl time.Duration) error { return c.rdb.Set(ctx, key, value, ttl).Err() } func (c *GoRedisClient) Del(ctx context.Context, keys ...string) error { return c.rdb.Del(ctx, keys...).Err() } ``` -------------------------------- ### Run the MCP server Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/QUICKSTART.md Execute the Go program to start the MCP server, which will listen for JSON-RPC messages on stdio. ```bash go run main.go ``` -------------------------------- ### Implement Custom Tool Benchmark Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/BENCHMARK.md Example of using mcptest helpers to benchmark a custom tool handler. ```go func BenchmarkMyTool(b *testing.B) { handler := func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { return &mcp.CallToolResult{ Content: []mcp.Content{mcp.TextContent{Type: "text", Text: "ok"}}, }, nil } mcptest.BenchmarkToolDirect(b, handler, map[string]any{"key": "value"}) } ``` -------------------------------- ### Benchmark Result Format Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/BENCHMARK.md Example output format for Go benchmarks showing operations, latency, and memory allocations. ```text BenchmarkToolDirect-16 1234567 987.6 ns/op 256 B/op 3 allocs/op ``` -------------------------------- ### Initialize Bridge and Start HTTP Server Source: https://github.com/hairglasses-studio/mcpkit/blob/main/bridge/a2a/README.md Set up a Bridge to wire a ToolRegistry into an A2A HTTP server. This includes configuring the agent's name, description, and listen address. The bridge can run its own server or be embedded. ```go bridge, err := a2a.NewBridge(reg, a2a.BridgeConfig{ Name: "my-agent", Description: "MCP tools as an A2A agent", URL: "http://localhost:8080", Addr: ":8080", // listen address (default: ":8080") Timeout: 60 * time.Second, // per-tool timeout (default: 30s) Logger: slog.Default(), Middleware: []registry.Middleware{myMiddleware}, }) // Option A: Run the built-in HTTP server. ctx, cancel := context.WithCancel(context.Background()) defer cancel() go bridge.Start(ctx) // Option B: Embed in your own server. http.Handle("/", bridge.Handler()) // Read the generated agent card. card := bridge.AgentCard() ``` -------------------------------- ### Quick Start: Register MCP tools and serve as A2A agent Source: https://github.com/hairglasses-studio/mcpkit/blob/main/bridge/a2a/README.md Register MCP tools, create a bridge executor, generate an A2A agent card, and serve over HTTP. Ensure the A2A SDK is imported. ```go // Register MCP tools as usual. reg := registry.NewToolRegistry() reg.RegisterModule(&MyModule{}) // Create the bridge executor. executor := a2a.NewBridgeExecutor(reg, a2a.ExecutorConfig{}) // Generate an A2A agent card from registered tools. cardGen := a2a.NewAgentCardGenerator(reg, nil, a2a.CardConfig{ Name: "my-agent", Description: "MCP tools exposed as an A2A agent", URL: "http://localhost:8080", }) card := cardGen.Generate() // Serve over HTTP using the official A2A SDK. handler := a2asrv.NewHandler(executor) mux := http.NewServeMux() mux.Handle(a2asrv.WellKnownAgentCardPath, a2asrv.NewStaticAgentCardHandler(card)) mux.Handle("/", a2asrv.NewJSONRPCHandler(handler)) http.ListenAndServe(":8080", mux) ``` -------------------------------- ### Create New Project with .NET MCP SDK Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/research/RESEARCH-DX.md Command to create a new project using the .NET MCP SDK's project template. This is the standard way to start a .NET-based MCP project. ```bash dotnet new mcpserver ``` -------------------------------- ### Conventional Commit Examples Source: https://github.com/hairglasses-studio/mcpkit/blob/main/CONTRIBUTING.md Examples of commit messages following the conventional commit style. ```text feat: add streaming transport support fix: handle nil context in middleware chain docs: add ToolModule authoring example test: add table-driven tests for registry refactor: simplify middleware chain resolution chore: update go.mod dependencies ``` -------------------------------- ### Register and Serve Tools with Middleware Source: https://context7.com/hairglasses-studio/mcpkit/llms.txt Demonstrates setting up a ToolRegistry with a custom logging middleware, rate limiting, circuit breaking, and response truncation. It then registers a module and serves tools via stdio. ```go package main import ( "context" "log" "log/slog" "os" "time" "github.com/hairglasses-studio/mcpkit/handler" "github.com/hairglasses-studio/mcpkit/middleware/truncate" "github.com/hairglasses-studio/mcpkit/registry" "github.com/hairglasses-studio/mcpkit/resilience" ) // ToolModule groups related tools type NotesModule struct{} func (m *NotesModule) Name() string { return "notes" } func (m *NotesModule) Description() string { return "Note management tools" } func (m *NotesModule) Tools() []registry.ToolDefinition { return []registry.ToolDefinition{ handler.TypedHandler[SearchInput, SearchResult]( "notes_search", "Search notes", func(ctx context.Context, in SearchInput) (SearchResult, error) { return SearchResult{Results: []string{"note1"}, Total: 1}, nil }, ), } } // Custom logging middleware func loggingMiddleware(logger *slog.Logger) registry.Middleware { return func(name string, td registry.ToolDefinition, next registry.ToolHandlerFunc) registry.ToolHandlerFunc { return func(ctx context.Context, req registry.CallToolRequest) (*registry.CallToolResult, error) { start := time.Now() result, err := next(ctx, req) logger.Info("tool called", "tool", name, "duration", time.Since(start), "error", err != nil) return result, err } } } func main() { logger := slog.New(slog.NewJSONHandler(os.Stderr, nil)) // Create registry with middleware stack (outermost first) reg := registry.NewToolRegistry(registry.Config{ DefaultTimeout: 30 * time.Second, MaxResponseSize: 128 * 1024, Middleware: []registry.Middleware{ truncate.New(truncate.WithMaxBytes(4096)), resilience.RateLimitMiddleware(resilience.NewRateLimitRegistry()), resilience.CircuitBreakerMiddleware(resilience.NewCircuitBreakerRegistry(nil)), loggingMiddleware(logger), }, }) // Register modules reg.RegisterModule(&NotesModule{}) // Wire to MCP server s := registry.NewMCPServer("notes-server", "1.0.0") reg.RegisterWithServer(s) if err := registry.ServeStdio(s); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Install Open Multi-Agent Source: https://github.com/hairglasses-studio/mcpkit/blob/main/js/open-multi-agent/README.md Install the package using npm. Ensure OPENAI_API_KEY is set in your environment variables. ```bash npm install @jackchen_me/open-multi-agent ``` -------------------------------- ### Install with Python MCP SDK Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/research/RESEARCH-DX.md Command to install or integrate with Claude Desktop using the Python MCP SDK. Facilitates integration with the Claude Desktop environment. ```bash mcp install ``` -------------------------------- ### Create a basic MCP server (Hello World) Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/QUICKSTART.md A minimal viable MCP server that echoes a message back to the caller. It uses TypedHandler for input/output and serves over stdio. ```go package main import ( "context" "log" "github.com/hairglasses-studio/mcpkit/handler" "github.com/hairglasses-studio/mcpkit/registry" ) type EchoInput struct { Message string `json:"message" jsonschema:"required,description=Message to echo back" } type EchoOutput struct { Reply string `json:"reply"` } func main() { td := handler.TypedHandler[EchoInput, EchoOutput]( "echo", "Echo a message back to the caller", func(ctx context.Context, in EchoInput) (EchoOutput, error) { return EchoOutput{Reply: "You said: " + in.Message}, nil }, ) s := registry.NewMCPServer("echo-server", "1.0.0") registry.AddToolToServer(s, td.Tool, td.Handler) if err := registry.ServeStdio(s); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Start Cluster with Docker Compose Source: https://github.com/hairglasses-studio/mcpkit/blob/main/_reference/a2a-go/examples/clustermode/server/deploy/README.md Start the cluster using Docker Compose in detached mode (`-d`). This command initiates the server replicas, MySQL instance, and Nginx load balancer. ```bash docker compose up -d ``` -------------------------------- ### Create New Repository with Scaffolding Source: https://github.com/hairglasses-studio/mcpkit/blob/main/js/open-multi-agent/CONTRIBUTING.md Use the scaffolding script to create a new project with standard files like Makefile, .editorconfig, .golangci.yml, CI configuration, and LICENSE. Specify the project name and language (e.g., 'go'). ```bash ~/hairglasses-studio/dotfiles/scripts/hg-new-repo.sh my-new-project go ``` -------------------------------- ### Example Structured Log Output Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/QUICKSTART.md Sample JSON output generated by the logging middleware to stderr. ```json {"time":"...","level":"INFO","msg":"tool called","tool":"greet","duration":"52.3us","error":false} ``` -------------------------------- ### Execute Gateway Adapter Benchmarks Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/BENCHMARK.md Command to run benchmarks for adapter creation, discovery, and proxying. ```bash go test -bench=. -benchmem ./gateway/adapter/ ``` -------------------------------- ### Clone and Build mcpkit Source: https://github.com/hairglasses-studio/mcpkit/blob/main/CONTRIBUTING.md Initializes the local development environment by cloning the repository and building the project. ```bash git clone https://github.com/hairglasses-studio/mcpkit.git cd mcpkit make build # or: go build ./... ``` -------------------------------- ### Clone and Checkout Repository Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/HANDOFF.md Initializes the local environment by cloning the repository and switching to the R&D cycle feature branch. ```bash git clone git@github.com:hairglasses-studio/mcpkit.git cd mcpkit git checkout feature/rdcycle-auto-2 ``` -------------------------------- ### Implement Middleware in main.go Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/QUICKSTART.md Configures the tool registry with truncation, rate limiting, circuit breaking, and custom logging middleware. ```go package main import ( "context" "fmt" "log" "log/slog" "os" "time" "github.com/hairglasses-studio/mcpkit/handler" "github.com/hairglasses-studio/mcpkit/middleware/truncate" "github.com/hairglasses-studio/mcpkit/registry" "github.com/hairglasses-studio/mcpkit/resilience" ) // --- Types --- type GreetInput struct { Name string `json:"name" jsonschema:"required,description=Name to greet"` Language string `json:"language,omitempty" jsonschema:"description=Greeting language (en or es),enum=en,enum=es"` } type GreetOutput struct { Message string `json:"message"` } // --- Module --- type greetModule struct{} func (m *greetModule) Name() string { return "greet" } func (m *greetModule) Description() string { return "Greeting tools" } func (m *greetModule) Tools() []registry.ToolDefinition { td := handler.TypedHandler[GreetInput, GreetOutput]( "greet", "Greet a user by name", func(_ context.Context, in GreetInput) (GreetOutput, error) { lang := in.Language if lang == "" { lang = "en" } var msg string switch lang { case "es": msg = fmt.Sprintf("Hola, %s!", in.Name) default: msg = fmt.Sprintf("Hello, %s!", in.Name) } return GreetOutput{Message: msg}, nil }, ) td.CircuitBreakerGroup = "greet-service" return []registry.ToolDefinition{td} } // --- Logging middleware --- func loggingMiddleware(logger *slog.Logger) registry.Middleware { return func(name string, td registry.ToolDefinition, next registry.ToolHandlerFunc) registry.ToolHandlerFunc { return func(ctx context.Context, req registry.CallToolRequest) (*registry.CallToolResult, error) { start := time.Now() result, err := next(ctx, req) logger.Info("tool called", "tool", name, "duration", time.Since(start), "error", err != nil, ) return result, err } } } // --- Main --- func main() { // Always log to stderr -- stdout is reserved for MCP JSON-RPC logger := slog.New(slog.NewJSONHandler(os.Stderr, nil)) reg := registry.NewToolRegistry(registry.Config{ Middleware: []registry.Middleware{ truncate.New(truncate.WithMaxBytes(4096)), resilience.RateLimitMiddleware(resilience.NewRateLimitRegistry()), resilience.CircuitBreakerMiddleware(resilience.NewCircuitBreakerRegistry(nil)), loggingMiddleware(logger), }, }) reg.RegisterModule(&greetModule{}) s := registry.NewMCPServer("greeter", "1.0.0") reg.RegisterWithServer(s) if err := registry.ServeStdio(s); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Get AgentCard Source: https://github.com/hairglasses-studio/mcpkit/blob/main/bridge/a2a/README.md Retrieve the AgentCard from the generator. This will return the cached card or generate a new one if it's not available or has been invalidated. ```go card := gen.Card() // returns cached or generates ``` -------------------------------- ### Registering MCP Resources and Prompts in main.go Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/QUICKSTART.md Implements tool, resource, and prompt modules and registers them with an MCP server instance. ```go package main import ( "context" "fmt" "log" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" "github.com/hairglasses-studio/mcpkit/handler" "github.com/hairglasses-studio/mcpkit/prompts" "github.com/hairglasses-studio/mcpkit/registry" "github.com/hairglasses-studio/mcpkit/resources" ) // --- Tool types --- type GreetInput struct { Name string `json:"name" jsonschema:"required,description=Name to greet"` } type GreetOutput struct { Message string `json:"message"` } // --- Tool module --- type greetModule struct{} func (m *greetModule) Name() string { return "greet" } func (m *greetModule) Description() string { return "Greeting tools" } func (m *greetModule) Tools() []registry.ToolDefinition { return []registry.ToolDefinition{ handler.TypedHandler[GreetInput, GreetOutput]( "greet", "Greet a user by name", func(_ context.Context, in GreetInput) (GreetOutput, error) { return GreetOutput{Message: "Hello, " + in.Name + "!"}, nil }, ), } } // --- Resource module --- type configResourceModule struct{} func (m *configResourceModule) Name() string { return "config" } func (m *configResourceModule) Description() string { return "Configuration resources" } func (m *configResourceModule) Resources() []resources.ResourceDefinition { return []resources.ResourceDefinition{ { Resource: mcp.NewResource( "config://app/settings", "App Settings", mcp.WithResourceDescription("Current application settings"), mcp.WithMIMEType("application/json"), ), Handler: func(_ context.Context, _ mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) { return []mcp.ResourceContents{ mcp.TextResourceContents{ URI: "config://app/settings", MIMEType: "application/json", Text: `{"log_level": "info", "max_results": 50, "language": "en"}`, }, }, nil }, Category: "configuration", }, } } func (m *configResourceModule) Templates() []resources.TemplateDefinition { return nil } // --- Prompt module --- type workflowPromptModule struct{} func (m *workflowPromptModule) Name() string { return "workflows" } func (m *workflowPromptModule) Description() string { return "Workflow prompt templates" } func (m *workflowPromptModule) Prompts() []prompts.PromptDefinition { return []prompts.PromptDefinition{ { Prompt: mcp.NewPrompt("greet_workflow", mcp.WithPromptDescription("Greet multiple users with a custom style"), mcp.WithArgument("names", mcp.RequiredArgument(), mcp.ArgumentDescription("Comma-separated list of names")), mcp.WithArgument("style", mcp.ArgumentDescription("Greeting style: casual or formal (default: casual)")), ), Handler: func(_ context.Context, req mcp.GetPromptRequest) (*mcp.GetPromptResult, error) { names := req.Params.Arguments["names"] style := req.Params.Arguments["style"] if style == "" { style = "casual" } return &mcp.GetPromptResult{ Description: "Greet users: " + names, Messages: []mcp.PromptMessage{ mcp.NewPromptMessage(mcp.RoleUser, mcp.NewTextContent( fmt.Sprintf( "Use the greet tool to greet each of these people with a %s style: %s", style, names, ), )), }, }, nil }, Category: "workflows", }, } } // --- Main --- func main() { // Tool registry toolReg := registry.NewToolRegistry() toolReg.RegisterModule(&greetModule{}) // Resource registry resReg := resources.NewResourceRegistry() resReg.RegisterModule(&configResourceModule{}) // Prompt registry promptReg := prompts.NewPromptRegistry() promptReg.RegisterModule(&workflowPromptModule{}) // Wire everything to a single MCP server s := server.NewMCPServer("greeter", "1.0.0", server.WithToolCapabilities(true), server.WithResourceCapabilities(false, true), server.WithPromptCapabilities(true), ) toolReg.RegisterWithServer(s) resReg.RegisterWithServer(s) promptReg.RegisterWithServer(s) if err := registry.ServeStdio(s); err != nil { ``` -------------------------------- ### Recommended Codex install for MCP server Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/QUICKSTART.md Command to add the MCP server to Codex, specifying the command to run the Go program. ```bash codex mcp add echo -- go run /absolute/path/to/main.go ``` -------------------------------- ### Build and Test Go Packages Source: https://github.com/hairglasses-studio/mcpkit/blob/main/AGENTS.md Standard commands for building, static analysis, and testing Go packages within the mcpkit project. Use `make check` for a comprehensive check. ```bash go build ./... ``` ```bash go vet ./... ``` ```bash go test ./... -count=1 ``` ```bash make check ``` ```bash make build-official ``` ```bash make check-dual ``` -------------------------------- ### Launch R&D Loop Source: https://github.com/hairglasses-studio/mcpkit/blob/main/docs/HANDOFF.md Provides options for starting the R&D loop using either the automated script or manual environment configuration. ```bash ./scripts/rdloop.sh --budget 100 --duration 12h ``` ```bash export ANTHROPIC_API_KEY="..." # from 1Password export GITHUB_TOKEN="..." # from 1Password export RDLOOP_BUDGET=100.0 export RDLOOP_DURATION=12h go run ./cmd/rdloop 2>&1 | tee rdloop_$(date +%Y%m%d_%H%M).log ``` -------------------------------- ### Build and Test Commands Source: https://github.com/hairglasses-studio/mcpkit/blob/main/README.md Standard commands for building, analyzing, and testing the project packages. ```bash go build ./... # Build all packages go vet ./... # Static analysis go test ./... -count=1 # Run all tests (no cache) make check # All three above make build-official # Verify official SDK build make check-dual # Full check + official SDK build ```