openapi2mcp

package
v0.2.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2025 License: MIT Imports: 18 Imported by: 0

README

openapi2mcp Go Library

This package provides a Go library for converting OpenAPI 3.x specifications into MCP (Model Context Protocol) tool servers.

Installation

go get github.com/jedisct1/openapi-mcp/pkg/openapi2mcp

For direct access to MCP types and tools:

go get github.com/jedisct1/openapi-mcp/pkg/mcp

Usage

package main

import (
        "log"
        "github.com/jedisct1/openapi-mcp/pkg/openapi2mcp"
)

func main() {
        // Load OpenAPI spec
        doc, err := openapi2mcp.LoadOpenAPISpec("openapi.yaml")
        if err != nil {
                log.Fatal(err)
        }

        // Create MCP server
        srv := openapi2mcp.NewServer("myapi", doc.Info.Version, doc)

        // Serve over HTTP (StreamableHTTP is now the default)
        if err := openapi2mcp.ServeStreamableHTTP(srv, ":8080", "/mcp"); err != nil {
                log.Fatal(err)
        }

        // Or serve over stdio
        // if err := openapi2mcp.ServeStdio(srv); err != nil {
        //     log.Fatal(err)
        // }
}
Using MCP Package Directly

For more advanced usage, you can work with MCP types and tools directly:

package main

import (
        "context"
        "log"

        "github.com/jedisct1/openapi-mcp/pkg/mcp/mcp"
        "github.com/jedisct1/openapi-mcp/pkg/mcp/server"
        "github.com/jedisct1/openapi-mcp/pkg/openapi2mcp"
)

func main() {
        // Load OpenAPI spec
        doc, err := openapi2mcp.LoadOpenAPISpec("openapi.yaml")
        if err != nil {
                log.Fatal(err)
        }

        // Create MCP server manually
        srv := server.NewMCPServer("myapi", doc.Info.Version)

        // Register OpenAPI tools
        ops := openapi2mcp.ExtractOpenAPIOperations(doc)
        openapi2mcp.RegisterOpenAPITools(srv, ops, doc, nil)

        // Add custom tools using the MCP package directly
        customTool := mcp.NewTool("custom",
                mcp.WithDescription("A custom tool"),
                mcp.WithString("message", mcp.Description("Message to process"), mcp.Required()),
        )

        srv.AddTool(customTool, func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
                args := req.GetArguments()
                message := args["message"].(string)

                return &mcp.CallToolResult{
                        Content: []mcp.Content{
                                mcp.TextContent{
                                        Type: "text",
                                        Text: "Processed: " + message,
                                },
                        },
                }, nil
        })

        // Serve
        if err := server.ServeStdio(srv); err != nil {
                log.Fatal(err)
        }
}

Features

  • Convert OpenAPI 3.x specifications to MCP tool servers
  • Support for HTTP (StreamableHTTP is default, SSE also available) and stdio transport
  • Automatic tool generation from OpenAPI operations
  • Built-in validation and error handling
  • AI-optimized responses with structured output

API Documentation

See GoDoc for complete API documentation.

HTTP Client Development

When using HTTP mode, openapi-mcp now serves a StreamableHTTP-based MCP server by default. For developers building HTTP clients, you can interact with the /mcp endpoint using POST/GET/DELETE as per the StreamableHTTP protocol. SSE is still available by running with the --http-transport=sse flag or using ServeHTTP in Go.

See the StreamableHTTP specification for protocol details.

If you need SSE, you can still use:

// Serve over HTTP using SSE
if err := openapi2mcp.ServeHTTP(srv, ":8080", "/mcp"); err != nil {
    log.Fatal(err)
}

Documentation

Overview

http_lint.go

Package openapi2mcp provides functions to expose OpenAPI operations as MCP tools and servers. It enables loading OpenAPI specs, generating MCP tool schemas, and running MCP servers that proxy real HTTP calls.

register.go

schema.go

selftest.go

server.go

spec.go

summary.go

Package openapi2mcp provides functionality for converting OpenAPI specifications to MCP tools. For working with MCP types and tools directly, import github.com/jedisct1/openapi-mcp/pkg/mcp/mcp and github.com/jedisct1/openapi-mcp/pkg/mcp/server

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildInputSchema

func BuildInputSchema(params openapi3.Parameters, requestBody *openapi3.RequestBodyRef) map[string]any

BuildInputSchema converts OpenAPI parameters and request body schema to a single JSON Schema object for MCP tool input validation. Returns a JSON Schema as a map[string]any. Example usage for BuildInputSchema:

params := ... // openapi3.Parameters from an operation
reqBody := ... // *openapi3.RequestBodyRef from an operation
schema := openapi2mcp.BuildInputSchema(params, reqBody)
// schema is a map[string]any representing the JSON schema for tool input

func GetMessageURL added in v0.2.4

func GetMessageURL(addr, basePath, sessionID string) string

GetMessageURL returns the URL for sending JSON-RPC requests to the MCP server. addr is the address the server is listening on (e.g., ":8080", "0.0.0.0:8080", "localhost:8080"). basePath is the base HTTP path (e.g., "/mcp"). sessionID should be the session ID received from the SSE endpoint event. Example usage:

url := openapi2mcp.GetMessageURL(":8080", "/custom-base", "session-id-123")
// Returns: "http://localhost:8080/custom-base/message?sessionId=session-id-123"

func GetSSEURL added in v0.2.4

func GetSSEURL(addr, basePath string) string

GetSSEURL returns the URL for establishing an SSE connection to the MCP server. addr is the address the server is listening on (e.g., ":8080", "0.0.0.0:8080", "localhost:8080"). basePath is the base HTTP path (e.g., "/mcp"). Example usage:

url := openapi2mcp.GetSSEURL(":8080", "/custom-base")
// Returns: "http://localhost:8080/custom-base/sse"

func GetStreamableHTTPURL added in v0.2.6

func GetStreamableHTTPURL(addr, basePath string) string

GetStreamableHTTPURL returns the URL for the Streamable HTTP endpoint of the MCP server. addr is the address the server is listening on (e.g., ":8080", "0.0.0.0:8080", "localhost:8080"). basePath is the base HTTP path (e.g., "/mcp"). Example usage:

url := openapi2mcp.GetStreamableHTTPURL(":8080", "/custom-base")
// Returns: "http://localhost:8080/custom-base"

func HandlerForBasePath added in v0.2.5

func HandlerForBasePath(server *mcpserver.MCPServer, basePath string) http.Handler

HandlerForBasePath returns an http.Handler that serves the given MCP server at the specified basePath. This is useful for multi-mount HTTP servers, where you want to serve multiple OpenAPI schemas at different URL paths. Example usage:

handler := openapi2mcp.HandlerForBasePath(srv, "/petstore")
mux.Handle("/petstore/", handler)

func HandlerForStreamableHTTP added in v0.2.6

func HandlerForStreamableHTTP(server *mcpserver.MCPServer, basePath string) http.Handler

HandlerForStreamableHTTP returns an http.Handler that serves the given MCP server at the specified basePath using StreamableHTTP. This is useful for multi-mount HTTP servers, where you want to serve multiple OpenAPI schemas at different URL paths. Example usage:

handler := openapi2mcp.HandlerForStreamableHTTP(srv, "/petstore")
mux.Handle("/petstore", handler)

func LoadOpenAPISpec

func LoadOpenAPISpec(path string) (*openapi3.T, error)

LoadOpenAPISpec loads and parses an OpenAPI YAML or JSON file from the given path. Returns the parsed OpenAPI document or an error. Example usage for LoadOpenAPISpec:

doc, err := openapi2mcp.LoadOpenAPISpec("petstore.yaml")
if err != nil { log.Fatal(err) }
ops := openapi2mcp.ExtractOpenAPIOperations(doc)

func LoadOpenAPISpecFromBytes

func LoadOpenAPISpecFromBytes(data []byte) (*openapi3.T, error)

LoadOpenAPISpecFromBytes loads and parses an OpenAPI YAML or JSON spec from a byte slice. Returns the parsed OpenAPI document or an error.

func LoadOpenAPISpecFromString

func LoadOpenAPISpecFromString(data string) (*openapi3.T, error)

LoadOpenAPISpecFromString loads and parses an OpenAPI YAML or JSON spec from a string. Returns the parsed OpenAPI document or an error.

func NewServer

func NewServer(name, version string, doc *openapi3.T) *mcpserver.MCPServer

NewServer creates a new MCP server, registers all OpenAPI tools, and returns the server. Equivalent to calling RegisterOpenAPITools with all operations from the spec. Example usage for NewServer:

doc, _ := openapi2mcp.LoadOpenAPISpec("petstore.yaml")
srv := openapi2mcp.NewServer("petstore", doc.Info.Version, doc)
openapi2mcp.ServeHTTP(srv, ":8080")

func NewServerWithOps

func NewServerWithOps(name, version string, doc *openapi3.T, ops []OpenAPIOperation) *mcpserver.MCPServer

NewServerWithOps creates a new MCP server, registers the provided OpenAPI operations, and returns the server. Example usage for NewServerWithOps:

doc, _ := openapi2mcp.LoadOpenAPISpec("petstore.yaml")
ops := openapi2mcp.ExtractOpenAPIOperations(doc)
srv := openapi2mcp.NewServerWithOps("petstore", doc.Info.Version, doc, ops)
openapi2mcp.ServeHTTP(srv, ":8080")

func PrintToolSummary

func PrintToolSummary(ops []OpenAPIOperation)

PrintToolSummary prints a summary of the generated tools (count, tags, etc).

func RegisterOpenAPITools

func RegisterOpenAPITools(server *mcpserver.MCPServer, ops []OpenAPIOperation, doc *openapi3.T, opts *ToolGenOptions) []string

RegisterOpenAPITools registers each OpenAPI operation as an MCP tool with a real HTTP handler. Also adds tools for externalDocs, info, and describe if present in the OpenAPI spec. The handler validates arguments, builds the HTTP request, and returns the HTTP response as the tool result. Returns the list of tool names registered.

func SelfTestOpenAPIMCP

func SelfTestOpenAPIMCP(doc *openapi3.T, toolNames []string) error

SelfTestOpenAPIMCP checks that the generated MCP server matches the OpenAPI contract (basic: all required tools and arguments are present). Returns an error if any required tools or arguments are missing.

func SelfTestOpenAPIMCPWithOptions added in v0.2.0

func SelfTestOpenAPIMCPWithOptions(doc *openapi3.T, toolNames []string, detailedSuggestions bool) error

SelfTestOpenAPIMCPWithOptions runs the self-test with or without detailed suggestions.

func ServeHTTP

func ServeHTTP(server *mcpserver.MCPServer, addr string, basePath string) error

ServeHTTP starts the MCP server using HTTP SSE (wraps mcpserver.NewSSEServer and Start). addr is the address to listen on, e.g. ":8080". basePath is the base HTTP path to mount the MCP server (e.g. "/mcp"). Returns an error if the server fails to start. Example usage for ServeHTTP:

srv, _ := openapi2mcp.NewServer("petstore", "1.0.0", doc)
openapi2mcp.ServeHTTP(srv, ":8080", "/custom-base")

func ServeHTTPLint added in v0.2.0

func ServeHTTPLint(addr string, detailedSuggestions bool) error

ServeHTTPLint starts an HTTP server for linting OpenAPI specs

func ServeStdio

func ServeStdio(server *mcpserver.MCPServer) error

ServeStdio starts the MCP server using stdio (wraps mcpserver.ServeStdio). Returns an error if the server fails to start. Example usage for ServeStdio:

openapi2mcp.ServeStdio(srv)

func ServeStreamableHTTP added in v0.2.6

func ServeStreamableHTTP(server *mcpserver.MCPServer, addr string, basePath string) error

ServeStreamableHTTP starts the MCP server using HTTP StreamableHTTP (wraps mcpserver.NewStreamableHTTPServer and Start). addr is the address to listen on, e.g. ":8080". basePath is the base HTTP path to mount the MCP server (e.g. "/mcp"). Returns an error if the server fails to start. Example usage for ServeStreamableHTTP:

srv, _ := openapi2mcp.NewServer("petstore", "1.0.0", doc)
openapi2mcp.ServeStreamableHTTP(srv, ":8080", "/custom-base")

Types

type HTTPLintRequest added in v0.2.0

type HTTPLintRequest struct {
	OpenAPISpec string `json:"openapi_spec"` // The OpenAPI spec as a YAML or JSON string
}

HTTPLintRequest represents the request body for HTTP lint/validate endpoints

type HTTPLintServer added in v0.2.0

type HTTPLintServer struct {
	// contains filtered or unexported fields
}

HTTPLintServer provides HTTP endpoints for OpenAPI validation and linting

func NewHTTPLintServer added in v0.2.0

func NewHTTPLintServer(detailedSuggestions bool) *HTTPLintServer

NewHTTPLintServer creates a new HTTP lint server

func (*HTTPLintServer) HandleHealth added in v0.2.0

func (s *HTTPLintServer) HandleHealth(w http.ResponseWriter, r *http.Request)

HandleHealth handles GET requests for health checks

func (*HTTPLintServer) HandleLint added in v0.2.0

func (s *HTTPLintServer) HandleLint(w http.ResponseWriter, r *http.Request)

HandleLint handles POST requests to lint OpenAPI specs

type LintIssue added in v0.2.0

type LintIssue struct {
	Type       string `json:"type"`                // "error" or "warning"
	Message    string `json:"message"`             // The main error/warning message
	Suggestion string `json:"suggestion"`          // Actionable suggestion for fixing the issue
	Operation  string `json:"operation,omitempty"` // Operation ID where the issue was found
	Path       string `json:"path,omitempty"`      // API path where the issue was found
	Method     string `json:"method,omitempty"`    // HTTP method where the issue was found
	Parameter  string `json:"parameter,omitempty"` // Parameter name where the issue was found
	Field      string `json:"field,omitempty"`     // Specific field where the issue was found
}

LintIssue represents a single linting issue found in an OpenAPI spec

type LintResult added in v0.2.0

type LintResult struct {
	Success      bool        `json:"success"`           // Whether the linting/validation passed
	ErrorCount   int         `json:"error_count"`       // Number of errors found
	WarningCount int         `json:"warning_count"`     // Number of warnings found
	Issues       []LintIssue `json:"issues"`            // List of all issues found
	Summary      string      `json:"summary,omitempty"` // Summary message
}

LintResult represents the result of linting or validating an OpenAPI spec

func LintOpenAPISpec added in v0.2.0

func LintOpenAPISpec(doc *openapi3.T, detailedSuggestions bool) *LintResult

LintOpenAPISpec performs comprehensive linting and returns structured results

type OpenAPIOperation

type OpenAPIOperation struct {
	OperationID string
	Summary     string
	Description string
	Path        string
	Method      string
	Parameters  openapi3.Parameters
	RequestBody *openapi3.RequestBodyRef
	Tags        []string
	Security    openapi3.SecurityRequirements
}

OpenAPIOperation describes a single OpenAPI operation to be mapped to an MCP tool. It includes the operation's ID, summary, description, HTTP path/method, parameters, request body, and tags.

func ExtractFilteredOpenAPIOperations

func ExtractFilteredOpenAPIOperations(doc *openapi3.T, includeRegex, excludeRegex *regexp.Regexp) []OpenAPIOperation

ExtractFilteredOpenAPIOperations returns only those operations whose description matches includeRegex (if not nil) and does not match excludeRegex (if not nil). Returns a filtered slice of OpenAPIOperation. Example usage for ExtractFilteredOpenAPIOperations:

include := regexp.MustCompile("pets")
filtered := openapi2mcp.ExtractFilteredOpenAPIOperations(doc, include, nil)

func ExtractOpenAPIOperations

func ExtractOpenAPIOperations(doc *openapi3.T) []OpenAPIOperation

ExtractOpenAPIOperations extracts all operations from the OpenAPI spec, merging path-level and operation-level parameters. Returns a slice of OpenAPIOperation describing each operation. Example usage for ExtractOpenAPIOperations:

doc, err := openapi2mcp.LoadOpenAPISpec("petstore.yaml")
if err != nil { log.Fatal(err) }
ops := openapi2mcp.ExtractOpenAPIOperations(doc)

type ToolGenOptions

type ToolGenOptions struct {
	NameFormat              func(string) string
	TagFilter               []string
	DryRun                  bool
	PrettyPrint             bool
	Version                 string
	PostProcessSchema       func(toolName string, schema map[string]any) map[string]any
	ConfirmDangerousActions bool // if true, add confirmation prompt for dangerous actions
}

ToolGenOptions controls tool generation and output for OpenAPI-MCP conversion.

NameFormat: function to format tool names (e.g., strings.ToLower) TagFilter: only include operations with at least one of these tags (if non-empty) DryRun: if true, only print the generated tool schemas, don't register PrettyPrint: if true, pretty-print the output Version: version string to embed in tool annotations PostProcessSchema: optional hook to modify each tool's input schema before registration/output ConfirmDangerousActions: if true (default), require confirmation for PUT/POST/DELETE tools

func(toolName string, schema map[string]any) map[string]any

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL