victorzhuk/skills

z-go-mcp-server

MCP (Model Context Protocol) server authoring in Go — SDK choice, transport selection, stdio discipline, tool design, and testing.

소스 보기

사용 방법

  1. 설치 명령을 복사하고 자신의 에이전트 환경에 설치하기 전에 소스 패키지를 확인하세요.
  2. 필요한 도구, 인증 정보, 지원 환경은 원본 문서에서 확인하세요.
  3. 입력과 원하는 산출물을 설명하고 출처와 결과를 대조하세요.
npx skills add https://github.com/victorzhuk/skills --skill z-go-mcp-server

시작 전 확인

  • 설치에는 모델 구독, API 한도, 파일 접근 권한이 포함되지 않습니다.
  • 별점 수와 설치 수는 활동 지표이며 독립적인 품질·보안 검증이 아닙니다.
원본 Skill 문서

원본 저장소의 제목, 예시, 코드, 표, 링크, 이미지를 유지해 표시합니다.

Go MCP server

Build MCP servers with the official SDK by default. Treat every tool as a workflow contract for the calling model, not a REST mirror.

SDK choice

Use modelcontextprotocol/go-sdk for new servers unless an existing SDK or a required capability determines the choice. Preserve working mark3labs/mcp-go integrations. Check each selected release's Go floor, protocol support and compatibility policy; SDK maturity does not establish support for every new protocol revision.

Before changing a server, record the pinned SDK version, supported protocol revisions, client versions and transports. Verify that matrix with client/server tests. Examples below use the official SDK's session API and require a compatible pinned release; they are not proof of 2026-07-28 support.

Transport choice

TransportUse whenAvoid when
stdio (mcp.StdioTransport)Local subprocess launched by one client — CLI tools, editor/agent integrations. verify the client supports the selected revisionMultiple concurrent clients, or the server runs remotely
Streamable HTTP (mcp.NewStreamableHTTPHandler)Remote server, multiple concurrent sessions, runs behind a load balancer or in KubernetesA single local subprocess covers the need — HTTP adds authentication and origin-validation requirements
SSE-only (the 2024-11-05 transport)Never for a new serverAlways — superseded by streamable HTTP in spec 2025-03-26; keep it only to serve clients stuck on the old transport

As checked on 2026-10-13, the current protocol is 2026-07-28. Its core is stateless: requests carry protocol-version metadata and servers support discovery. Earlier revisions use initialize and may use Mcp-Session-Id; preserve that lifecycle only for the revisions your SDK/client pair supports. Do not infer SDK support from the protocol publication date.

For HTTP, validate Origin and Host according to the selected transport revision, authenticate callers, and authorize each tool. Check the pinned SDK's defaults rather than assuming it covers these controls. A generic browser cross-origin helper is not a substitute for the protocol's Origin policy.

Security boundary

  • Derive caller and tenant identity from verified authentication. Authorize the requested action and resource on every call, including read-only tools.
  • For OAuth, validate issuer, audience, expiry, and required scopes. Accept only tokens issued for this MCP server. Never forward its bearer token to an upstream API; use separately scoped downstream credentials.
  • Validate tool arguments in code, including ranges, paths, URLs, and ownership. Schema descriptions, tool annotations, and model confidence are not permission checks.
  • Treat returned documents, upstream errors, and tool metadata as untrusted content. Keep result data separate from trusted instructions. Do not accept model-supplied approval flags as authorization.
  • For consequential actions, verify the caller's approval policy at execution time and bind any approval to the exact operation and arguments. Preserve existing valid authorization.
  • Limit request/result bytes, execution time, concurrency, and downstream work. Apply [[z-go-http-client]] destination controls to tools that fetch URLs.
  • Run stdio servers with only the filesystem, network, and credential access they need. Stdio avoids a listening endpoint; it does not sandbox the process.

Use [[z-security-hardening]] for shared prompt-injection defenses and MCP security guidance for the selected protocol's authorization requirements.

This server-side streamable-HTTP SSE is internal transport plumbing, not an app-level streaming feature — for hand-rolled SSE to a browser client, see [[z-go-llm-streaming]].

stdio discipline

Stdout carries protocol JSON-RPC only. Anything else on stdout — a stray fmt.Println, a dependency that logs to stdout by default, a panic trace — corrupts the stream and the client can't parse it.

  • Build slog on os.Stderr explicitly: slog.New(slog.NewJSONHandler(os.Stderr, nil)). Don't rely on a package default you haven't checked.
  • Route or silence any third-party logger that defaults to stdout.
  • mcp.StdioTransport owns stdout once connected — never write to it yourself.

Tool design

The model is the caller. Design tools it can pick correctly and recover from when it picks wrong.

  • Name as `service_verb_noun`: excursions_search, excursions_get_booking, not search or getData. A consistent prefix lets an agent juggling several MCP servers disambiguate at a glance.
  • Shape tools around a workflow, not an endpoint. A tool mirroring GET /bookings/{id}/legs 1:1 forces three round trips for one task; a tool returning "booking + legs + cancellation window" together is a better contract. When unsure, favor coverage over cleverness — an under-fitted workflow tool blocks real tasks.
  • Write the description for the model, not a teammate: what it does, every parameter's meaning and constraints, one example call. Skip adjectives that don't change behavior.
  • Paginate and filter server-side. Never hand back a raw ClickHouse result set or full Postgres row — cap page size, project only the fields the task needs, summarize the rest.
  • Eval against real tasks before shipping: write 5-10 realistic, independently verifiable prompts a user would give an agent, run them against the server, and fix whichever tool the model picks wrong or misuses.

Input schemas from Go structs

mcp.AddTool is generic over the input and output types and derives the JSON Schema from the struct — no separate schema to keep in sync:

go
type SearchParams struct {
	City    string `json:"city" jsonschema:"IATA city code, e.g. LON"`
	Checkin string `json:"checkin" jsonschema:"date in YYYY-MM-DD"`
	Limit   int    `json:"limit,omitempty" jsonschema:"max results from 1 to 100, default 20"`
}

mcp.AddTool(server, &mcp.Tool{
	Name:        "excursions_search",
	Description: "Search bookable excursions for a city and date, paginated.",
}, func(ctx context.Context, req *mcp.CallToolRequest, in SearchParams) (*mcp.CallToolResult, SearchResult, error) {
	if in.Limit == 0 {
		in.Limit = 20
	}
	if in.Limit < 1 || in.Limit > 100 {
		return nil, SearchResult{}, errors.New("limit must be between 1 and 100")
	}
	...
})

json tags name the fields; jsonschema tags supply the description the model reads — write that string by the same rule as the tool description above.

The description does not enforce Limit; the handler does. Pass the normalized limit to the query and cap the returned page. Choose the maximum from the tool contract, then test the generated schema and runtime behavior. Validate resource ownership separately from input shape.

Register tools before serving requests. Verify discovery/listing for each supported revision; older session-based clients may derive capabilities during initialization.

Errors the agent can act on

MCP splits failures into two channels — pick the right one:

ChannelWhenGo SDK behavior
Protocol error (JSON-RPC error)Unknown tool, malformed request, server fault — not something the model can fix by retryingOnly the raw Server.AddTool(ToolHandler) path sends this when it returns error
Tool execution error (isError: true in the result)Bad input, upstream API failure, business-rule violation — the model can retry with different argumentsmcp.AddTool's generic handler packs a returned Go error here automatically

Prefer the generic mcp.AddTool path so ordinary failures land as tool errors. Return a safe error code and concise recovery guidance. Do not echo raw upstream errors, tokens, or arbitrary user text as instructions; the model receives that content.

Cancellation and shutdown

  • Tool handlers get the call's context.Context; a client cancellation notification cancels it. Check ctx.Err() in any loop and return early — don't leave a detached goroutine running past a cancelled call.
  • stdio: ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM), defer stop(), then server.Run(ctx, &mcp.StdioTransport{}). Run blocks until the client disconnects or ctx is cancelled, and closes the session either way.
  • Streamable HTTP: mcp.NewStreamableHTTPHandler is a plain http.Handler — wrap it in http.Server and drain with srv.Shutdown(ctx) like any other HTTP service.

Testing

Skip subprocess plumbing — connect a client and server over an in-memory pipe and drive real tool calls:

go
ct, st := mcp.NewInMemoryTransports()
srv := mcp.NewServer(&mcp.Implementation{Name: "excursions", Version: "test"}, nil)
mcp.AddTool(srv, &mcp.Tool{Name: "excursions_search"}, searchHandler)
ss, err := srv.Connect(ctx, st, nil)
require.NoError(t, err)
defer ss.Close()

cli := mcp.NewClient(&mcp.Implementation{Name: "test-client", Version: "v0"}, nil)
session, err := cli.Connect(ctx, ct, nil)
require.NoError(t, err)
defer session.Close()
result, err := session.CallTool(ctx, &mcp.CallToolParams{
	Name:      "excursions_search",
	Arguments: map[string]any{"city": "LON"},
})

This exercises the pinned SDK's connection lifecycle, schema validation, and dispatch — no mocking the protocol layer. Assert on result.IsError and result.Content, the same shape the model receives. One test per tool's happy path, one per validation failure that should surface as a tool error.

Reach for golden JSON-RPC frame fixtures only for cross-SDK wire-compatibility regression tests; the in-memory client above already exercises real serialization, so it stays the default for ordinary handler tests.

Do not

  • Ship a tool whose only documentation is its name — the model has nothing else to pick with.
  • Mirror every REST or gRPC endpoint 1:1 "for completeness" — collapse the common workflow into one tool, add the rest only when a real task needs them.
  • Return a bad-input failure through the raw ToolHandler protocol-error path — the model reads a protocol error as unfixable and gives up instead of retrying.
  • Write anything but JSON-RPC frames to stdout in a stdio server, including via a dependency's default logger.
  • Build a new server on the 2024-11-05 SSE-only transport.
  • Expose a remote server before implementing the selected protocol/client authentication contract and per-tool authorization. Keep local stdio setup scoped to its launching user.

Verify

sh
go build ./...
timeout 5m go test -parallel 4 -p 2 -timeout 2m ./... -run TestMCP -v

Verify the pinned SDK/client protocol matrix: current-revision discovery and per-request version handling where supported, legacy initialization only for legacy revisions, expected tool schemas, cancellation, malformed input, and HTTP authorization/origin rejection. Record any unsupported revision instead of claiming conformance.

Test wrong-audience and expired tokens, cross-tenant resource access, invalid limits, forbidden fetch destinations, and missing or changed approvals. Assert that rejected calls never reach the protected dependency. Include malicious tool-result text; authorization must hold even if the model follows it.

같은 저장소의 Skills

더 많은 Skills

모든 Skills
victorzhuk
커뮤니티

z-accessibility

Audit and improve web accessibility following WCAG 2.2 guidelines. Use when asked to "improve accessibility", "a11y audit", "WCAG compliance", "screen reader support", "keyboard navigation", or "make accessible".

설치 수
1
GitHub Stars
0
업데이트
10월 22일
victorzhuk
커뮤니티

z-algo-core

DS/algorithm selection judgment for production code, not competitive tricks — hash map for membership/dedup, slice+sort beats a tree until proven, heap for top-k, two-pointer/sliding-window for scans, BFS/DFS/topo-sort for dependency shapes. Triggers on Big-O, hash map vs tree. Does not cover profiling/tuning; see [[z-go-performance]].

설치 수
1
GitHub Stars
0
업데이트
10월 22일
victorzhuk
커뮤니티

z-bdd

BDD acceptance contracts for humans and agents across UI, API, and CLI products. Use for Gherkin, Given-When-Then, E2E acceptance, or scenario evidence. Define repeatable scenarios with explicit assertions and required outcomes. Test selection belongs to [[z-testing-strategy]]. Go harness wiring belongs to [[z-go-bdd]].

설치 수
1
GitHub Stars
0
업데이트
10월 22일
victorzhuk
커뮤니티

z-codegraph

Use an existing CodeGraph integration for call graphs, impact analysis, affected tests, or route discovery. Discover installed tools and index freshness; follow host LSP precedence and verify current source. Do not initialize indexes without user authorization.

설치 수
1
GitHub Stars
0
업데이트
10월 22일