Skip to content

chore: upgrade modelcontextprotocol #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion description_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"strings"
"testing"

"github.com/modelcontextprotocol/go-sdk/jsonschema"
"github.com/google/jsonschema-go/jsonschema"
)

func TestGenerateAIFriendlyDescription_WithJsonSchema(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion error.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"strings"

"github.com/modelcontextprotocol/go-sdk/jsonschema"
"github.com/google/jsonschema-go/jsonschema"
)

// generateAI400ErrorResponse creates a comprehensive, AI-optimized error response for 400 HTTP errors
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ toolchain go1.24.6

require (
github.com/getkin/kin-openapi v0.132.0
github.com/modelcontextprotocol/go-sdk v0.2.0
github.com/google/jsonschema-go v0.2.0
github.com/modelcontextprotocol/go-sdk v0.2.1-0.20250812214950-6e03217c831b
go.yaml.in/yaml/v3 v3.0.4
)

Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/jsonschema-go v0.2.0 h1:Uh19091iHC56//WOsAd1oRg6yy1P9BpSvpjOL6RcjLQ=
github.com/google/jsonschema-go v0.2.0/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
Expand All @@ -18,8 +20,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/modelcontextprotocol/go-sdk v0.2.0 h1:PESNYOmyM1c369tRkzXLY5hHrazj8x9CY1Xu0fLCryM=
github.com/modelcontextprotocol/go-sdk v0.2.0/go.mod h1:0sL9zUKKs2FTTkeCCVnKqbLJTw5TScefPAzojjU459E=
github.com/modelcontextprotocol/go-sdk v0.2.1-0.20250812214950-6e03217c831b h1:UY+mamH9fcvW4D7X2DcNnTUNSFagNNr85evEF1xAdqs=
github.com/modelcontextprotocol/go-sdk v0.2.1-0.20250812214950-6e03217c831b/go.mod h1:71VUZVa8LL6WARvSgLJ7DMpDWSeomT4uBv8g97mGBvo=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY=
Expand Down
2 changes: 1 addition & 1 deletion openapi2mcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"net/http"

"github.com/getkin/kin-openapi/openapi3"
"github.com/modelcontextprotocol/go-sdk/jsonschema"
"github.com/google/jsonschema-go/jsonschema"
)

// OpenAPIOperation describes a single OpenAPI operation to be mapped to an MCP tool.
Expand Down
15 changes: 7 additions & 8 deletions postprocess_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"testing"

"github.com/getkin/kin-openapi/openapi3"
"github.com/modelcontextprotocol/go-sdk/jsonschema"
"github.com/google/jsonschema-go/jsonschema"
)

func TestPostProcessSchema_Integration(t *testing.T) {
Expand All @@ -29,7 +29,7 @@ func TestPostProcessSchema_Integration(t *testing.T) {

// Build the initial schema
originalSchema := BuildInputSchema(params, nil)

// Verify original schema doesn't have the custom description
if originalSchema.Description != "" {
t.Errorf("Original schema should not have description, got: %s", originalSchema.Description)
Expand All @@ -48,11 +48,11 @@ func TestPostProcessSchema_Integration(t *testing.T) {
if processedSchema.Type != "object" {
t.Errorf("Expected type 'object', got %q", processedSchema.Type)
}

if processedSchema.Properties == nil {
t.Error("Properties should be preserved")
}

if _, ok := processedSchema.Properties["testParam"]; !ok {
t.Error("testParam property should be preserved")
}
Expand All @@ -64,8 +64,7 @@ func TestPostProcessSchema_Integration(t *testing.T) {

func TestPostProcessSchema_TypesIntegrity(t *testing.T) {
// Test that the function signature change maintains type safety
var postProcessor func(string, jsonschema.Schema) jsonschema.Schema
postProcessor = func(toolName string, schema jsonschema.Schema) jsonschema.Schema {
postProcessor := func(toolName string, schema jsonschema.Schema) jsonschema.Schema {
// This demonstrates the function signature is correct
return schema
}
Expand All @@ -83,9 +82,9 @@ func TestPostProcessSchema_TypesIntegrity(t *testing.T) {
testSchema := jsonschema.Schema{
Type: "object",
}

result := opts.PostProcessSchema("test", testSchema)
if result.Type != "object" {
t.Error("Function should return the schema")
}
}
}
60 changes: 4 additions & 56 deletions register.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"time"

"github.com/getkin/kin-openapi/openapi3"
"github.com/modelcontextprotocol/go-sdk/jsonschema"
"github.com/google/jsonschema-go/jsonschema"
"github.com/modelcontextprotocol/go-sdk/mcp"
)

Expand Down Expand Up @@ -189,58 +189,6 @@ func generateAIFriendlyDescription(op OpenAPIOperation, inputSchema jsonschema.S
return desc.String()
}

// generateExampleValue creates appropriate example values based on the parameter schema
func generateExampleValue(prop map[string]any) any {
typeStr, _ := prop["type"].(string)

// Check for enum values first
if enum, ok := prop["enum"].([]any); ok && len(enum) > 0 {
return enum[0]
}

// Check for example values in schema
if example, ok := prop["example"]; ok {
return example
}

// Generate based on type
switch typeStr {
case "string":
if format, ok := prop["format"].(string); ok {
switch format {
case "email":
return "[email protected]"
case "uri", "url":
return "https://example.com"
case "date":
return "2024-01-01"
case "date-time":
return "2024-01-01T00:00:00Z"
case "uuid":
return "123e4567-e89b-12d3-a456-426614174000"
default:
return "example_string"
}
}
return "example_string"
case "number":
return 123.45
case "integer":
return 123
case "boolean":
return true
case "array":
if items, ok := prop["items"].(map[string]any); ok {
return []any{generateExampleValue(items)}
}
return []any{"item1", "item2"}
case "object":
return map[string]any{"key": "value"}
default:
return nil
}
}

// generateExampleValueFromSchema creates appropriate example values based on the jsonschema.Schema
func generateExampleValueFromSchema(prop *jsonschema.Schema) any {
if prop == nil {
Expand Down Expand Up @@ -501,7 +449,7 @@ func RegisterOpenAPITools(server *mcp.Server, ops []OpenAPIOperation, doc *opena
}
}

mcp.AddTool(server, tool, func(ctx context.Context, session *mcp.ServerSession, params *mcp.CallToolParams) (*mcp.CallToolResult, error) {
mcp.AddTool(server, tool, func(ctx context.Context, req *mcp.ServerRequest[*mcp.CallToolParams]) (*mcp.CallToolResult, error) {
info := "External documentation URL: " + doc.ExternalDocs.URL
if doc.ExternalDocs.Description != "" {
info += "\nDescription: " + doc.ExternalDocs.Description
Expand Down Expand Up @@ -531,7 +479,7 @@ func RegisterOpenAPITools(server *mcp.Server, ops []OpenAPIOperation, doc *opena
}
}

mcp.AddTool(server, tool, func(ctx context.Context, session *mcp.ServerSession, params *mcp.CallToolParams) (*mcp.CallToolResult, error) {
mcp.AddTool(server, tool, func(ctx context.Context, req *mcp.ServerRequest[*mcp.CallToolParams]) (*mcp.CallToolResult, error) {
var sb strings.Builder
if doc.Info.Title != "" {
sb.WriteString("Title: " + doc.Info.Title + "\n")
Expand Down Expand Up @@ -584,7 +532,7 @@ func RegisterOpenAPITools(server *mcp.Server, ops []OpenAPIOperation, doc *opena
MIMEType: "application/json",
}

server.AddResource(&timestampResource, func(ctx context.Context, session *mcp.ServerSession, params *mcp.ReadResourceParams) (*mcp.ReadResourceResult, error) {
server.AddResource(&timestampResource, func(ctx context.Context, req *mcp.ServerRequest[*mcp.ReadResourceParams]) (*mcp.ReadResourceResult, error) {
now := time.Now().Unix()
content := fmt.Sprintf(`{"unix_timestamp": %d, "iso8601": "%s", "timezone": "%s"}`,
now,
Expand Down
11 changes: 1 addition & 10 deletions schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"

"github.com/getkin/kin-openapi/openapi3"
"github.com/modelcontextprotocol/go-sdk/jsonschema"
"github.com/google/jsonschema-go/jsonschema"
)

// escapeParameterName converts parameter names with brackets to MCP-compatible names.
Expand All @@ -31,15 +31,6 @@ func escapeParameterName(name string) string {
return escaped
}

// unescapeParameterName converts escaped parameter names back to their original form.
// This maintains a mapping from escaped names to original names for parameter lookup.
func unescapeParameterName(escaped string, originalNames map[string]string) string {
if original, exists := originalNames[escaped]; exists {
return original
}
return escaped // Return as-is if not found in mapping
}

// buildParameterNameMapping creates a mapping from escaped parameter names to original names.
// This is used to reverse the escaping when looking up parameter values.
func buildParameterNameMapping(params openapi3.Parameters) map[string]string {
Expand Down
76 changes: 2 additions & 74 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,84 +5,12 @@ import (
"context"
"fmt"
"net/http"
"os"
"strings"

"github.com/getkin/kin-openapi/openapi3"
"github.com/modelcontextprotocol/go-sdk/mcp"
)

// authContextFunc extracts authentication headers from HTTP requests and sets them
// as environment variables for the duration of each request. This allows API keys
// and other authentication to be provided via HTTP headers when using HTTP mode.
func authContextFunc(ctx context.Context, r *http.Request) context.Context {
// Save original environment values to restore them later
origAPIKey := os.Getenv("API_KEY")
origBearerToken := os.Getenv("BEARER_TOKEN")
origBasicAuth := os.Getenv("BASIC_AUTH")

// Extract authentication from HTTP headers
if apiKey := r.Header.Get("X-API-Key"); apiKey != "" {
os.Setenv("API_KEY", apiKey)
} else if apiKey := r.Header.Get("Api-Key"); apiKey != "" {
os.Setenv("API_KEY", apiKey)
}

if bearerToken := r.Header.Get("Authorization"); bearerToken != "" {
if len(bearerToken) > 7 && bearerToken[:7] == "Bearer " {
os.Setenv("BEARER_TOKEN", bearerToken[7:])
} else if len(bearerToken) > 6 && bearerToken[:6] == "Basic " {
os.Setenv("BASIC_AUTH", bearerToken[6:])
}
}

// Create a context that restores the original environment when done
return &authContext{
Context: ctx,
origAPIKey: origAPIKey,
origBearerToken: origBearerToken,
origBasicAuth: origBasicAuth,
}
}

// authContext wraps a context and restores original environment variables when done
type authContext struct {
context.Context
origAPIKey string
origBearerToken string
origBasicAuth string
}

// Done restores the original environment variables when the context is done
func (c *authContext) Done() <-chan struct{} {
done := c.Context.Done()
if done != nil {
go func() {
<-done
c.restoreEnv()
}()
}
return done
}

func (c *authContext) restoreEnv() {
if c.origAPIKey != "" {
os.Setenv("API_KEY", c.origAPIKey)
} else {
os.Unsetenv("API_KEY")
}
if c.origBearerToken != "" {
os.Setenv("BEARER_TOKEN", c.origBearerToken)
} else {
os.Unsetenv("BEARER_TOKEN")
}
if c.origBasicAuth != "" {
os.Setenv("BASIC_AUTH", c.origBasicAuth)
} else {
os.Unsetenv("BASIC_AUTH")
}
}

// 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:
Expand Down Expand Up @@ -118,8 +46,8 @@ func NewServerWithOps(name, version string, doc *openapi3.T, ops []OpenAPIOperat
//
// openapi2mcp.ServeStdio(srv)
func ServeStdio(server *mcp.Server) error {
transport := mcp.NewStdioTransport()
_, err := server.Connect(context.Background(), transport)
transport := new(mcp.StdioTransport)
_, err := server.Connect(context.Background(), transport, nil)
return err
}

Expand Down
16 changes: 5 additions & 11 deletions tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"strings"

"github.com/getkin/kin-openapi/openapi3"
"github.com/modelcontextprotocol/go-sdk/jsonschema"
"github.com/google/jsonschema-go/jsonschema"
"github.com/modelcontextprotocol/go-sdk/mcp"
)

Expand All @@ -30,17 +30,11 @@ func toolHandler(
baseURLs []string,
confirmDangerousActions bool,
requestHandler func(req *http.Request) (*http.Response, error),
) func(ctx context.Context, session *mcp.ServerSession, params *mcp.CallToolParams) (*mcp.CallToolResult, error) {
return func(ctx context.Context, session *mcp.ServerSession, params *mcp.CallToolParams) (*mcp.CallToolResult, error) {
var args map[string]any
if params.Arguments == nil {
) func(ctx context.Context, req *mcp.ServerRequest[*mcp.CallToolParams]) (*mcp.CallToolResult, error) {
return func(ctx context.Context, req *mcp.ServerRequest[*mcp.CallToolParams]) (*mcp.CallToolResult, error) {
args, ok := req.Params.Arguments.(map[string]any)
if args == nil || !ok {
args = map[string]any{}
} else {
var ok bool
args, ok = params.Arguments.(map[string]any)
if !ok {
args = map[string]any{}
}
}

// Build parameter name mapping for escaped parameter names
Expand Down
Loading