Би мэдэж байна уу, бид Model Context Protocol (MCP) GenAI инженерийн хувьд хоорондоо мэдэж байгаа үед байна. Anthropic GenAI инженерийн шинэчлэхэд 2024 оны нэгдүгээр сарын MCP-ийг танилцуулж байна. Энэ нь инженерийн хувьд бид хэрэглээний тохиолдолд суурилсан янз бүрийн арга хэрэгсэл ашиглах боломжтой бөгөөд бидний сонголттай LLM-ийг бидний дуртай IDEs, эсвэл Claude гэх мэт ширээний хэрэглэгчдийн тавтай морилноос энэ арга хэрэгслүүдийг ашиглах боломжтой. Түүнээс хойш олон MCP серверүүд энтузийн инженерийн боловсруулсан байна. Энэ нь олон хэл дээр MCP SDK-ийг хурдан хөгжүүлэхэд боломжийг олгодог. Нөхцөл Хамгийн сүүлийн үеийн, . (yay ) Би үзсэн , болон би үүнийг spin нь авах ёстой гэж мэдэсэн! Байрлал Татаж авах Өнгөрсөн Golang SDK-ийн албан ёсны санал MCP нь юу вэ, та хүсч байна уу? Бид MCP-ийг хурдан танилцуулахын тулд эхэлнэ үү, энэ нь . Хамгийн сүүлийн үеийн хүртэл AI инженерийн янз бүрийн LLM-ийн хүчин чадал, зөв нэг сонгох талаар анхааралтай үнэлгээ хэрэгтэй. MCP нь та өөрийн сонголттай LLM-ийг сонгож, өөрчилсөн хэрэгслүүдийг имплементийг ашиглаж, өөрчилсөн өгөгдлийн эх үүсвэртэй холбогдсон болно! Протокол нь гол бүтэц: Model Context Protocol MCP Клиент MCP сервер Ажлын хүчин чадал (Ажлын хэрэгсэл, ресурс, Prompts) Илүү LLM MCP сервер нь зарим чадвартай байдаг: Ажлын хэрэгсэл - Энэ нь үйл ажиллагаа явуулж болно, жишээ нь дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн дараагийн Resources - Эдүүлбэртэй өгөгдлийн эх сурвалж, жишээ нь та LLM-ийг харж хүсэж байгаа документын жагсаалт Prompts - хэрэглэгчид хурдан хүссэн хариу авах туслах шаблон багц Та өөрийн хэрэглээнд ашиглахыг эхлэх боломжтой олон MCP серверүүд байдаг. Та гайхалтай MCP серверүүдээс энэ цуглуулгыг харж болно: https://github.com/punkpeye/awesome-mcp-servers BYOM (Our Own MCP Server) Энэ нийтлэлд, би бидний өөрийн MCP сервер Golang ашиглан хөгжүүлэх вэбсайтад дамжуулахыг хүсч байна. Хоёр хоногийн өмнө, ямар ч шалтгаан нь,n Би энэ дахь бүх репозиторийг дамжуулах хүссэн . Kubernetes GitHub орг Одоо би албан ёсны GitHub MCP сервер ашиглаж болох боловч энэ нь репозиторын болон байгууллагад маш сайн хэрэгсэл багц санал болгож байгаа боловч энэ нь аж ахуйн нэгжийн бүх репозиторын жагсаалтыг жагсаалтын шууд хэрэгсэлгүй байсан. Энэ нь Golang-ийг ашиглах үед хэрэглэгддэг тодорхой хэрэгсэл нь MCP серверг боловсруулсан вэ? Golang-д MCP сервер хөгжүүлэх Энэ нь албан ёсны Golang MCP SDK юм: README болон жишээ / хуудсууд нь MCP сервер, клиент хөгжүүлэх талаар сайн жишээг агуулдаг. https://github.com/modelcontextprotocol/go-sdk Эдүүлбэрээр, би MCP сервер үүсгэхийн тулд дараах зорилготой байна: server := mcp.NewServer(&mcp.Implementation{ Name: "demo-github-mcp", Title: "A demo github mcp server", Version: "0.0.1", }, nil) Дараа нь сервер нь GitHub org-д бүх репозиторын жагсаалтыг жагсаалтын боломжийг олгож байна. Энэ нь SDK-ийн санал болгож буй ToolHandler төрөл хэрэгсэл ашиглаж болно. type ToolHandlerFor[In, Out any] func(context.Context, *ServerSession, *CallToolParamsFor[In]) (*CallToolResultFor[Out], error) Дараа нь, би үүсгэсэн програм хангамж, 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: Тавтай морилно уу, бид зөвхөн тохиромжтой аргументийг хүлээн зөвшөөрч байна if params == nil { return nil, fmt.Errorf("empty params") } args := params.Arguments if args.Name == "" && args.URL == "" { return nil, fmt.Errorf("empty args") } GitHub API-ийн URL-ийг GitHub API-ийн докторууд дээр суурилсан хандах 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)) } 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) } Сэтгэгдэл нь текст хэлбэрээр дамжуулах 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 хэрэгсэл тодорхойлолсон дараа дараагийн арга нь 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) Дараа нь сервер эхлэх цаг байна! Энэ демо MCP сервер, би stdio тээвэрлэлт ашиглаж байна, энэ нь сервер STDIN болон STDOUT дамжуулан холбох боломжийг олгодог. Энэ нь Claude Desktop эсвэл VSCode гэх мэт клиенттай орон нутгийн MCP интеграцийг стандарт арга юм. 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...") Эдгээр нь кодыг нэгтгэсэн бүх зүйлтэй харуулж байна: 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 } Одоо эцсийн үйл явдал нь энэ нь компилийг бий болгох, дараа нь гүйцэтгэлийг үүсгэх болно: go build Claude гэх мэт клиенттай MCP сервер ашиглах Бид Claude's Desktop-д энэ сервер нэмнэ үү. Клод ширээний програм хангамжийг нээж, Клод -> Татаж авах -> Developer. Энд та Local MCP Server гэж нэрлэгддэг хэсэг үзнэ үү. Доорх товч дээр дарна уу Edit Config. Энэ нь Claude config файлыг нээж болно. MCP сервер нэмэх файлын редактийг дараах хэлбэрээр хуваалцах: { "mcpServers": { "demo-github-mcp": { "command": "/path/to/executable/generated/from/go build", "args": [] } } } Claude-ийн програмыг шинэчлэх (Энэ нь Claude-ийн дотор MCP серверүүд шинэчлэх нь зөвхөн арга юм) Тэгээд одоо энэ нь туршиж цаг байна! Эдгээр нь тавтай морилно уу: List all repositories in the Kubernetes github org Клод орон нутгийн ажиллуулсан демо-github-mcp серверийг мэдэгдсэн бөгөөд энэ нь ашиглаж чадна уу! Би үүнийг хүлээн зөвшөөрсөн үед Клод орг-д репозиторын жагсаалтыг жагсаалтаас ашигласан хэрэгсэл (лист-репозиторын жагсаалтаас) санал болгож байна: Бид Golang ашиглан хялбар MCP сервер хөгжүүлэх, Claude гэх мэт MCP клиент дамжуулан ашиглаж болохыг харуулж байна! Өнгөрсөн цаг “AHA” Би энэ сервер боловсруулсан үед би үүнийг асуултанд байлгав: "Би репозиторын жагсаалтын код бичдэг бол LLM нь юу хийх болно?" Клод Sonnet 4 нь "Kubernetes GitHub org-д бүх репозиторын жагсаалтыг жагсаалтаас" -ийг уншиж, орон сууцны MCP сервер нь зөвлөгөөний хувьд хамгийн сайн ажилладаг гэж мэдэгдэж байгаа үед, миний мэдрэмжийг бэхжүүлсэн байна 😀 Энэ үед, би хэрэгсэл нэр, энэ нь хүлээн зөвшөөрсөн параметрүүд талаар ямар ч мэдээллийг хангах хэрэгтэй байсан. Би энгийн хэлбэрийн дамжуулан миний асуултанд асуултанд асуултад, энэ нь ашиглах хэрэгсэл, хэрэгсэл гэж нэрлэдэг талаар мэдэгдэж байна, ажил хийж байна! Бүтээгдэхүүний асуултууд Манай MCP сервер нь демо зорилгоор маш сайн ажилладаг боловч үйлдвэрлэлийн хэрэглээний хувьд хэд хэдэн чухал шинж чанартай байдаг: Pagination гарын авлага: GitHub-ийн API-ийн хуудсыг хуудсан үр дүнд дамжуулдаг. Үүнээс дээш кодд би per_page асуултын параметр нь 100 хүртэл нэмэгдэж байна. Бүтээгдэхүүний код нь дараагийн хуудсууд болон нийт хуудсуудтай талаархи мэдээлэл авахын тулд Reply Header Link-ийг боловсруулсан болно. (Энэ үүнийг үзнэ үү) Үнэлгээний хязгаарлалт: Үнэлгээний код нь GitHub API-ийн Үнэлгээний хязгаарлалттай. Автентичлал: Автентичлалтай асуултууд нь автентичлалгүй асуултуудтай харьцуулахад өндөр түвшинд байдаг. Автентичлалтай асуултууд нь хувийн GitHub репозиториуд / аж ахуйн нэгжийн GitHub-д шаардлагатай. Дараа нь юу вэ? Энэ GitHub MCP сервер нь сайн эхлэл байсан. Гэхдээ би энэ бичдэг гол шалтгаан нь таны дуртай GenAI хэрэгсэл таны дуртай болгон өөрчилж хэрхэн хялбар байж болохыг харуулж байна! Энэ нь Golang-д MCP сервер нь өөрийн төслийг эхлэх нь гайхамшигтай хялбар юм! Би MCP-ийн хялбар байдал, Golang-ийн өндөр гүйцэтгэлийн шинж чанарыг хослуулсан хүчтэй үйлчилгээг үзэх чадахгүй байна!