Share
Embed
Making of GoDoctor: Lessons Learned While Building a Go-Aware MCP Server
Talk presented at FOSDEM 2026 on February 1st at the Go Devroom.
Note: it seems some slides are failing rendering due to the import process (blue slides and diagrams). Sorry for the trouble.
Daniela Petruzalek
February 02, 2026
Transcript
32 slides
-
The Making of GoDoctor: Lessons learned while building a Go-aware
MCP server 01/Feb/2026 • [email protected] Daniela Petruzalek Developer Relations Engineer Google Cloud -
1 Introduction 2 Model Context Protocol 3 Developing GoDoctor 4
Results and Recommendations Contents -
A little about myself… DevRel at Google UK Originally from
Brazil Previously Backend / Data Engineer Currently obsessed with AI Love Games, Anime and Cats =^_^= -
Model Context Protocol MCP is an open protocol that standardizes
how applications provide context to large language models (LLMs). (...) MCP enables you to build agents and complex workflows on top of LLMs and connects your models with the world. modelcontextprotocol.io -
MCP Server: Building Blocks Tools: model controlled, execute actions Prompts:
user controlled, interaction templates Resources: app controlled, contextual data -
GoDoctor Objective: add specialist knowledge to coding agents Goals: -
Reduce agent hallucinations - Improve code quality - Improve token efficiency - Improve response time github.com/danicat/godoctor -
The Birth of GoDoctor: Read the Docs! Problem: model hallucinating
APIs / SDKs Hypothesis: if the model just read the docs*, this could be avoided (context engineering / grounding) Solution: expose the “go doc” command as a tool “read_docs” * Note: Gemini 3 is much better at doing this out of the box -
Code Review Problem: code generated is not very idiomatic Hypothesis:
if the model could request an “unbiased” review, it would have the opportunity to self-correct Solution: a “code_review” tool that calls a model with fine tuned context -
Common problems coding with agents Edit failures (search context) Introduction
of “typos” and format errors Dependency hallucination Builds successfully, but breaks the tests Refactor loops, code quality (lint), anti-patterns, … -
Some early experiments Second generation of tools: scalpel, scribble, gopretty,
endoscope. Failed due to: - Required precise manipulation (lines and columns) - Doctor-themed naming is cute, but not useful - Behaviour too similar to a built-in tool - Didn’t do much more than run_shell_command -
Tenkai: Experimentation Framework Building blocks: scenarios, experiment templates, alternatives and
configurations Each alternative runs each scenario N times (sample size) The data is assessed for statistical significance with statistical tests like Welch’s T-test, Fisher’s exact test, etc github.com/danicat/tenkai -
Tenkai: Experiment Structure User Scenario Experiment Template Alternative 1 (Control)
Alternative 2 Scenario Runs N times Configuration Blocks Config 1 Config 2 e.g. “create a hello world app” e.g. “use Gemini 3 Flash preview” -
Tenkai: Architecture Streamable HTTPS Frontend + Server (Cloud Run) Runner
(Cloud Run Jobs) Experiment Data (Google Cloud SQL) User Scenarios and Run Data (Cloud Cloud Storage) GoDoctor (Cloud Run) -
The Experimentation Loop Observe model behaviour for common patterns Develop
an hypothesis Create the tool, run an experiment against baseline Analyse tool usage patterns after the experiment Are the observations statistically significant? Rinse and repeat -
Results New generation of tools: smart_read, smart_edit, smart_build Tuned descriptions
to “sell” better the value of the tools Never do a simple operation easily replaced with shell Return additional context (e.g. type info, package docs) On failure, provide hints for self-correction Reduce the model “degree of freedom” -
project_init Bootstraps Go projects by creating directories, initializing modules, and
installing dependencies. project_init(path=".", module_name="github.com/user/my-app", dependencies=["github.com/…"]) Key Features: - Atomic workflow combining multiple setup steps into one call. - Returns documentation for installed packages immediately. - Returns top level docs for “hallucinated” dependencies -
smart_read Go-aware file reading operation. smart_read(filename="main.go", start_line=10, end_line=50) Key Features:
- Allows slicing the file using line numbers - Returns documentation for external dependencies (only the first time) - Syntax check using go/parser -
smart_edit Go-aware file editing with smart “matching” features smart_edit(filename="main.go", old_content="func
foo()", new_content="func bar()") Key Features: - Normalises whitespace and indentation variances before matching - Supports line numbers for precise replacement - Tolerant to typos up to a given threshold (e.g. Levenshtein distance <= 2) - Runs gofmt and goimports to maintain style consistency. - Prevents saving changes that introduce syntax errors. - Returns suggestions when edit fails -
smart_build Deterministic build pipeline with build, test and vet (or
lint). smart_build(packages="./...", auto_fix=true) Key Features: - Runs go build, test and vet (or golangci-lint) in the same step - Reports detailed package coverage and total statement coverage - Resolves minor module and formatting issues automatically (go mod tidy, gofmt -w) -
Experiment: no MCP, gopls and godoctor Runner: Gemini CLI with
AUTO model Scenario: Build a “hello world” MCP server Sample size: 50 Includes all runs -
Experiment: no MCP, gopls and godoctor Runner: Gemini CLI with
Gemini 3 Flash Preview Scenario: Build a “hello world” MCP server Sample size: 50 Adjusted for successful runs only -
Conclusions MCP tools should not be 1:1 mappings of your
API / SDK Documentation and examples are gold for agents Augment your tools with hints upon failures Reduce the model degree of freedom (e.g. build -> test) -
Try building it yourself! Codelab: How to Build an MCP
Server with Go and Gemini CLI (Updated: Jan/2026) -
If you would like to know more Personal blog: danicat.dev
Talk materials: danicat.dev/events LinkedIn linkedin.com/in/petruzalek Twitter x.com/danicat83 Bluesky danicat83.bsky.social Thank you!