title | description |
---|---|
Contributing |
Guidelines for contributing to the mcp-golang project |
This document provides a step-by-step guide for contributing to the mcp-golang project. By no means is it complete, but it should help you get started.
To set up your development environment, follow these steps:
- Go 1.19 or higher
- Git
- Clone the repository:
git clone https://github.com/rvoh-emccaleb/mcp-golang.git
cd mcp-golang
- Install dependencies:
go mod download
- Run tests:
go test ./...
The project is organized into several key packages:
server/
: Core server implementationtransport/
: Transport layer implementations (stdio, SSE)protocol/
: MCP protocol implementationexamples/
: Example implementationsinternal/
: Internal utilities and helpers
To implement a custom transport, create a struct that implements the Transport
interface.
If your transport is not part of the spec then you can add it as an experimental feature.
Before you implement the transport, you should have a good understanding of the MCP protocol. Take a look at https://spec.modelcontextprotocol.io/specification/
All new functions should have unit tests where possible. We currently use testify for this. Each test should explain its purpose and expected behavior. E.g.
// TestProtocol_Request tests the core request-response functionality of the protocol.
// This is the most important test as it covers the primary use case of the protocol.
// It includes subtests for:
// 1. Successful request/response with proper correlation
// 2. Request timeout handling
// 3. Request cancellation via context
// These scenarios ensure the protocol can handle both successful and error cases
// while maintaining proper message correlation and resource cleanup.
func TestProtocol_Request(t *testing.T) {
p := NewProtocol(nil)
transport := mcp.newMockTransport()
if err := p.Connect(transport); err != nil {
t.Fatalf("Connect failed: %v", err)
}
// Test successful request
t.Run("Successful request", func(t *testing.T) {
ctx := context.Background()
go func() {
// Simulate response after a short delay
time.Sleep(10 * time.Millisecond)
msgs := transport.getMessages()
if len(msgs) == 0 {
t.Error("No messages sent")
return
}
lastMsg := msgs[len(msgs)-1]
req, ok := lastMsg.(map[string]interface{})
if !ok {
t.Error("Last message is not a request")
return
}
// Simulate response
transport.simulateMessage(map[string]interface{}{
"jsonrpc": "2.0",
"id": req["id"],
"result": "test result",
})
}()
result, err := p.Request(ctx, "test_method", map[string]string{"key": "value"}, nil)
if err != nil {
t.Fatalf("Request failed: %v", err)
}
if result != "test result" {
t.Errorf("Expected result 'test result', got %v", result)
}
})
// Test request timeout
t.Run("Request timeout", func(t *testing.T) {
ctx := context.Background()
opts := &RequestOptions{
Timeout: 50 * time.Millisecond,
}
_, err := p.Request(ctx, "test_method", nil, opts)
if err == nil {
t.Fatal("Expected timeout error, got nil")
}
})
// Test request cancellation
t.Run("Request cancellation", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(10 * time.Millisecond)
cancel()
}()
_, err := p.Request(ctx, "test_method", nil, nil)
if !errors.Is(err, context.Canceled) {
t.Fatalf("Expected context.Canceled error, got %v", err)
}
})
}
}
Run integration tests that use the actual transport layers:
func TestWithStdioTransport(t *testing.T) {
transport := stdio.NewStdioServerTransport()
server := server.NewServer(transport)
// Test server with real transport
}
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Run existing tests
- Submit a pull request
- Keep changes focused and atomic
- Follow existing code style
- Include tests for new functionality
- Update documentation as needed
- Add yourself to CONTRIBUTORS.md
Follow these steps to install and run Mintlify on your operating system:
Step 1: Install Mintlify:
```bash npm
npm i -g mintlify
```
```bash yarn
yarn global add mintlify
```
Step 2: Navigate to the docs directory (where the mint.json
file is located) and execute the following command:
mintlify dev
A local preview of your documentation will be available at http://localhost:3000
.
When your PR merges into the main branch, it will be deployed automatically.
- Check existing GitHub issues
- Join our Discord community
- Read the Model Context Protocol specification