> ## Documentation Index
> Fetch the complete documentation index at: https://mcpgolang.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Contributing

> Guidelines for contributing to the mcp-golang project

## Development Guide

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.

### Development Setup

To set up your development environment, follow these steps:

#### Prerequisites

* Go 1.19 or higher
* Git

#### Local Development

1. Clone the repository:

```bash theme={null}
git clone https://github.com/metoro-io/mcp-golang.git
cd mcp-golang
```

2. Install dependencies:

```bash theme={null}
go mod download
```

3. Run tests:

```bash theme={null}
go test ./...
```

### Project Structure

The project is organized into several key packages:

* `server/`: Core server implementation
* `transport/`: Transport layer implementations (stdio, SSE)
* `protocol/`: MCP protocol implementation
* `examples/`: Example implementations
* `internal/`: Internal utilities and helpers

### Implementation Guidelines

#### Creating a Custom Transport

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/](https://spec.modelcontextprotocol.io/specification/)

### Testing

#### Unit Tests

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.

```go theme={null}

// 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)
		}
	})
}
}
```

#### Integration Tests

Run integration tests that use the actual transport layers:

```go theme={null}
func TestWithStdioTransport(t *testing.T) {
    transport := stdio.NewStdioServerTransport()
    server := server.NewServer(transport)
    
    // Test server with real transport
}
```

### Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests for new functionality
5. Run existing tests
6. Submit a pull request

#### Pull Request Guidelines

* Keep changes focused and atomic
* Follow existing code style
* Include tests for new functionality
* Update documentation as needed
* Add yourself to CONTRIBUTORS.md

## Adding docs

<Info>
  **Prerequisite**: Please install Node.js (version 19 or higher) before proceeding.
</Info>

Follow these steps to install and run Mintlify on your operating system:

**Step 1**: Install Mintlify:

<CodeGroup>
  ```bash npm theme={null}
  npm i -g mintlify
  ```

  ```bash yarn theme={null}
  yarn global add mintlify
  ```
</CodeGroup>

**Step 2**: Navigate to the docs directory (where the `mint.json` file is located) and execute the following command:

```bash theme={null}
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.

## Getting Help

* Check existing [GitHub issues](https://github.com/metoro-io/mcp-golang/issues)
* Join our [Discord community](https://discord.gg/33saRwE3pT)
* Read the [Model Context Protocol specification](https://modelcontextprotocol.io/)
