Waxaan ku dhigi karaa in ay ku saabsan Model Context Protocol (MCP) waa mid ka mid ah dhismaha injiilada GenAI. Anthropic ayaa soo bandhigay MCP in November 2024, waxa uu ku yaalaa injiilada GenAI. Waxaa ka mid ah in ay ka mid ah injiilada, sida injiilada, waxaan sidoo kale ku yaalaa qalabka kala duwan oo ku salaysan isticmaalka our, iyo ku yaalaa LLM ka mid ah injiilada la isticmaalaa in ay ka mid ah injiilada ah oo ka mid ah macluumaad ka mid ah IDEs ama macluumaadka desktop sida Claude. Si kastaba ha ahaatee, waxaa ka mid ah macluumaadka MCP oo loo isticmaalaa injiilada injiilada. Haku Sida loo yaabaa, Haku: Waxaan u aragto Waxaan ku dhaheenay in ay ku dhaheenay in ay ku dhaheenay in ay ku dhaheenay! QEEBE Haku Haku Waxaa laga yaabaa in ay ka mid ah dhismaha ugu horeysay ee Golang SDK. Ma rabtaa MCP? Waayo, waxaan ka soo bandhigay in la soo bandhigay MCP, oo waa mid ka mid ah mid ka mid ah Sida loo yaabaa, injiilada AI ayaa loo isticmaali karaa in ay ka mid ah wax soo saarka LLM-ka ah si ay u baahan tahay in ay ka mid ah wax soo saarka LLM-ka ah oo ka mid ah macluumaadka. Model Context Protocol Qalabka MCP Macluumaadka MCP Qalabka (Tools, Resources, Prompts) Qalabka LLM Macluumaadka MCP waa mid ka mid ah macluumaadka ka mid ah: Tools - Functions waa in aad u shaqeeyaan, sida list all emails from a sender, searchup a PR on Github Resources - Source data external, sida list of documents that you want the LLM to refer to Prompts - A set of templates which help users get desired answers fast Waxaa jira badan oo ka mid ah macluumaadka MCP oo ka mid ah macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Mac https://github.com/punkpeye/awesome-mcp-servers BYOM (Waaq u isticmaalaa MCP Server) In this post, waxaan ka heli karaa sida loo isticmaali karaa MCP server our ah oo loo isticmaali karaa Golang. Saacad ka hor, oo ka mid ah mid ka mid ah mid ah,n waxaan ka heli karaa oo dhan repositories ee . Ku saabsan GitHub Waxa uu u isticmaali karaa GitHub MCP Server ah, laakiin sidoo kale waxaa loo isticmaali karaa mid ka mid ah macluumaadka ugu fiican ee macluumaadka iyo shuruudaha, laakiin waxaa loo isticmaali karaa mid ka mid ah macluumaadka oo dhan ee shuruudaha ee shuruudaha. Shuruudaha MCP Server ee Golang Sida loo yaqaan Golang MCP SDK: The README iyo examples / folders waa mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah. https://github.com/modelcontextprotocol/go-sdk Sida loo yaqaan MCP Server waxaa loo isticmaali karaa: server := mcp.NewServer(&mcp.Implementation{ Name: "demo-github-mcp", Title: "A demo github mcp server", Version: "0.0.1", }, nil) Sida loo yaqaan "GitHub" waxaa loo yaqaan "GitHub" iyo "ToolHandler" waxaa loo yaqaan "ToolHandler" sida loo yaqaan "SDK". type ToolHandlerFor[In, Out any] func(context.Context, *ServerSession, *CallToolParamsFor[In]) (*CallToolResultFor[Out], error) Sida loo yaabaa, waxaa loo yaqaan 'A Tool, oo ay ku xiran tahay argumento badan oo ka mid ah Github org: 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: Verification Input to ensure that we only accept valid arguments if params == nil { return nil, fmt.Errorf("empty params") } args := params.Arguments if args.Name == "" && args.URL == "" { return nil, fmt.Errorf("empty args") } URL-ka GitHub API waxaa loo isticmaali karaa ku saabsan 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" Waayo, waxaa loo yaabaa in la soo xiriir. 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)) } Nala soo xiriir 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) } Xirfadeed oo ka mid ah textual 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 Ka dib markii loo isticmaali karaa, waxaa laga yaabaa in la isticmaali karaa server MCP: 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) Sidaas, waxaa laga yaabaa in la yaabaa server! For this demo MCP server, I am using the stdio transport, which allows the server to communicate via STDIN and STDOUT. This is the standard approach for local MCP integrations with clients such as Claude Desktop or 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...") Sidee waa mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ka mid ah mid ah mid ka mid ah mid ah mid ka mid ah mid ah mid ka mid ah mid ah mid ah mid ka mid ah mid ah mid ka mid ah mid ah mid ka mid ah mid ah: 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 } Sida loo yaabaa, waxaa loo isticmaali karaa in ay ka mid ah mid ka mid ah: go build Sida loo isticmaalo server MCP iyo client sida Claude Waayo, si ay u aragtiyo in ay u aragtiyaan server Claude's desktop. Waayo, waxaa laga yaabaa in ay ku yaalaa Claude -> Settings -> Developer. Sida loo yaqaan "Local MCP Servers" waxaa laga yaqaan "Edit Config" oo loo yaqaan "Local MCP Servers". Nala soo xiriir in la soo xiriir MCP Server: { "mcpServers": { "demo-github-mcp": { "command": "/path/to/executable/generated/from/go build", "args": [] } } } Ma rabtaa app Claude (wax yar, this is the only way to refresh MCP servers within Claude) Waxaad ka soo bandhigay in la soo bandhigay!This is the prompt I gave: List all repositories in the Kubernetes github org Claude wuxuu ku yaalaa server demo-github-mcp ah oo loo isticmaali karaa! Markaad ka mid ah in la soo bandhigiisa, Claude la soo bandhigiisa repositories ee org iyo sidoo kale soo bandhigiisa loo isticmaalo (list-repositories) ka dib markii la soo bandhigiisa: Waayo, waxaan ka mid ahaysaa in ay loo isticmaali karaa server MCP ah oo loo isticmaali karaa Golang, iyo loo isticmaali karaa via client MCP sida Claude! Waayo, “Aha” Sida loo soo saarka server this, waxaan ku yidhi, "If I'm writing the code for listing repositories, what's the LLM going to do?" oo ka mid ah oo ka mid ah oo ka mid ah oo ka mid ah oo ka mid ah oo ka mid ah oo ka mid ah oo ka mid ah oo ka mid ah. Markaas Claude Sonnet 4 wuxuu ka soo xiriir in aad u soo xiriir - "Lista all repositories in the Kubernetes GitHub org" - oo ka mid ah si ay u ahaysaa in ay macluumaadka MCP ah oo loo isticmaali karaa in aad u isticmaali karaa in aad u isticmaali karaa, fikradda ah oo aad u isticmaali karaa 😀. Qalabka Production Markaad ka mid ah macluumaadka macluumaadka MCP waa mid ka mid ah macluumaadka macluumaadka macluumaadka macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Macluumaadka Maclu Pagination hantida: API GitHub waxay ku yaalaa resultanka paginated, xawaaraha waa 30 entries per page. In codka ugu horeysay waxaan ku yaalaa in la 100 oo ka mid ah parameter query per_page. Rate limiting: codka ugu horeysay waxay ka mid ah qiyaasta API GitHub Authentication: Waqtiga authenticated waxay ka mid ah xafiisyada ugu badan oo ku saabsan waqtiga non-authenticated. Authentication waxaa sidoo kale loo isticmaali karaa waqtiga GitHub kala duwan / shirkadaha GitHub. Ma rabtaa wax soo saarka? Dhismaha GitHub MCP Server waxaa laga yaabaa in la soo bandhigay, laakiin xawaaraha ugu horeysay ee loo yaqaan this waa in la soo bandhigay in ay ku habboonay macluumaadka GenAI ah oo aad u caawinayo! Waxaa sidoo kale waxaa laga yaabaa in ay ku habboonay macluumaadka MCP ee Golang oo loo yaqaan MCP Server for your own projects! Waxaan sidoo kale ka soo bandhigay in la soo bandhigay macluumaadka MCP iyo kharashka sare ee Golang!