Я адчуваю, што мы знаходзімся ў пункце, дзе Мадэль Контекст Протокол (MCP) адчуваецца амаль сінонімам з GenAI інжынерства. Anthropic прадставіла MCP у лістападзе 2024, рэвалюцыянуючы GenAI інжынерства. Гэта прывёла нас да пункту, дзе, як інжынеры, мы можам рэалізаваць розныя інструменты на аснове нашага выкарыстання, і накіраваць LLM нашага выбору, каб выкарыстоўваць гэтыя інструменты з зручнасці нашых любімых IDEs або настольных кліентаў, як Клод. З таго часу, як яго з'яўлення, было шмат MCP сервераў, распрацаваных энтузіасты. Гэта было магчыма з-за хуткага развіцця MCP SDK на розных мовах, у тым ліку І І апошнім часам, І я бачыў, І я ведаў, што я магу ўзяць гэта для спіна! Пайтан Табліца Голан Гэтая афіцыйная прапанова для Golang SDK Што такое MCP, вы запрашаеце? Давайце пачнём з хуткага ўвядзення да MCP, які кароткі для Да нядаўняга часу, інжынерыя AI патрабавала уважлівай ацэнкі здольнасцяў розных LLMs, каб выбраць правільны. З MCP, вы можаце выбраць LLM вашага выбару, і пашыраць яго здольнасці, ужываючы нарматыўныя інструменты і падключаючыся да знешніх крыніц дадзеных самі! Model Context Protocol MCP кліент MCP серверы Дадатковыя магчымасці (даступныя інструменты, рэсурсы, рэсурсы) Вынікі LLM MCP сервер мае пэўныя магчымасці, якія вызначаюцца: Інструменты - Функцыі, якія ён можа выканаць, такія як спіс усіх электронных пошлін ад адсылальніка, пошук PR на Github рэсурсы - Знешні крыніца дадзеных, напрыклад, спіс дакументаў, якія вы хочаце, каб LLM звязацца Prompts - набор шаблонаў, якія дапамагаюць карыстальнікам атрымаць жаданыя адказы хутка Існуе шмат MCP сервераў ужо даступныя, якія вы можаце пачынаць выкарыстоўваць для вашых прыкладанняў. Вы можаце звярнуць увагу на гэтую зборку выдатных MCP сервераў: https://github.com/punkpeye/awesome-mcp-servers BYOM (Загрузіць свой MCP сервер) На сённяшні дзень мне цяжка нешта знайсці ў інтэрнэце або нешта з фільмаў, што мог бы праглядзець са спакойнай душой. . Загрузіць GitHub Цяпер я мог бы выкарыстоўваць афіцыйны сервер GitHub MCP, але хоць ён прапануе вялікі набор інструментаў для рэпазіторыяў і арганізацый, у яго не было правільнага інструмента для спісу ўсіх рэпазіторыяў у арганізацыі. Распрацоўка 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. Гэта можна зрабіць, рэалізаваючы інструмент тыпу ToolHandler, як забяспечваецца SDK. 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") } Стварэнне URL GitHub API з ўваходу на аснове 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" Адправіць заяву і атрымаць адказ 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) } Уступнае слова і пераклад Уладзіміра Правасуда. // Братэрства 87. 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 сервера, я выкарыстоўваю стадыё транспарт, які дазваляе серверм камунікаваць праз STDIN і STDOUT. Гэта стандартны падыход для локальных інтэграцый MCP з кліентамі, такімі як Claude Desktop або 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...") Вось так выглядае код з усім усяго: 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 Выкарыстанне сервера MCP з кліентам, як Claude Давайце паглядзім, як дадаць гэты сервер на рабочы стол Клода. Затым пераходзьце на Claude -> Settings -> Developer. Тут вы будзеце бачыць раздзел, які называецца Локальны серверы MCP. Націсніце на кнопку ніжэй, які называецца Edit Config. Гэта будзе адкрыць файл Claude config. Удакладніце файл, каб дадаць сервер MCP наступным чынам: { "mcpServers": { "demo-github-mcp": { "command": "/path/to/executable/generated/from/go build", "args": [] } } } Загрузіць прыкладанне Claude (У цяперашні час, гэта адзіны спосаб абнаўляць серверы MCP ў Claude) І цяпер прыйшоў час выпрабаваць гэта! List all repositories in the Kubernetes github org Клод прызнаў локальна працуючы сервер demo-github-mcp і спытаў, ці ён можа гэта выкарыстоўваць! Як толькі я пацвердзіў яго, Клод выпісваў рэпазіторыі ў органах і нават паказаў выкарыстаны інструмент (лісты-рэпазіторыі) на пачатку адказу: Мы бачылі, як мы можам распрацаваць просты сервер MCP, выкарыстоўваючы Golang, і выкарыстоўваць яго праз кліенты MCP, такіх як Claude! «Ах» час Калі я распрацоўваў гэты сервер, я працягваў пытаць сябе: "Калі я напішу код для спісу рэпаторый, што будзе рабіць LLM?", А потым раптам ён націснуў - LLM дазваляе сувязь з гэтым серверам праз натуральную мову! Калі Клод Соннет 4 прачытаў мой пампт - "Спіс усіх рэпазіторыяў у Kubernetes GitHub org" - і сам прызнаў, што локальна працуючы сервер MCP будзе працаваць найлепш для пампту, мой розум быў выпухнуты 😀 У той момант, я не маў даць яму ніякай інфармацыі пра назву інструмента або параметры, якія ён прыняў. Вытворчасць разгляду Хоць наш сервер MCP працуе добра для дэманстрацыйных целей, ёсць некалькі важных функцый, якія прапусцілі для вытворчага выкарыстання: Пераклад паўстаў у межах праекту «Homines Urbani» Таварыства «Villa Decius», Кракаў. Абмежаванне тарифаў: Вышэйшы код не ўлічвае ліміты тарифаў GitHub API Аўтэнтыфікацыя: Аўтэнтыфікаваныя запыты маюць вышэйшы ліміт працэнтаў, чым неаўтэнтыфікаваныя запыты. Аўтэнтыфікацыя патрабуецца таксама для запытаў у прыватныя рэпазітары GitHub / прадпрыемства GitHub. Што наступнага? Гэта дэма GitHub MCP сервер быў добрым стартам. Але асноўная прычына, што я пішу гэта, каб паказаць, як лёгка гэта можа быць, каб наладзіць ваш любімы GenAI інструмент да вашага любімасці! Гэта таксама выдатна проста, каб пачаць з MCP сервера ў Голангу для вашых уласных праектаў! Я не магу чакаць, каб убачыць магутныя паслугі, створаныя з сумяшчальнасці гнуткасці MCP і высокай прадукцыйнасці Голанга!