К основному содержанию
скилл CX Codex

go-grpc — скилл для Claude Code: gRPC-сервисы на Go

Скилл для ИИ-агента, который ведёт разработку gRPC-сервисов на Go: proto-контракты, коды ошибок, дедлайны, интерцепторы и стриминг.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add eduardo-sl/go-agent-skills --skill go-grpc -a claude-code
Открыть на GitHub

Что делает go-grpc

Скилл даёт агенту набор правил для gRPC в Go. Версия пакета ставится в имя (payment.v1), теги полей не переиспользуются, под каждый RPC заводится своя пара Request/Response. Сгенерированный код коммитится, а buf lint и buf breaking в CI ловят переименованные поля до того, как их увидит клиент.

Ошибки возвращаются через status.Error с маппингом доменных ошибок в одном месте: NotFound, AlreadyExists, InvalidArgument против FailedPrecondition, Unavailable для повторов. Клиент разбирает код через status.FromError, а не текст сообщения. Дедлайн ставится на каждый вызов, и ctx передаётся дальше в БД и другие RPC — иначе отмена не дойдёт до конца цепочки.

Кросс-заботы выносятся в интерцепторы: recovery снаружи, потом логирование, потом авторизация. Для стриминга есть параллельные StreamInterceptor. Тесты идут через bufconn с боевыми интерцепторами и без сети. Для работы нужен тулчейн Go, а кодогенерация требует protoc или buf — без них шаг сборки не пройдёт.

Какие задачи решает

  • спроектировать proto-контракт с версионированием пакета
  • свести доменные ошибки к gRPC-кодам в одном месте
  • расставить дедлайны и пробросить отмену вниз по вызовам
  • вынести логирование и авторизацию в интерцепторы
  • протестировать сервис через bufconn без сети

Примеры запросов агенту

  • Спроектируй proto для сервиса платежей с версией в имени пакета
  • Разложи доменные ошибки по gRPC-кодам через status.Error
  • Напиши серверный стриминг с завершением по ctx.Done()

Как установить go-grpc

1Через Skills CLI (Vercel)

npx skills add eduardo-sl/go-agent-skills --skill go-grpc -a claude-code

2Вручную: положить файлы

~/.claude/skills/go-grpc/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/go-grpc/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о go-grpc

Как установить go-grpc в Claude Code?

Выполните npx skills add eduardo-sl/go-agent-skills --skill go-grpc -a claude-code. Скилл появится в ~/.claude/skills/go-grpc/SKILL.md.

Что делает go-grpc?

Задаёт агенту правила разработки gRPC-сервисов на Go: дизайн proto, коды ошибок, дедлайны, интерцепторы, стриминг и тесты через bufconn.

Что нужно для работы скилла?

Тулчейн Go, а для генерации кода — protoc или buf. Скилл рассчитан на Claude и другие агенты для Go-проектов.

Исходный текст

SKILL.md · MIT
---
name: go-grpc
description: >
  gRPC services in Go beyond the basics: proto design, status codes and
  error details, interceptors, deadlines, streaming, health checks, and
  graceful shutdown. Use when: "gRPC service", "proto design", "gRPC error
  handling", "interceptor", "gRPC streaming", "gRPC deadline", "grpc health
  check", "gRPC status codes".
  Not for: REST handlers (go-api-design), protobuf-agnostic layering
  (go-architecture-review), TLS hardening (go-security-audit).
user-invocable: true
license: MIT
compatibility: Designed for Claude Code or similar AI coding agents working on Go projects. Requires the Go toolchain. Requires protoc or buf for code generation.
allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(gofmt:*) Bash(protoc:*) Bash(buf:*)
metadata:
  author: eduardo-sl
  version: "1.4.0"
---

# Go gRPC Services

gRPC's contract-first model only pays off if the contract is treated as
an API: versioned packages, deliberate error codes, deadlines
everywhere, and interceptors for everything cross-cutting.

Detailed reference material, loaded on demand:

- `references/clients.md` — `NewClient`, service-config retries and load
  balancing, keepalive on both sides, reading status codes.
- `references/testing.md` — in-memory `bufconn` server and client,
  asserting status codes.

Read a reference file only when the summary below is not enough.

## 1. Proto Design Rules

```protobuf
syntax = "proto3";

package payment.v1;                            // version IN the package
option go_package = "github.com/acme/payment-service/gen/payment/v1;paymentv1";

service PaymentService {
  rpc CreatePayment(CreatePaymentRequest) returns (CreatePaymentResponse);
}

message CreatePaymentRequest {                 // one request/response pair
  string order_id = 1;                         // per RPC, always — even if
  int64 amount_cents = 2;                      // empty today
}

message CreatePaymentResponse {
  Payment payment = 1;
}
```

- Version in the package (`payment.v1`); breaking change = `payment.v2`.
- Never reuse or renumber field tags; `reserved 3, 7;` deleted ones.
- Dedicated Request/Response messages per RPC — adding a field later is
  free; changing a shared message breaks every RPC using it.
- Generate with buf or a pinned protoc in `make generate`; commit
  generated code so builds don't depend on toolchain drift.
- In CI, `buf lint` and `buf breaking --against '.git#branch=main'` stop
  renumbered fields and removed RPCs before they reach a client.
  Field rules (lengths, ranges, formats) belong in protovalidate
  annotations, enforced by an interceptor.

## 2. Errors: Status Codes, Not Strings

Return `status.Error`, mapping domain errors in ONE place:

```go
func (s *Server) CreatePayment(ctx context.Context, req *pb.CreatePaymentRequest) (*pb.CreatePaymentResponse, error) {
    p, err := s.svc.Create(ctx, toDomain(req))
    if err != nil {
        return nil, toStatus(err)
    }
    return &pb.CreatePaymentResponse{Payment: fromDomain(p)}, nil
}

func toStatus(err error) error {
    switch {
    case errors.Is(err, domain.ErrNotFound):
        return status.Error(codes.NotFound, "payment not found")
    case errors.Is(err, domain.ErrDuplicate):
        return status.Error(codes.AlreadyExists, "payment already exists")
    case errors.Is(err, context.DeadlineExceeded):
        return status.Error(codes.DeadlineExceeded, "timed out")
    default:
        return status.Error(codes.Internal, "internal error") // no details leak
    }
}
```

Code semantics that matter: `InvalidArgument` (bad request regardless
of state), `FailedPrecondition` (bad state), `NotFound`, `AlreadyExists`,
`Unauthenticated` vs `PermissionDenied`, `Unavailable` (retryable),
`Internal` (bug). Clients read codes with `status.FromError(err)` —
never parse messages.

## 3. Deadlines Are Mandatory

```go
// Client — every call gets a deadline
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()
resp, err := client.CreatePayment(ctx, req)

// Server — check before expensive work
if err := ctx.Err(); err != nil {
    return nil, status.FromContextError(err).Err()
}
```

The server inherits the client's deadline through the context. Pass
`ctx` into every downstream call (DB, other RPCs) so cancellation
propagates end to end.

## 4. Interceptors for Cross-Cutting Concerns

Handlers stay business-only; recovery, auth, logging, metrics live in
interceptors:

```go
srv := grpc.NewServer(
    grpc.ChainUnaryInterceptor(
        recoveryInterceptor,   // outermost: panic → codes.Internal
        loggingInterceptor,
        authInterceptor,
    ),
)

func loggingInterceptor(ctx context.Context, req any,
    info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
    start := time.Now()
    resp, err := handler(ctx, req)
    slog.InfoContext(ctx, "rpc",
        slog.String("method", info.FullMethod),
        slog.Duration("duration", time.Since(start)),
        slog.String("code", status.Code(err).String()),
    )
    return resp, err
}
```

Order matters: recovery first (outermost), then observability, then
auth. Streaming RPCs need the parallel `StreamInterceptor` versions.

## 5. Streaming

- **Server streaming** for large result sets: `stream.Send` in a loop,
  return non-nil error to abort with a status.
- **Client/bidi streaming** only when the protocol truly needs it —
  each open stream holds a goroutine and flow-control state.
- Always terminate on `ctx.Done()`:

```go
func (s *Server) WatchPayments(req *pb.WatchRequest, stream pb.PaymentService_WatchPaymentsServer) error {
    for {
        select {
        case <-stream.Context().Done():
            return status.FromContextError(stream.Context().Err()).Err()
        case ev := <-s.events:
            if err := stream.Send(toProto(ev)); err != nil {
                return err
            }
        }
    }
}
```

## 6. Clients

- `grpc.NewClient` (it replaces the deprecated `Dial`) once per target at
  startup; share the `*grpc.ClientConn` — it multiplexes and reconnects.
- Retries, timeouts and load balancing in the service config: retry
  `UNAVAILABLE` on idempotent methods only, and use `round_robin` (the
  default `pick_first` sends everything to one backend).
- Client keepalive pings must be allowed by the server's
  `EnforcementPolicy` (default `MinTime` 5 minutes), or the server closes
  the connection with `too_many_pings`.
- Branch on `status.Code(err)`, never on the message.

Examples: `references/clients.md`.

## 7. Testing

Test through the generated client over `bufconn`: a real server with the
production interceptors, no network. Dial `passthrough:///bufnet` with
`WithContextDialer` — `NewClient`'s default `dns` resolver would try to
resolve the name. Assert with `status.Code(err)`. Example:
`references/testing.md`.

## 8. Production Server Setup

```go
lis, err := net.Listen("tcp", cfg.Addr)
if err != nil {
    return fmt.Errorf("listen: %w", err)
}

srv := grpc.NewServer(
    grpc.Creds(creds),                // TLS; mTLS for service-to-service
    grpc.MaxRecvMsgSize(4<<20),       // explicit; size it to the largest valid request
    grpc.ChainUnaryInterceptor(...),
)
pb.RegisterPaymentServiceServer(srv, server)

healthSrv := health.NewServer() // grpc.health.v1 — load balancers need it
healthpb.RegisterHealthServer(srv, healthSrv)
reflection.Register(srv)        // grpcurl/debugging; gate on non-prod if policy requires

go func() {
    <-ctx.Done()
    stopped := make(chan struct{})
    go func() { srv.GracefulStop(); close(stopped) }()
    select {
    case <-stopped:                 // in-flight RPCs finished
    case <-time.After(10 * time.Second):
        srv.Stop()                  // force after grace period
    }
}()

return srv.Serve(lis)
```

For mTLS, the server's `tls.Config` sets `ClientCAs` and
`ClientAuth: tls.RequireAndVerifyClientCert`; handlers read the caller's
verified identity from `peer.FromContext(ctx)` rather than trusting
metadata.

## Verification Checklist

1. Proto packages versioned (`*.v1`); no tag reuse; `reserved` for removals
2. Dedicated Request/Response message per RPC
3. Generated code produced by a pinned tool (buf/protoc) and committed; `buf breaking` runs in CI
4. All handler errors are `status.Error` with semantically correct codes
5. `codes.Internal` responses never leak internal error text
6. Every client call has a deadline; ctx propagated through all layers
7. Recovery, logging, auth implemented as chained interceptors (unary + stream)
8. Streams select on `stream.Context().Done()`
9. Health service registered; graceful stop with forced fallback; TLS (mTLS internally) and an explicit receive limit
10. `grpcurl` smoke test (or generated client test) passes against the running server
11. One shared `ClientConn` per target, built with `grpc.NewClient`; retries limited to `UNAVAILABLE`

© eduardo-sl · MIT · eduardo-sl/go-agent-skills

Похожие скиллы

Все скиллы по теме «Бэкенд и API» →
mcp-builder официальный anthropics Скилл проводит через создание MCP-сервера на TypeScript или Python: от изучения протокола до тестов и оценки качества. 130 949установок claude-api официальный anthropics Справочник по Anthropic SDK и API Claude для генерации кода без устаревших параметров и выдуманных методов. 74 198установок lark-im larksuite Скилл подключает Lark IM к агенту: он отправляет сообщения, ищет историю, управляет чатами и файлами. Подойдёт для задач вокруг командных коммуникаций. CX Codex +1 472 900установок lark-event larksuite Слушает события Lark/Feishu и отдаёт их потоком NDJSON. Подходит для ботов, обработчиков сообщений и долгих подписчиков. CX Codex +1 466 800установок caveman-discover JuliusBrussee Находит точки вызова LLM в репозитории и размечает их воркфлоу для Caveman Cloud, чтобы расходы на токены не сливались в одну общую кучу. CX Codex +1 104 400установок migration JuliusBrussee Скилл задаёт правила безопасных миграций схем, данных и API с обязательным откатом. Пригодится при изменениях, где нельзя терять данные или ломать совместимость. CX Codex +1 103 900установок

Из того же набора11

git-commit Скилл учит агента писать коммиты по Conventional Commits: тип, область, императив в заголовке. Пригодится, когда история коммитов в проекте превратилась в кашу. CX Codex +1 ★ 83звёзд репо go-troubleshooting Скилл ведёт агента по диагностике рантайм-проблем в Go: паники, дедлоки, утечки горутин и памяти, отчёты race detector. Пригодится, когда программа падает или висит, а причина неясна. CX Codex +1 ★ 83звёзд репо go-observability Скилл для Go-сервисов: помогает настроить структурные логи на log/slog, трейсы и метрики через OpenTelemetry, а также алерты по SLO. Пригодится, когда сервис уже в проде и нужно видеть, что в нём происходит. CX Codex +1 ★ 83звёзд репо go-error-handling Скилл задаёт агенту правила работы с ошибками в Go: обёртка через %w, sentinel-ошибки, свои типы и errors.Is/errors.As. CX Codex +1 ★ 83звёзд репо go-context Скилл для ИИ-агента, который проверяет и правит работу с context.Context в Go: отмена, таймауты, значения, типичные ошибки. CX Codex +1 ★ 83звёзд репо go-project-layout Подсказывает, как разложить новый Go-проект по папкам: cmd/, internal/, плоская раскладка для мелких утилит. Пригодится в самом начале, когда структура ещё не сложилась. CX Codex +1 ★ 83звёзд репо go-dependency-injection Скилл учит агента внедрять зависимости в Go через конструкторы и собирать всё в main. Пригодится, когда в проекте завёлся глобальный синглтон или код тяжело тестировать. CX Codex +1 ★ 83звёзд репо go-api-design Скилл ведёт агента по проектированию HTTP-обработчиков на Go: маршруты, middleware, валидация, пагинация, graceful shutdown. Пригодится, когда пишете REST-сервис с нуля или переделываете существующий. CX Codex +1 ★ 83звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой