{"kind":"AgentDefinition","metadata":{"namespace":"community","name":"go-mcp-server","version":"0.1.0"},"spec":{"agents_md":"---\ndescription: 'Best practices and patterns for building Model Context Protocol (MCP) servers in Go using the official github.com/modelcontextprotocol/go-sdk package.'\napplyTo: \"**/*.go, **/go.mod, **/go.sum\"\n---\n\n# Go MCP Server Development Guidelines\n\nWhen building MCP servers in Go, follow these best practices and patterns using the official Go SDK.\n\n## Server Setup\n\nCreate an MCP server using `mcp.NewServer`:\n\n```go\nimport \"github.com/modelcontextprotocol/go-sdk/mcp\"\n\nserver := mcp.NewServer(\n    \u0026mcp.Implementation{\n        Name:    \"my-server\",\n        Version: \"v1.0.0\",\n    },\n    nil, // or provide mcp.Options\n)\n```\n\n## Adding Tools\n\nUse `mcp.AddTool` with struct-based input and output for type safety:\n\n```go\ntype ToolInput struct {\n    Query string `json:\"query\" jsonschema:\"the search query\"`\n    Limit int    `json:\"limit,omitempty\" jsonschema:\"maximum results to return\"`\n}\n\ntype ToolOutput struct {\n    Results []string `json:\"results\" jsonschema:\"list of search results\"`\n    Count   int      `json:\"count\" jsonschema:\"number of results found\"`\n}\n\nfunc SearchTool(ctx context.Context, req *mcp.CallToolRequest, input ToolInput) (\n    *mcp.CallToolResult,\n    ToolOutput,\n    error,\n) {\n    // Implement tool logic\n    results := performSearch(ctx, input.Query, input.Limit)\n    \n    return nil, ToolOutput{\n        Results: results,\n        Count:   len(results),\n    }, nil\n}\n\n// Register the tool\nmcp.AddTool(server, \n    \u0026mcp.Tool{\n        Name:        \"search\",\n        Description: \"Search for information\",\n    },\n    SearchTool,\n)\n```\n\n## Adding Resources\n\nUse `mcp.AddResource` for providing accessible data:\n\n```go\nfunc GetResource(ctx context.Context, req *mcp.ReadResourceRequest) (*mcp.ReadResourceResult, error) {\n    content, err := loadResourceContent(ctx, req.URI)\n    if err != nil {\n        return nil, err\n    }\n    \n    return \u0026mcp.ReadResourceResult{\n        Contents: []any{\n            \u0026mcp.TextResourceContents{\n                ResourceContents: mcp.ResourceContents{\n                    URI:      req.URI,\n                    MIMEType: \"text/plain\",\n                },\n                Text: content,\n            },\n        },\n    }, nil\n}\n\nmcp.AddResource(server,\n    \u0026mcp.Resource{\n        URI:         \"file:///data/example.txt\",\n        Name:        \"Example Data\",\n        Description: \"Example resource data\",\n        MIMEType:    \"text/plain\",\n    },\n    GetResource,\n)\n```\n\n## Adding Prompts\n\nUse `mcp.AddPrompt` for reusable prompt templates:\n\n```go\ntype PromptInput struct {\n    Topic string `json:\"topic\" jsonschema:\"the topic to analyze\"`\n}\n\nfunc AnalyzePrompt(ctx context.Context, req *mcp.GetPromptRequest, input PromptInput) (\n    *mcp.GetPromptResult,\n    error,\n) {\n    return \u0026mcp.GetPromptResult{\n        Description: \"Analyze the given topic\",\n        Messages: []mcp.PromptMessage{\n            {\n                Role: mcp.RoleUser,\n                Content: mcp.TextContent{\n                    Text: fmt.Sprintf(\"Analyze this topic: %s\", input.Topic),\n                },\n            },\n        },\n    }, nil\n}\n\nmcp.AddPrompt(server,\n    \u0026mcp.Prompt{\n        Name:        \"analyze\",\n        Description: \"Analyze a topic\",\n        Arguments: []mcp.PromptArgument{\n            {\n                Name:        \"topic\",\n                Description: \"The topic to analyze\",\n                Required:    true,\n            },\n        },\n    },\n    AnalyzePrompt,\n)\n```\n\n## Transport Configuration\n\n### Stdio Transport\n\nFor communication over stdin/stdout (most common for desktop integrations):\n\n```go\nif err := server.Run(ctx, \u0026mcp.StdioTransport{}); err != nil {\n    log.Fatal(err)\n}\n```\n\n### HTTP Transport\n\nFor HTTP-based communication:\n\n```go\nimport \"github.com/modelcontextprotocol/go-sdk/mcp\"\n\ntransport := \u0026mcp.HTTPTransport{\n    Addr: \":8080\",\n    // Optional: configure TLS, timeouts, etc.\n}\n\nif err := server.Run(ctx, transport); err != nil {\n    log.Fatal(err)\n}\n```\n\n## Error Handling\n\nAlways return proper errors and use context for cancellation:\n\n```go\nfunc MyTool(ctx context.Context, req *mcp.CallToolRequest, input MyInput) (\n    *mcp.CallToolResult,\n    MyOutput,\n    error,\n) {\n    // Check context cancellation\n    if ctx.Err() != nil {\n        return nil, MyOutput{}, ctx.Err()\n    }\n    \n    // Return errors for invalid input\n    if input.Query == \"\" {\n        return nil, MyOutput{}, fmt.Errorf(\"query cannot be empty\")\n    }\n    \n    // Perform operation\n    result, err := performOperation(ctx, input)\n    if err != nil {\n        return nil, MyOutput{}, fmt.Errorf(\"operation failed: %w\", err)\n    }\n    \n    return nil, result, nil\n}\n```\n\n## JSON Schema Tags\n\nUse `jsonschema` tags to document your structs for better client integration:\n\n```go\ntype Input struct {\n    Name     string   `json:\"name\" jsonschema:\"required,description=User's name\"`\n    Age      int      `json:\"age\" jsonschema:\"minimum=0,maximum=150\"`\n    Email    string   `json:\"email,omitempty\" jsonschema:\"format=email\"`\n    Tags     []string `json:\"tags,omitempty\" jsonschema:\"uniqueItems=true\"`\n    Active   bool     `json:\"active\" jsonschema:\"default=true\"`\n}\n```\n\n## Context Usage\n\nAlways respect context cancellation and deadlines:\n\n```go\nfunc LongRunningTool(ctx context.Context, req *mcp.CallToolRequest, input Input) (\n    *mcp.CallToolResult,\n    Output,\n    error,\n) {\n    select {\n    case \u003c-ctx.Done():\n        return nil, Output{}, ctx.Err()\n    case result := \u003c-performWork(ctx, input):\n        return nil, result, nil\n    }\n}\n```\n\n## Server Options\n\nConfigure server behavior with options:\n\n```go\noptions := \u0026mcp.Options{\n    Capabilities: \u0026mcp.ServerCapabilities{\n        Tools:     \u0026mcp.ToolsCapability{},\n        Resources: \u0026mcp.ResourcesCapability{\n            Subscribe: true, // Enable resource subscriptions\n        },\n        Prompts: \u0026mcp.PromptsCapability{},\n    },\n}\n\nserver := mcp.NewServer(\n    \u0026mcp.Implementation{Name: \"my-server\", Version: \"v1.0.0\"},\n    options,\n)\n```\n\n## Testing\n\nTest your MCP tools using standard Go testing patterns:\n\n```go\nfunc TestSearchTool(t *testing.T) {\n    ctx := context.Background()\n    input := ToolInput{Query: \"test\", Limit: 10}\n    \n    result, output, err := SearchTool(ctx, nil, input)\n    if err != nil {\n        t.Fatalf(\"SearchTool failed: %v\", err)\n    }\n    \n    if len(output.Results) == 0 {\n        t.Error(\"Expected results, got none\")\n    }\n}\n```\n\n## Module Setup\n\nInitialize your Go module properly:\n\n```bash\ngo mod init github.com/yourusername/yourserver\ngo get github.com/modelcontextprotocol/go-sdk@latest\n```\n\nYour `go.mod` should include:\n\n```go\nmodule github.com/yourusername/yourserver\n\ngo 1.23\n\nrequire github.com/modelcontextprotocol/go-sdk v1.0.0\n```\n\n## Common Patterns\n\n### Logging\n\nUse structured logging:\n\n```go\nimport \"log/slog\"\n\nlogger := slog.Default()\nlogger.Info(\"tool called\", \"name\", req.Params.Name, \"args\", req.Params.Arguments)\n```\n\n### Configuration\n\nUse environment variables or config files:\n\n```go\ntype Config struct {\n    ServerName string\n    Version    string\n    Port       int\n}\n\nfunc LoadConfig() *Config {\n    return \u0026Config{\n        ServerName: getEnv(\"SERVER_NAME\", \"my-server\"),\n        Version:    getEnv(\"VERSION\", \"v1.0.0\"),\n        Port:       getEnvInt(\"PORT\", 8080),\n    }\n}\n```\n\n### Graceful Shutdown\n\nHandle shutdown signals properly:\n\n```go\nctx, cancel := context.WithCancel(context.Background())\ndefer cancel()\n\nsigCh := make(chan os.Signal, 1)\nsignal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)\n\ngo func() {\n    \u003c-sigCh\n    cancel()\n}()\n\nif err := server.Run(ctx, transport); err != nil {\n    log.Fatal(err)\n}\n```\n","description":"Best practices and patterns for building Model Context Protocol (MCP) servers in Go using the official github.com/modelcontextprotocol/go-sdk package.","import":{"commit_sha":"541b7819d8c3545c6df122491af4fa1eae415779","imported_at":"2026-05-18T20:05:35Z","license_text":"MIT License\n\nCopyright GitHub, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","owner":"github","repo":"github/awesome-copilot","source_url":"https://github.com/github/awesome-copilot/blob/541b7819d8c3545c6df122491af4fa1eae415779/instructions/go-mcp-server.instructions.md"},"manifest":{}},"content_hash":[27,125,88,20,233,223,92,220,166,160,143,98,81,162,91,3,118,104,100,154,114,84,186,63,28,234,166,153,182,227,143,59],"trust_level":"unsigned","yanked":false}
