1. Introduction
In this codelab, you'll learn how to build and deploy a Model Context Protocol (MCP) server to extend the capabilities of the Gemini CLI. You will be building godoctor, a Go-based server that provides custom tools for Go development, transforming the Gemini CLI from a general-purpose coding assistant into a specialized Go development expert.
This codelab uses a "prompt-driven" approach. You will act as a tech lead, providing prompts to your AI assistant (the Gemini CLI itself). Your goal is to learn how to translate project requirements into effective prompts and let the AI handle the implementation details.
At the heart of this project is the Model Context Protocol (MCP). MCP is an open-source protocol that standardizes how large language models (LLMs) like Gemini communicate with external tools and services. It acts as a bridge, allowing the AI to access real-world information and perform actions beyond its built-in knowledge. By building an MCP server, you are creating a custom plugin that the Gemini CLI can discover and use, effectively teaching it new skills.
What you'll learn
- How to install and configure the Gemini CLI
- How to formulate effective prompts to guide an AI assistant in software development
- How to provide context and guidelines to an AI assistant
- How to create and configure an MCP server to augment the Gemini CLI capabilities
- How to containerize and deploy a Go application to Google Cloud Run
What you'll need
This workshop can be run entirely within the Google Cloud Shell, which comes pre-installed with all the necessary dependencies (gcloud CLI, Go, Docker, Gemini CLI).
Alternatively, if you prefer to work on your own machine, you will need the following:
- Node.js 20 or later
- A Google Cloud project with billing enabled
- The Google Cloud SDK (gcloud CLI) installed and initialized
- Go 1.24 or later installed on your system
- Docker installed on your system
Key Technologies
Here you can find more information about the technologies we will be utilizing:
- Gemini CLI: The AI-powered command-line interface that we will be extending
- Model Context Protocol (MCP): The open-source protocol that allows the Gemini CLI to communicate with our custom tool
- Go SDK for MCP: The Go library we will use to implement our MCP server
Tips for a Successful Codelab
Working with an AI assistant is a new way of developing software. Here are some tips to make your experience smooth and successful:
- Don't be afraid to hit ESC. The AI will sometimes propose actions or code that you don't agree with. Use the ESC key to cancel its proposed action and provide a new prompt to guide it in the right direction. You are the pilot.
- Encourage tool use. If the AI seems lost or is making up information, encourage it to use its available tools. Prompts like "Can you use Google Search to verify that?" or "Use the read_file tool to understand the current code before making changes" can be very effective.
- Resist manual changes. Try to have the AI perform all the work. This is the core skill you are practicing. However, if you must make a manual change, tell the AI about it afterward. A prompt like "I have manually updated the README.md file. Please read it again to refresh your knowledge" will ensure the AI stays in sync with your project.
- Have you tried turning it off and on again? In the rare case that the AI is trying to force a given path against your command, it might be due to context degradation (sometimes also called "context rot"). In this case you can use the Gemini CLI command "/compress" to reduce the context noise or, in extreme cases, you can use the "/clear" command to clean the entire session history.
2. Environment Setup
Self-paced environment setup
- Sign-in to the Google Cloud Console and create a new project or reuse an existing one. If you don't already have a Gmail or Google Workspace account, you must create one.
- The Project name is the display name for this project's participants. It is a character string not used by Google APIs. You can always update it.
- The Project ID is unique across all Google Cloud projects and is immutable (cannot be changed after it has been set). The Cloud Console auto-generates a unique string; usually you don't care what it is. In most codelabs, you'll need to reference your Project ID (typically identified as
PROJECT_ID
). If you don't like the generated ID, you might generate another random one. Alternatively, you can try your own, and see if it's available. It can't be changed after this step and remains for the duration of the project. - For your information, there is a third value, a Project Number, which some APIs use. Learn more about all three of these values in the documentation.
- Next, you'll need to enable billing in the Cloud Console to use Cloud resources/APIs. Running through this codelab won't cost much, if anything at all. To shut down resources to avoid incurring billing beyond this tutorial, you can delete the resources you created or delete the project. New Google Cloud users are eligible for the $300 USD Free Trial program.
Start Cloud Shell
While Google Cloud can be operated remotely from your laptop, in this codelab you will be using Google Cloud Shell, a command line environment running in the Cloud.
From the Google Cloud Console, click the Cloud Shell icon on the top right toolbar:
It should only take a few moments to provision and connect to the environment. When it is finished, you should see something like this:
This virtual machine is loaded with all the development tools you'll need. It offers a persistent 5GB home directory, and runs on Google Cloud, greatly enhancing network performance and authentication. All of your work in this codelab can be done within a browser. You do not need to install anything.
3. Getting Started with the Gemini CLI
In this section you will learn about the Gemini CLI, including how to install and configure it for your environment.
What is the Gemini CLI?
The Gemini CLI is an AI-powered command-line interface that can help you with a wide range of development tasks. It can understand your project's context, answer questions, generate code, and use external tools to extend its capabilities.
Installation
Install the Gemini CLI globally using npm.
npm install -g @google/gemini-cli
You can confirm the CLI is installed by running:
gemini --version
Configuration
The Gemini CLI's behavior is controlled by configuration files and environment variables. There are two key files:
GEMINI.md
: This file provides natural language guidelines and context to the AI. The CLI reads this file to understand your project's coding standards and conventions..gemini/settings.json
: This file controls the configuration of the CLI including how to connect to external tools. We are going to use this file to configure the CLI to use the MCP server we are building in this lab.
We will first set up the environment and then proceed to create the GEMINI.md
file. The settings.json
file will be configured at a later step.
- Create and initialize a project directory:
mkdir godoctor
cd godoctor
go mod init godoctor
- Authenticate with the Google Cloud application default credentials:
We need to login to an account that has access to the GCP project you are going to use for this codelab:
- Make sure you have the Google Cloud SDK installed and initialized.
- Run the following command to set up Application Default Credentials:
gcloud auth application-default login
4. Development Guidelines
To ensure the AI assistant generates high-quality, idiomatic Go code, it's essential to provide it with clear guidelines. This is done in the GEMINI.md file.
Goal: Create a GEMINI.md file that will serve as the set of rules for the AI assistant during this project.
Task: Create a file named GEMINI.md in the root of your godoctor directory and paste the following content into it.
# Go Development Guidelines
All code contributed to this project must adhere to the following principles.
### 1. Formatting
All Go code **must** be formatted with `gofmt` before being submitted.
### 2. Naming Conventions
- **Packages:** Use short, concise, all-lowercase names.
- **Variables, Functions, and Methods:** Use `camelCase` for unexported identifiers and `PascalCase` for exported identifiers.
- **Interfaces:** Name interfaces for what they do (e.g., `io.Reader`), not with a prefix like `I`.
### 3. Error Handling
- Errors are values. Do not discard them.
- Handle errors explicitly using the `if err != nil` pattern.
- Provide context to errors using `fmt.Errorf("context: %w", err)`.
### 4. Simplicity and Clarity
- "Clear is better than clever." Write code that is easy to understand.
- Avoid unnecessary complexity and abstractions.
- Prefer returning concrete types, not interfaces.
### 5. Documentation
- All exported identifiers (`PascalCase`) **must** have a doc comment.
- Comments should explain the *why*, not the *what*.
# Agent Guidelines
- **Reading URLs:** ALWAYS read URLs provided by the user. They are not optional.
Now your development environment is fully set up.
5. The Initial Build: A godoc Server
Your first goal is to create the initial version of the godoctor
server. This version should be a minimal, production-ready application that provides a single tool called godoc
that provides the ability to look up Go documentation.
Goal: Create a production-ready MCP server that exposes the go doc command, allowing an LLM to query Go documentation.
Run the Gemini CLI command on the shell:
gemini
When you run the CLI for the first time it will ask you to choose an authentication mode and a theme. For the authentication mode, choose to "login with Google" to login with a personal Google account so you can benefit from Gemini CLI's generous free tier. You should see an option to select your authentication mode similar to this:
In case you need to change your selection, you can type /auth
and hit enter to open this menu again.
Next you will be prompted to pick up a theme:
Similar to /auth
, you can also change the theme later with the /theme
command.
After choosing the authentication method and your preferred theme you will be taken to the command prompt. Here you can type your commands, for example:
Write a hello world application in Go.
The CLI uses a combination of its own reasoning (via a Gemini model like Gemini Flash or Gemini Pro) and tools to perform the tasks. It uses tools whenever it needs to interact with the filesystem or external services, like APIs, databases, etc. Examples of the tools that come out of the box, or "internal tools", are read_file, write_file, web_fetch and google_search. The MCP server that we are building will also become a tool available to the CLI.
The first time it runs a tool it will ask for your permission. You can give it a one off permission, a blanket approval for the rest of the session, or deny its request. If it is a file editing operation you will also find the option to edit the file using an external editor, just in case you want to make some adjustments. For example, this is the output of the prompt above, to create a hello world program:
Besides prompts, you can also use slash commands. If you type "/", the CLI will automatically show you the autocomplete options. You can continue to type the full command or select one from the options. The /auth
and /theme
commands mentioned above are a couple of such commands.
Once you are familiar with the interface, you can start the main task of this section, which is to ask the CLI to write the MCP server for us.
Creating a Hello World MCP server
One of the best ways to ensure the model will build things more consistently is to break down complex tasks into incremental steps. While the model might be able to figure out a complex task on its own, without the right setup it will take a long time to discover the right implementation.
For a more consistent approach, we are going to first instruct it to build a "Hello World" MCP server before implementing the functionality we want (reading go documentation).
An example prompt is shown below:
Your task is to create a Model Context Protocol (MCP) server to expose a "hello world" tool. For the MCP implementation, you should use the official Go SDK for MCP and use the stdio transport.
Read these references to gather information about the technology and project structure before writing any code:
- https://github.com/modelcontextprotocol/go-sdk/blob/main/README.md
- https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle
- https://go.dev/doc/modules/layout
To test the server, use shell commands like these:
(
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}';
echo '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}';
echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}';
) | ./bin/godoctor
Note that the prompt above is composed by three main segments:
- The problem specification, including what we want to build and the constraints (e.g. use the official SDK instead of any SDK)
- Reference documentation for the model to help it disambiguate the request
- A testing procedure, which works as the acceptance criteria for the task
Having these three components will help the model to achieve the desired results in a more consistent manner.
Go doc tool implementation
Once you have a working implementation, we can move to implement the real "go doc" tool:
Add a new tool to our MCP server called "godoc" that invokes the "go doc" shell command. The tool will take a mandatory "package" argument and an optional "symbol" argument.
Read the reference for the go doc command to understand its API: https://pkg.go.dev/golang.org/x/tools/cmd/godoc
Test it by executing the call with:
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name": "godoc", "arguments": {"package": "fmt"} } }'
| ./bin/godoctor
Test it using both a standard library package and an external package like "github.com/modelcontextprotocol/go-sdk/mcp", both with and without symbols.
Feel free to experiment with this prompt or try to come up with your own.
A Helpful Command Line Interface
As soon as you get settled on a good implementation, you can instruct the model to create a godoctor CLI using a MCP client. This will help streamline the testing of features by avoiding to build the JSON-RPC calls manually like it has been doing so far.
Example prompt:
Now create a godoctor-cli component that will call the MCP server using command transport. This CLI will expose all tools using subcommands and allow us to test the MCP server implementation without needing to build the JSON-RPC calls manually.
Use the reference implementation at https://github.com/modelcontextprotocol/go-sdk/blob/main/README.md to build the client.
Test it by calling from the command line:
- the hello_world tool
- the godoc tool with a local package
- the godoc tool with a local package and symbol
- the godoc tool with an external package
- the godoc tool with an external package and symbol
Now that you have a working set of client and server, in the next section you are going to configure the Gemini CLI with the MCP server you just created to start leveraging its benefits on the next coding task.
Useful Resources
Given that MCP is still a novel concept and that the Go SDK for MCP is a new library, in this step Gemini might take a long time to discover the right implementation on its own. In order to help the model come up with the right solution, you might want to give it the following references:
- You can give the model the following prompt so it will discover the SDK API more consistently: "use the go doc shell command to discover the api for the go-sdk library"
- If the model tries to inspect the source code of the SDK with the
read_file
tool, it will fail because Gemini CLI cannot read files outside its current scope. You can instruct it to usecat
andls
commands instead through therun_shell_command
tool. - If the model has trouble debugging the application, instruct it to add more verbose logging and improve the contextual information in error messages.
- If everything else fails, give it a reference implementation: https://github.com/danicat/godoctor
6. Configuring godoctor as an MCP Server for Gemini CLI
After the AI assistant has generated the code for both the client and the server, you can instruct it to run a few manual tests. For example:
retrieve the documentation for the package net/http
Make sure you also test it with an external dependency (not in the standard library):
retrieve the documentation for the go-sdk package
Once you are satisfied with the results, instruct it to write a README.md with instructions on how to use and develop this project.
Now write a detailed README.md file explaining both from a user and a developer perspective how to use and to build this project.
Now we are going to configure the server so that the Gemini CLI can use it during the next phase of development.
- Ask the CLI to update GEMINI.md to use
godoc
as the preferred method to read documentation:
update the GEMINI.md file to use the godoc tool to retrieve documentation about Go packages or symbols. Always prefer to use godoc over WebFetch and GoogleSearch, and only use those when godoc doesn't give a clear answer.
- Now we need to restart the Gemini CLI to configure it. First, let's save the chat session so you can resume from where you stopped once it is restarted.
/chat save workshop001
- Exit the CLI by pressing Ctrl+D twice.
- Compile the server binary: Create a
bin
directory and compile the godoctor server into it.
mkdir -p bin
go build -o ./bin/godoctor ./cmd/godoctor # adjust paths as needed
- Configure Gemini CLI for the local tool: Create a
.gemini/settings.json
file in your project root and add anmcpServers
section to tell the Gemini CLI how to run your compiled server.
mkdir -p .gemini
touch .gemini/settings.json
- Now, add the following content to the new file using a command line editor like
vim
ornano
:
{
"mcpServers": {
"godoctor": {
"command": "./bin/godoctor"
}
}
}
- Now launch Gemini CLI and restore the chat session:
/chat resume workshop001
- You should be able to see the tool is loaded by pressing Ctrl+T:
- Test the integration by asking the Gemini CLI to use your tool with a prompt like "Get the documentation for net/http"
You should see something like this:
If the tool is working correctly you should see the documentation retrieved through the tool call:
Congratulations, you have made an MCP tool! But this is not the end, we still can make it a bit more useful.
7. Adding an AI-Powered Code Reviewer
Let's add a more sophisticated, AI-powered feature: a code reviewer that uses the Gemini API.
Goal: Add a new tool named code_review to the existing project. This tool will use the Gemini API to analyze Go code and provide feedback.
Example Prompt:
I want to add a new tool to my project called code_review. This tool should use the Gemini API to analyze Go code and provide a list of improvements in json format according to the best practices accepted by the Go community. The tool should take the Go code content and an optional hint as input. The hint will be used to provide additional guidance for the AI reviewer, like "focus on security" or "help me simplify this code". Please update the server to include this new tool and modify the CLI client to add a review command to use it.
Use this SDK to call Gemini: https://github.com/googleapis/go-genai
Useful Tips
Once the model starts working on it you might automatically see it requesting to call the godoc
tool to browse the documentation for the genai
package. If it doesn't, you can always interrupt the process with the escape key and remind it that now it has the godoc
tool at its disposal.
Testing the Code Reviewer
- We need to restart Gemini CLI to build and reload the MCP server. Save the chat session with
/chat save workshop002
and then exit the CLI by pressing Ctrl+D twice. - The
code_review
tool needs an API key since we are calling a Gemini model to do the reviews for us. You can generate an API key using Google AI Studio. - Configure the environment variable
GEMINI_API_KEY
with the API key generated in the step above:
export GEMINI_API_KEY="YOUR_API_KEY"
- Re-compile the server: After adding the new tool, you must re-compile the server binary to include the changes.
go build -o ./bin/godoctor ./cmd/godoctor
- Launch the Gemini CLI again. Restore the chat session with
/chat resume workshop002
. - Important. Ensure that you are authenticated with your personal gmail account so that the Gemini CLI itself doesn't use your billing account. You can do this by using the
/auth
command:
- Confirm that the tool is enabled by pressing Ctrl+T. You should see something like this:
- Now let's test the
code-review
tool by reviewing one of the tool's source files:
"Use the godoctor tool to review the cmd/godoctor/main.go file."
You should see something like this:
With the code review tool working, now you can suggest the model to apply some of the improvements it found, for a full "self-improving" workflow!
You have now confirmed that the code-review
tool works. In the next section you will work on deploying it to the cloud.
To clear the GEMINI_API_KEY:
- Save your current session with
/chat save workshop003
and exit the CLI - Backup the API key somewhere safe:
export | grep GEMINI_API_KEY > env.bkp
- Unset the
GEMINI_API_KEY
:
export GEMINI_API_KEY=
- Restart the CLI and load the session with
/chat resume workshop003
- Ask the model to apply the code review improvements.
8. Prepare your server for the cloud
The MCP server we have developed so far only runs in the local machine, which is fine if you are developing tools for your own use, but often in enterprise environments we need to deploy tools for wider usage of hundreds or even thousands of developers.
In order to scale our MCP server, we need to convert it from a server that only speaks standard I/O to a server that can talk HTTP, and deploy it somewhere where it can be accessible by different developers. For this objective we are going to use a transport mode defined in the MCP specification as streamable HTTP, and use Cloud Run as our deployment target.
Goal: Refactor the godoctor server to use the streamable HTTP transport.
Example Prompt:
The godoctor server is currently using the stdio transport. I want to deploy it to Cloud Run, so I need to refactor it to use the streamable HTTP transport instead. Please modify the server to comply with the streamable HTTP specification.
Useful Resources
- If the model struggles with implementing the streamable HTTP transport, you can give it this reference: https://github.com/modelcontextprotocol/go-sdk/blob/main/design/design.md
- The model might try to use HTTP+SSE instead, which has been deprecated. If you see it going through this path, steer it back towards streamable HTTP.
Testing the Server using HTTP
Ask the model to update the godoctor client to also use streamable HTTP so you can test that it is still working.
Now update the client to use streamable HTTP and run a test by retrieving documentation from one package
Optional: If you want to configure Gemini CLI to use the server via HTTP:
- Save your session and exit the CLI
- Edit your
.gemini/settings.json
file and change the configuration to point to your local running server.
"mcpServers": {
"godoctor": {
"httpUrl": "http://localhost:8080"
}
}
- Run the refactored server locally:
go run ./cmd/godoctor/main.go
- In a new terminal (since the operation above is blocking), start the Gemini CLI and give it a prompt to test the connection, e.g., "Use the godoctor tool to get the documentation for fmt.Println."
- Stop the server with Ctrl+C when you are done testing.
9. Containerizing the Application with Docker
Now that our server is using the correct transport protocol, we can containerize it for deployment.
Goal: Create a Dockerfile to package the godoctor server into a portable, production-ready container image.
Example Prompt:
Please create a multi-stage Dockerfile that compiles the Go binary and copies it into a minimal golang image like golang:1.24-alpine.
Testing the Docker Image
After the Dockerfile
is created, build the image and run it to ensure it works correctly. You can instruct Gemini to do it for you:
build the image and test the connectivity to the server using the godoctor client
Optional: if you want to do the test manually:
- Build the container:
docker build -t godoctor:latest .
- Run the container locally:
docker run -p 8080:8080 -e PORT=8080 godoctor:latest
- Test the running container: In another terminal, start the Gemini CLI and ask it to fetch documentation.
- Stop the server with Ctrl+C when you are done testing.
10. Deploying to Cloud Run
Now it's time to deploy our container to the cloud.
Goal: Deploy the containerized godoctor server to Google Cloud Run.
Prompt Guidance: Ask your AI assistant to provide the gcloud commands to deploy your container.
Example Prompt:
Now please deploy this image to Cloud Run and return me an URL I can use to call the MCP tool. Deploy it to us-central1 and use the project currently configured in the environment.
Once the deployment is finished we will configure the Gemini CLI to use the tool you just deployed.
Ask Gemini to update your .gemini/settings.json
file to change the MCP tool configuration to point to your deployed service.
now update the .gemini/settings.json file to use this URL for the godoctor server
The final mcpServers
section should look like this (remember to replace the placeholder with your actual Cloud Run app URL):
"mcpServers": {
"godoctor": {
"httpUrl": "https://<your-cloud-run-id>.us-central1.run.app"
}
}
Testing the Cloud Run Deployment
You are now ready for the final, end-to-end test.
Restart the Gemini CLI one last time (using /chat save
and /chat resume
to preserve your context). Now the CLI should be able to call the remote MCP server. Try asking for documentation for any packages.
Just remember that in order to use the code review tool the service needs the GEMINI_API_KEY
. You can ask Gemini CLI to re-deploy it with the right environment:
update the cloud run environment to add a GEMINI_API_KEY and use the value in @env.bkp. Then update the .gemini/settings.json file with the correct service URL
Restart the CLI and test it with a prompt:
Use the godoctor tool to review the cmd/godoctor/main.go file
The Gemini CLI will now connect to your deployed Cloud Run service and execute the code review.
Example prompt:
I'm done with my tests on the CloudRun server, please delete this deployment for me and revert my .gemini/settings.json to use the local version.
11. Congratulations!
You have successfully guided an AI assistant to build, containerize, and deploy a sophisticated, AI-powered tool. More importantly, you've practiced the essential skill of modern software development: translating requirements into effective prompts. You have successfully extended the Gemini CLI with a custom tool, making it a more powerful and specialized Go development assistant.