Skip to content

Quick Start

Get up and running with MCP-Go in minutes. This guide walks you through creating your first MCP server and client.

Hello World Server

Let's start with the simplest possible MCP server - a "hello world" tool:

package main
 
import (
    "context"
    "errors"
    "fmt"
 
    "github.com/mark3labs/mcp-go/mcp"
    "github.com/mark3labs/mcp-go/server"
)
 
func main() {
    // Create a new MCP server
    s := server.NewMCPServer(
        "Hello World Server",
        "1.0.0",
        server.WithToolCapabilities(false),
    )
 
    // Define a simple tool
    tool := mcp.NewTool("hello_world",
        mcp.WithDescription("Say hello to someone"),
        mcp.WithString("name",
            mcp.Required(),
            mcp.Description("Name of the person to greet"),
        ),
    )
 
    // Add tool handler
    s.AddTool(tool, helloHandler)
 
    // Start the stdio server
    if err := server.ServeStdio(s); err != nil {
        fmt.Printf("Server error: %v\n", err)
    }
}
 
func helloHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    name, err := request.RequireString("name")
    if err != nil {
        return mcp.NewToolResultError(err.Error()), nil
    }
 
    return mcp.NewToolResultText(fmt.Sprintf("Hello, %s! 👋", name)), nil
}

Save this as hello-server/main.go and run:

cd hello-server
go mod init hello-server
go get github.com/mark3labs/mcp-go
go run main.go

Running Your First Server

Testing with Claude Desktop

  1. Install Claude Desktop from Anthropic's website

  2. Configure your server by editing Claude's config file:

    macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json

    {
      "mcpServers": {
        "hello-world": {
          "command": "go",
          "args": ["run", "/path/to/your/hello-server/main.go"]
        }
      }
    }
  3. Restart Claude Desktop and look for the 🔌 icon indicating MCP connection

  4. Test your tool by asking Claude: "Use the hello_world tool to greet Alice"

Testing with MCP Inspector

For debugging and development, use the MCP Inspector:

# Install the MCP Inspector
npm install -g @modelcontextprotocol/inspector
 
# Run your server with the inspector
mcp-inspector go run main.go

This opens a web interface where you can test your tools interactively.

Basic Client Example

You can also create MCP clients to connect to other servers:

package main
 
import (
    "context"
    "fmt"
    "log"
 
    "github.com/mark3labs/mcp-go/client"
    "github.com/mark3labs/mcp-go/mcp"
)
 
func main() {
    // Create a stdio client that connects to another MCP server
	// NTOE: NewStdioMCPClient will start the connection automatically. Don't call the Start method manually
    c, err := client.NewStdioMCPClient(
        "go", "run", "path/to/server/main.go",
    )
    if err != nil {
        log.Fatal(err)
    }
    defer c.Close()
 
    ctx := context.Background()
 
    // Initialize the connection
    if err := c.Initialize(ctx); err != nil {
        log.Fatal(err)
    }
 
    // List available tools
    tools, err := c.ListTools(ctx)
    if err != nil {
        log.Fatal(err)
    }
 
    fmt.Printf("Available tools: %d\n", len(tools.Tools))
    for _, tool := range tools.Tools {
        fmt.Printf("- %s: %s\n", tool.Name, tool.Description)
    }
 
    // Call a tool
    result, err := c.CallTool(ctx, mcp.CallToolRequest{
        Params: mcp.CallToolParams{
            Name: "hello_world",
            Arguments: map[string]interface{}{
                "name": "World",
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }
 
    // Print the result
    for _, content := range result.Content {
        if content.Type == "text" {
            fmt.Printf("Result: %s\n", content.Text)
        }
    }
}

StreamableHTTP Client Example

For StreamableHTTP-based servers, use the StreamableHTTP client:

package main
 
import (
    "context"
    "fmt"
    "log"
 
    "github.com/mark3labs/mcp-go/client"
    "github.com/mark3labs/mcp-go/mcp"
)
 
func main() {
    // Create a StreamableHTTP client
    c := client.NewStreamableHttpClient("http://localhost:8080/mcp")
    defer c.Close()
 
    ctx := context.Background()
 
    // Initialize and use the client
    if err := c.Initialize(ctx); err != nil {
        log.Fatal(err)
    }
 
    // Call a tool
    result, err := c.CallTool(ctx, mcp.CallToolRequest{
        Params: mcp.CallToolRequestParams{
            Name: "hello_world",
            Arguments: map[string]interface{}{
                "name": "StreamableHTTP World",
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }
 
    fmt.Printf("Tool result: %+v\n", result)
}

What's Next?

Now that you have a working MCP server and client:

  • Learn about Tools - Create powerful tool interfaces
  • Add Resources - Expose data sources to LLMs
  • Create Prompts - Build reusable prompt templates
  • Explore Advanced Features - Production-ready features

Common Issues

Server Won't Start

  • Check that the port isn't already in use
  • Verify Go module dependencies are installed
  • Ensure proper file permissions

Client Connection Failed

  • Verify the server is running and accessible
  • Check network connectivity for StreamableHTTP clients
  • Validate stdio command paths for stdio clients

Tool Calls Failing

  • Verify tool parameter types match the schema
  • Check error handling in your tool functions
  • Use the MCP Inspector for debugging