Ngingathanda ukuthi siphinde lapho i-Model Context Protocol (MCP) ibonise cishe i-synonymum ye-GenAI engineering. I-Anthropic ibonise i-MCP ngo-Novemba 2024, okuguqulwa i-GenAI engineering. Yenza nathi kwindawo lapho, njengama-engineers, singathola izixhobo ezihlukahlukene ngokuvumelana ne-use case yethu, futhi ukulawula i-LLM yayo yokusebenzisa izixhobo ezivamile ezivela kumakhasimende ethu adumile noma i-desktop client efana ne-Claude. Ngemuva kokufika kwalo, kukhona amasevisi eziningi ze-MCP ezivela kumadivayisi amakhulu. Lokhu kunokwenzeka ngenxa yokuthuthukiswa okusheshayo kwe-MCP SDK ngezilimi ezahlukene, kuhlanganise Ngena ngemva Ngaphezu kwalokho, . (yay ) Ngithanda , futhi ngazi ukuthi kufanele ukuthatha ngoba spin! Ngena ngemvume Ukuhlobisa Ukuhlobisa Umhlahlandlela we-Golang SDK Yini i-MCP, ungathanda? Thola kuqala ngokushesha ukuhlaziywa kwe-MCP, okuyinto encane Ngaphezu kwalokho, umkhakha we-AI wahlanganyela ukubuyekeza ngokucindezeleka kwezidingo ze-LLM ahlukahlukene ukuze ukhethe i-right one. Nge-MCP, ungakwazi ukhethe i-LLM lapho ukhethe, futhi ukwandisa izinzuzo zayo ngokuvumela izixhobo ezizodwa kanye nokuxhumana ngezithombe ze-Data ze-external ngokwayo! Izakhiwo eziyinhloko ze-protocol zihlanganisa: Model Context Protocol Ikhasimende MCP Ukusebenza kwe-MCP Server Izinzuzo (Izinzuzo, Izinzuzo, Izinzuzo) Umhlahlandlela I-Server ye-MCP inesibopho ezithile ezidlulele ngokuvamile: Izinsiza - Izinsiza zokusebenza, njenge-listing zonke i-imeyili kusuka ku-sender, searchup a PR ku-Github Umthombo - Umthombo we-Data e-External, njenge-list ye-documents ukuthi ufuna ukuba i-LLM uqhagamshelane Prompts - Isithombe se-templates esiza kubasebenzisi ukuthola imibuzo eyenziwe ngokushesha Kukho amasevisi eziningi ze-MCP ezokufinyelela ukuthi ungasebenzisa izicelo zakho. Ungasebenzisa lokhu ukubuyekezwa kwe-MCP servers emangalisayo: https://github.com/punkpeye/awesome-mcp-servers I-BYOM (Ukuvelisa inkonzo yakho ye-MCP) Kule post, Ngingathanda ukuthi singathanda indlela yokuthuthukisa inkonzo yethu MCP usebenzisa Golang. Izinsuku ezingu-suku, ngenxa ye-reaso,n Ngingathanda zonke ama-repositories e-Golang. . Kubernetes I-GitHub org Ngingathanda ukuyisebenzisa i-GitHub MCP server esemthethweni, kodwa uma inikeza isixhobo esihle ye-repositories kanye nezinhlangano, ayikho isixhobo esizayo yokufaka zonke i-repositories e-organisations. Ngakho-ke lokhu kubonakala njengesikhathi esihle yokufundisa indlela yokuthuthukisa i-MCP server ye-tool esifundeni esifunayo lapho usebenzisa i-Golan. Ukukhishwa kwe-MCP Server e Golang Ngiyazi i-Golang MCP SDK: I-README kanye ne-examples/folders zihlanganisa izibonelo ezinhle zokuthuthukiswa kwe-MCP server kanye ne-client. https://github.com/modelcontextprotocol/go-sdk Ngemuva kwezi zibonelo, ngithanda ukwenza i-MCP server efanayo: server := mcp.NewServer(&mcp.Implementation{ Name: "demo-github-mcp", Title: "A demo github mcp server", Version: "0.0.1", }, nil) Isinyathelo esilandelayo kuyinto ukunikezela i-server ne-capability yokubonisa zonke i-repositories ku-GitHub org. Lokhu kungenziwa ngokuvumela isixhobo se-ToolHandler efana ne-SDK type ToolHandlerFor[In, Out any] func(context.Context, *ServerSession, *CallToolParamsFor[In]) (*CallToolResultFor[Out], error) Ngemuva kwalokho, i-a isixhobo, okuvumela i-arguments ezilandelayo ezihlobene ne-Github org njenge-input: ListRepositories // User can pass in either the name of the org (example: kubernetes), or its URL (example: https://github.com/kubernetes) type GithubOrgArgs struct { Name string URL string } func ListRepositories(ctx context.Context, ss *mcp.ServerSession, params *mcp.CallToolParamsFor[GithubOrgArgs]) (*mcp.CallToolResultFor[struct{}], error) { Now let's go over the body of ListRepositories step-by-step: Ukubuyekezwa ku-Input ukuqinisekisa ukuthi sincoma kuphela ama-arguments asebenzayo if params == nil { return nil, fmt.Errorf("empty params") } args := params.Arguments if args.Name == "" && args.URL == "" { return nil, fmt.Errorf("empty args") } Ukwakha i-GitHub API URL kusuka ku-input esekelwe ku-GitHub API docs var apiURL string var organization string if args.URL != "" { // If URL is provided, extract org name and build API URL url := strings.TrimPrefix(args.URL, "https://") url = strings.TrimPrefix(url, "http://") url = strings.TrimPrefix(url, "github.com/") url = strings.TrimSuffix(url, "/") orgName := strings.Split(url, "/")[0] apiURL = fmt.Sprintf("https://api.github.com/orgs/%s/repos", orgName) organization = orgName } else { // Use the provided organization name apiURL = fmt.Sprintf("https://api.github.com/orgs/%s/repos", args.Name) organization = args.Name } apiURL = apiURL + "?per_page=100" Thumela isicelo futhi ufumane impendulo client := &http.Client{Timeout: 10 * time.Second} req, err := http.NewRequestWithContext(ctx, "GET", apiURL, nil) if err != nil { return nil, err } req.Header.Add("Accept", "application/vnd.github.v3+json") resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) return nil, fmt.Errorf("GitHub API error (status %d): %s", resp.StatusCode, string(body)) } Ukubhalisa impendulo kusuka ku-GitHub API type repository struct { Name string `json:"name"` FullName string `json:"full_name"` HTMLURL string `json:"html_url"` Private bool `json:"private"` } // Parse the JSON response var repositories []repository if err := json.NewDecoder(resp.Body).Decode(&repositories); err != nil { return nil, fmt.Errorf("failed to parse response: %w", err) } Thumela isibuyekezo njenge-text context var result strings.Builder result.WriteString(fmt.Sprintf("Repositories for organization %s:", organization)) for _, repo := range repositories { result.WriteString(fmt.Sprintf("Name: %s, URL: %s", repo.Name, repo.HTMLURL)) } return &mcp.CallToolResultFor[struct{}]{ Content: []mcp.Content{ &mcp.TextContent{Text: result.String()}, }, }, nil Ngemva kokufaka isixhobo, isinyathelo esilandelayo kuyinto ukuhlasela ku-MCP server: mcp.AddTool(server, &mcp.Tool{ Name: "list-repositories", Description: "A tool to list all repositories in a Github org", InputSchema: &jsonschema.Schema{ Type: "object", Properties: map[string]*jsonschema.Schema{ "name": { Type: "string", Description: "GitHub organization name (e.g., kubernetes)", }, "url": { Type: "string", Description: "GitHub organization URL (e.g., https://github.com/kubernetes)", }, }, }, }, ListRepositories) Okulandelayo, iye isikhathi yokuhamba i-server! Ukuze le demo ye-MCP server, ngisebenzisa i-stdio transport, okuyinto ivumela i-server ukuxhumana nge-STDIN ne-STDOUT. Lokhu kuyinto indlela esisodwa yokuxhumana kwe-MCP yendawo nge-clients efana ne-Claude Desktop noma i-VSCode. t := mcp.NewLoggingTransport(mcp.NewStdioTransport(), os.Stderr) log.Println("🚀 MCP server starting up...") if err := server.Run(context.Background(), t); err != nil { log.Printf("Server failed: %v", err) } log.Println("🚀 MCP server shutting down...") Ngiyazi indlela ikhowudi nge-ke yonke into efakwe: func main() { server := mcp.NewServer(&mcp.Implementation{ Name: "demo-github-mcp", Title: "A demo github mcp server", Version: "0.0.1", }, nil) mcp.AddTool(server, &mcp.Tool{ Name: "list-repositories", Description: "A tool to list all repositories in a Github org", InputSchema: &jsonschema.Schema{ Type: "object", Properties: map[string]*jsonschema.Schema{ "name": { Type: "string", Description: "GitHub organization name (e.g., kubernetes)", }, "url": { Type: "string", Description: "GitHub organization URL (e.g., https://github.com/kubernetes)", }, }, }, }, ListRepositories) t := mcp.NewLoggingTransport(mcp.NewStdioTransport(), os.Stderr) log.Println("🚀 MCP server starting up...") if err := server.Run(context.Background(), t); err != nil { log.Printf("Server failed: %v", err) } log.Println("🚀 MCP server shutting down...") } type GithubOrgArgs struct { Name string URL string } func ListRepositories(ctx context.Context, ss *mcp.ServerSession, params *mcp.CallToolParamsFor[GithubOrgArgs]) (*mcp.CallToolResultFor[struct{}], error) { if params == nil { return nil, fmt.Errorf("empty params") } args := params.Arguments if args.Name == "" && args.URL == "" { return nil, fmt.Errorf("empty args") } var apiURL string var organization string if args.URL != "" { // If URL is provided, extract org name and build API URL url := strings.TrimPrefix(args.URL, "https://") url = strings.TrimPrefix(url, "http://") url = strings.TrimPrefix(url, "github.com/") url = strings.TrimSuffix(url, "/") orgName := strings.Split(url, "/")[0] apiURL = fmt.Sprintf("https://api.github.com/orgs/%s/repos", orgName) organization = orgName } else { // Use the provided organization name apiURL = fmt.Sprintf("https://api.github.com/orgs/%s/repos", args.Name) organization = args.Name } apiURL = apiURL + "?per_page=100" client := &http.Client{Timeout: 10 * time.Second} req, err := http.NewRequestWithContext(ctx, "GET", apiURL, nil) if err != nil { return nil, err } req.Header.Add("Accept", "application/vnd.github.v3+json") resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) return nil, fmt.Errorf("GitHub API error (status %d): %s", resp.StatusCode, string(body)) } type repository struct { Name string `json:"name"` FullName string `json:"full_name"` HTMLURL string `json:"html_url"` Private bool `json:"private"` } // Parse the JSON response var repositories []repository if err := json.NewDecoder(resp.Body).Decode(&repositories); err != nil { return nil, fmt.Errorf("failed to parse response: %w", err) } var result strings.Builder result.WriteString(fmt.Sprintf("Repositories for organization %s:", organization)) for _, repo := range repositories { result.WriteString(fmt.Sprintf("Name: %s, URL: %s", repo.Name, repo.HTMLURL)) } return &mcp.CallToolResultFor[struct{}]{ Content: []mcp.Content{ &mcp.TextContent{Text: result.String()}, }, }, nil } Now the end step is to compile this and generate the executable with: go build Ukusetshenziswa kwe-MCP server nge-client efana ne-Claude Sishayele kanjani ukulanda le server ku-desktop ye-Claude. Khangisa isicelo se-Cloude desktop, bese uye ku-Cloude -> Settings -> Developer. Ngiya kuba ingxenye ebizwa ngokuthi Local MCP Servers. Cishe ingcindezi ngezansi ebizwa ngokuthi Edit Config. Lokhu kuyavula ifayela Claude config. Ukuguqulwa ifayela ukongeza i-server ye-MCP ngokuvamile: { "mcpServers": { "demo-github-mcp": { "command": "/path/to/executable/generated/from/go build", "args": [] } } } Re-Start Claude app (Kwangathi, lokhu kuphela indlela yokushicilela MCP servers ngaphakathi Claude) Futhi manje ixesha ukuhlola lokhu! Ngiyazi i-prompt yam: List all repositories in the Kubernetes github org U-Claude wahlola i-demo-github-mcp ye-server esebenza ngokulandelanayo futhi wabhala ukuba ingasebenzisa lokhu! Ngemuva kokubuyekezwa, u-Claude wahlala ama-repositories e-org kanye nokuvumela isixhobo esebenzayo (i-list-repositories) ekuqaleni kokuphendula: Futhi lapho siphinde! Sithole ukuthi singakwazi ukukhiqiza inkonzo MCP elula usebenzisa Golang, futhi usebenzisa ngokusebenzisa amakhasimende MCP ezifana Claude! I-”AHA” isikhathi Njengoba ngithuthukisa le server, ngithanda ngokuvamile: "Uma ngifake ikhodi yokubhalisa i-repositories, ukuthi i-LLM uya ukwenza?", Futhi ngethuba ngempumelelo - i-LLM ivumela ukuxhumana kule server nge-language yamanani! Uma Claude Sonnet 4 ukhangela inguqulo yami - "Ukuhlola zonke izikhwama ku Kubernetes GitHub org" - futhi ngokuzimela ukuthi i-locally-running MCP server iyasebenza okwenziwe ngempumelelo, umqondo yami walahlehlwe 😀 Kule isikhathi, angafuna ukunikezela nayiphi na ulwazi mayelana ne-tool name noma ama-parametres esidumile. Ngithole imibuzo yami nge-phrase elula, futhi lithole ukuthi isixhobo ukusetshenziswa, indlela yokufaka isixhobo, futhi ngithole umsebenzi! Imibuzo yokukhiqiza Nangona inkonzo yethu ye-MCP iyasebenza kahle ngenxa ye-demo, kukhona izici eziningana ezinzima ezingenalutho zokukhiqiza: Ukusetshenziswa kwe-pagination: I-API ye-GitHub ivumela imiphumela e-paginated, isizukulwane se-default angama-30 ngamaphepha. Kwi-code angaphambili ngama-100 nge-parameter ye-per_page isixazululo. Ukuze kusetshenziswe ikhodi yokukhiqiza, uzodingeka isithombe se-response Link ukuze uthole ulwazi mayelana ne-page elilandelayo kanye nenani lokuxhumana. (Ukuqondisa lokhu) I-rate limiting: I-code eyinhloko ayihlanganisa ama-GitHub API rate limits Ukubhalisa: Izicelo zokubhalisa zihlanganisa isivinini esikhulu kunezidingo zokubhalisa. Ukubhalisa kunezidingo zokubhalisa ku-Private GitHub repositories/enterprise GitHub. Yini elandelayo? U-Demo ye-GitHub MCP Server iyona lokuqala enhle. Kodwa ingxenye yokuqala lapho ngifofoza lokhu kubonisa ukuthi kungcono ukuthi kungcono ukucubungula isixhobo sakho esidumile ye-GenAI lapho uya khona! Kuyinto enhle kakhulu ukuqala nge-server ye-MCP e-Golang kumeprojekthi yakho! Ngingathanda ukubona izinsizakalo ezinzima ezivela kuhlanganiswa kwe-flexibility ye-MCP ne-Golang!