Add MCP Server Code generation
Add MCP (Model Context Protocol) Server Code Generation
This PR adds comprehensive support for generating MCP servers from OpenAPI specifications, enabling AI agents to interact with APIs through the Model Context Protocol.
Overview
The Model Context Protocol (MCP) allows AI systems to expose tools and resources in a standardized way. This implementation generates MCP server code from OpenAPI specs, automatically converting REST API operations into MCP tools with proper JSON schemas.
Key Features
1. MCP Server Generation
- New
mcp-server: truegeneration option - Generates
MCPHandlerInterfacewith methods for each operation - Generates
RegisterMCPTools()function to register tools with MCP server - Compatible with
strict-servermode via adapter pattern
2. Operation Filtering with x-mcp Extension
- Control which operations are exposed as MCP tools using
x-mcpboolean extension - Three filtering modes via
mcp-inclusion-modeconfiguration:-
include(default): Include operations by default, exclude only withx-mcp: false -
exclude: Exclude operations by default, include only withx-mcp: true -
explicit: Require explicitx-mcpfield on all operations (errors if missing)
-
3. Structured Input/Output Schemas
- Automatically generates JSON schemas for tool inputs organized by parameter type:
-
path: Path parameters -
query: Query parameters -
header: Header parameters -
cookie: Cookie parameters -
body: Request body (JSON)
-
- Automatically generates output schemas from response definitions
Configuration
Basic Configuration
package: api
generate:
mcp-server: true
strict-server: true # Optional: enables strict mode with adapter
models: true
With Operation Filtering
package: api
generate:
mcp-server: true
strict-server: true
output-options:
mcp-inclusion-mode: "explicit" # or "include" or "exclude"
OpenAPI Extension
paths:
/pets/{id}:
get:
operationId: GetPet
x-mcp: true # Include in MCP server
# ...
delete:
operationId: DeletePet
x-mcp: false # Exclude from MCP server
# ...
Generated Code
MCPHandlerInterface
type MCPHandlerInterface interface {
GetPet(ctx context.Context, request *mcp.CallToolRequest) (*mcp.CallToolResult, error)
ListPets(ctx context.Context, request *mcp.CallToolRequest) (*mcp.CallToolResult, error)
}
Tool Registration
func RegisterMCPTools(mcpServer MCPServer, si MCPHandlerInterface) error {
// Registers each operation as an MCP tool with proper schemas
}
Strict Mode Integration
When using strict-server: true, an adapter is generated:
func NewStrictMCPHandler(ssi StrictServerInterface, middlewares []StrictMCPMiddlewareFunc) MCPHandlerInterface
Implementation Details
Files Added/Modified
-
pkg/codegen/mcp.go: Core MCP generation logic (~460 lines)-
MCPInclusionModeenum type for type-safe filtering modes -
filterOperationsForMCP()- Filters operations based on x-mcp extension -
GenerateMCPServer()- Generates MCP interface and registration -
operationToMCPTool()- Converts OpenAPI operations to MCP tools -
buildMCPInputSchema()- Builds structured input JSON schemas -
buildMCPOutputSchema()- Extracts output schemas from responses
-
-
pkg/codegen/mcp_test.go: Comprehensive test suite (~490 lines)- Tests for x-mcp extension parsing (5 test cases)
- Tests for operation filtering (10 test cases covering all modes)
- Tests for schema generation
- All tests pass successfully
-
pkg/codegen/templates/mcp/: Go templates for code generation-
mcp-interface.tmpl- MCPHandlerInterface generation -
mcp-register.tmpl- Tool registration function
-
-
pkg/codegen/templates/strict/strict-mcp.tmpl: Strict mode adapter -
pkg/codegen/configuration.go: Configuration updates- Added
MCPInclusionModefield toOutputOptions - Added validation for inclusion mode values
- Added
-
pkg/codegen/operations.go: Strict server interface logic- Fixed duplicate
StrictServerInterfacegeneration when using MCP with other servers
- Fixed duplicate
-
examples/mcp-server/: Complete working example- Pet store API with MCP server
- Demonstrates tool registration and usage
- README with usage instructions
-
go.mod: Added MCP SDK dependency-
github.com/modelcontextprotocol/go-sdk v1.1.0
-
Key Technical Decisions
-
Quoted strings for JSON schemas: Uses quoted strings with proper escaping instead of backticks to avoid Go formatter issues with long lines
-
Filtering before generation: Operations are filtered before generating interfaces and registration code, ensuring consistency
-
Enum type for inclusion mode: Uses
MCPInclusionModetyped enum for compile-time safety instead of string literals -
Strict server pattern compatibility: MCP can be used standalone or with strict-server mode via adapter
-
No duplicate interfaces: When using MCP with other servers,
StrictServerInterfaceis only generated once
Testing
All changes are fully tested:
- ✅ 15 new test cases for MCP filtering functionality
- ✅ All existing tests continue to pass
- ✅ Tested with both standalone MCP and multi-server configurations
- ✅ Tested all three inclusion modes (include, exclude, explicit)
go test ./pkg/codegen -run "TestGetXMCPExtension|TestFilterOperationsForMCP" -v
# All 15 tests pass
Example Usage
1. Generate MCP Server Code
oapi-codegen -config cfg.yaml api.yaml > server.gen.go
2. Implement the Interface
type Server struct{}
func (s *Server) GetPet(ctx context.Context, request *mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// Extract parameters from request
var input struct {
Path struct {
ID string `json:"id"`
} `json:"path"`
}
if err := json.Unmarshal(request.Params.Arguments, &input); err != nil {
return nil, err
}
// Your business logic here
pet := fetchPet(input.Path.ID)
// Return result
result, _ := json.Marshal(map[string]interface{}{
"id": pet.ID,
"name": pet.Name,
})
return &mcp.CallToolResult{
Content: []interface{}{
map[string]interface{}{
"type": "text",
"text": string(result),
},
},
}, nil
}
3. Register Tools
mcpServer := mcp.NewServer()
handler := &Server{}
RegisterMCPTools(mcpServer, handler)
Breaking Changes
None. This is a purely additive feature that doesn't affect existing generation modes.
Migration Guide
No migration needed for existing users. To adopt MCP server generation:
- Add
mcp-server: trueto your config - Add the MCP SDK dependency:
go get github.com/modelcontextprotocol/go-sdk/mcp - Regenerate your code
- Implement the
MCPHandlerInterface
Documentation
- Added comprehensive README in
examples/mcp-server/with complete working example - Added inline documentation in all new functions and types
- Added detailed comments explaining the three inclusion modes
Related Links
- MCP Specification: https://github.com/modelcontextprotocol
- MCP Go SDK: https://github.com/modelcontextprotocol/go-sdk
Checklist
- [x] Implementation complete
- [x] Tests added and passing
- [x] Example application included
- [x] Documentation added
- [x] No breaking changes
- [x] Follows existing code patterns (uses templates, configuration structure, etc.)
- [x] Type-safe enum for configuration options
- [x] Comprehensive error messages
This PR enables oapi-codegen users to seamlessly expose their OpenAPI-defined APIs as MCP tools, making them accessible to AI agents and LLM applications with minimal effort.
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
| Diff | Package | Supply Chain Security |
Vulnerability | Quality | Maintenance | License |
|---|---|---|---|---|---|---|
| github.com/modelcontextprotocol/go-sdk@v1.1.0 | ||||||
| golang.org/x/tools@v0.34.0 | ||||||
| golang.org/x/mod@v0.25.0 |