Skip to content

Commit 702ca71

Browse files
authored
Merge branch 'main' into docs/quota-policy
2 parents e0b0e9f + 331665a commit 702ca71

19 files changed

Lines changed: 663 additions & 158 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module github.com/envoyproxy/ai-gateway
22

33
// Explicitly specify the Go patch version to be able to purge the CI cache correctly.
4-
go 1.25.7
4+
go 1.25.8
55

66
require (
77
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0

internal/apischema/anthropic/anthropic.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,10 +1113,11 @@ const (
11131113

11141114
func (t *ToolUnion) UnmarshalJSON(data []byte) error {
11151115
typ := gjson.GetBytes(data, "type")
1116-
if !typ.Exists() {
1117-
return errors.New("missing type field in tool")
1116+
typStr := toolTypeCustom
1117+
if typ.Exists() && typ.String() != "" {
1118+
typStr = typ.String()
11181119
}
1119-
switch typ.String() {
1120+
switch typStr {
11201121
case toolTypeCustom:
11211122
var tool Tool
11221123
if err := json.Unmarshal(data, &tool); err != nil {

internal/apischema/anthropic/anthropic_test.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -735,9 +735,20 @@ func TestToolUnion_UnmarshalJSON(t *testing.T) {
735735
want: ToolUnion{WebSearchTool: &WebSearchTool{Type: "web_search_20250305", Name: "web_search"}},
736736
},
737737
{
738-
name: "missing type",
739-
jsonStr: `{"name":"my_tool"}`,
740-
wantErr: true,
738+
name: "missing type defaults to custom",
739+
jsonStr: `{"name":"my_tool","description":"A tool","input_schema":{"type":"object"}}`,
740+
want: ToolUnion{Tool: &Tool{
741+
Name: "my_tool", Description: "A tool",
742+
InputSchema: ToolInputSchema{Type: "object"},
743+
}},
744+
},
745+
{
746+
name: "empty type defaults to custom",
747+
jsonStr: `{"type":"","name":"my_tool","input_schema":{"type":"object"}}`,
748+
want: ToolUnion{Tool: &Tool{
749+
Type: "", Name: "my_tool",
750+
InputSchema: ToolInputSchema{Type: "object"},
751+
}},
741752
},
742753
{
743754
name: "unknown type ignored",

internal/endpointspec/endpointspec.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,7 @@ func (MessagesEndpointSpec) GetTranslator(schema filterapi.VersionedAPISchema, m
344344
case filterapi.APISchemaAnthropic:
345345
return translator.NewAnthropicToAnthropicTranslator(schema.Version, modelNameOverride), nil
346346
case filterapi.APISchemaOpenAI:
347-
// The Anthropic prefix can be altered using values.yaml if necessary
348-
return translator.NewAnthropicToChatCompletionOpenAITranslator(schema.Version, modelNameOverride), nil
347+
return translator.NewAnthropicToChatCompletionOpenAITranslator(schema.OpenAIPrefix(), modelNameOverride), nil
349348
default:
350349
return nil, fmt.Errorf("/v1/messages endpoint only supports backends that return native Anthropic format (Anthropic, GCPAnthropic, AWSAnthropic). OpenAI translation is also supported. Backend %s uses different model format", schema.Name)
351350
}

internal/extproc/server.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ func (s *Server) Process(stream extprocv3.ExternalProcessor_ProcessServer) error
143143
var internalReqID string
144144
var originalReqID string
145145
var logger *slog.Logger
146+
// Seed the context with the server-level logger as a fallback so that loggerFromContext never returns nil in processMsg.
147+
ctx = context.WithValue(ctx, loggerContextKey, s.logger)
146148
defer func() {
147149
if !isUpstreamFilter {
148150
s.routerProcessorsPerReqIDMutex.Lock()

internal/mcpproxy/handlers.go

Lines changed: 141 additions & 74 deletions
Large diffs are not rendered by default.

internal/mcpproxy/handlers_test.go

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,15 @@ func TestServePOST_InitializeRequest(t *testing.T) {
255255
require.NoError(t, err)
256256
require.ElementsMatch(t, []filterapi.MCPBackendName{"backend1"}, slices.Collect(maps.Keys(perBackendSessions)))
257257

258-
count, sum := testotel.GetHistogramValues(t, mr, "mcp.initialization.duration", attribute.NewSet())
258+
// backend1 is the only backend that successfully initialized.
259+
count, sum := testotel.GetHistogramValues(t, mr, "mcp.initialization.duration", attribute.NewSet(
260+
attribute.String("mcp.backend", "backend1"),
261+
))
259262
require.Equal(t, 1, int(count)) // nolint: gosec
260263
require.Greater(t, sum, 0.0)
261264

262265
capaCount := testotel.GetCounterValue(t, mr, "mcp.capabilities.negotiated", attribute.NewSet(
266+
attribute.String("mcp.backend", "backend1"),
263267
attribute.String("capability.type", "tools"),
264268
attribute.String("capability.side", "server")))
265269
require.Equal(t, 1, int(capaCount))
@@ -616,16 +620,23 @@ func TestServePOST_ToolsCallRequest(t *testing.T) {
616620
var countAttrs, durationAttrs attribute.Set
617621
if tt.wantStatus == http.StatusOK {
618622
countAttrs = attribute.NewSet(
623+
attribute.String("mcp.backend", tt.wantBackend),
619624
attribute.String("mcp.method.name", "tools/call"),
620625
attribute.String("status", "success"),
621626
)
622-
durationAttrs = attribute.NewSet()
627+
durationAttrs = attribute.NewSet(
628+
attribute.String("mcp.backend", tt.wantBackend),
629+
)
623630
} else {
624631
countAttrs = attribute.NewSet(
632+
attribute.String("mcp.backend", tt.wantBackend),
625633
attribute.String("mcp.method.name", "tools/call"),
626634
attribute.String("status", "error"),
627635
)
628-
durationAttrs = attribute.NewSet(attribute.String("error.type", string(metrics.MCPErrorInvalidParam)))
636+
durationAttrs = attribute.NewSet(
637+
attribute.String("mcp.backend", tt.wantBackend),
638+
attribute.String("error.type", string(metrics.MCPErrorInvalidParam)),
639+
)
629640
}
630641

631642
methodCount := testotel.GetCounterValue(t, mr, "mcp.method.count", countAttrs)
@@ -688,7 +699,7 @@ func TestHandleToolCallRequest_UnknownBackend(t *testing.T) {
688699
httpReq := httptest.NewRequest(http.MethodPost, "/mcp", nil)
689700
rr := httptest.NewRecorder()
690701

691-
err := proxy.handleToolCallRequest(t.Context(), s, rr, &jsonrpc.Request{}, params, nil, httpReq)
702+
_, err := proxy.handleToolCallRequest(t.Context(), s, rr, &jsonrpc.Request{}, params, nil, httpReq)
692703
require.Error(t, err)
693704

694705
require.Equal(t, http.StatusNotFound, rr.Code)
@@ -719,7 +730,7 @@ func TestHandleToolCallRequest_BackendError(t *testing.T) {
719730
httpReq := httptest.NewRequest(http.MethodPost, "/mcp", nil)
720731
rr := httptest.NewRecorder()
721732

722-
err := proxy.handleToolCallRequest(t.Context(), s, rr, &jsonrpc.Request{}, params, nil, httpReq)
733+
_, err := proxy.handleToolCallRequest(t.Context(), s, rr, &jsonrpc.Request{}, params, nil, httpReq)
723734
require.Error(t, err)
724735

725736
require.Equal(t, http.StatusInternalServerError, rr.Code)
@@ -776,7 +787,7 @@ func TestHandleToolCallRequest_InvalidToolName(t *testing.T) {
776787
id := mustJSONRPCRequestID()
777788
req := &jsonrpc.Request{ID: id, Method: "tools/call"}
778789

779-
err := reqCtx.handleToolCallRequest(t.Context(), s, rr, req, params, nil, httpReq)
790+
_, err := reqCtx.handleToolCallRequest(t.Context(), s, rr, req, params, nil, httpReq)
780791
// JSON-RPC errors are application-level errors that should be returned for proper metrics tracking,
781792
// but they're not treated as span exceptions since the protocol worked correctly.
782793
require.Error(t, err)
@@ -840,7 +851,7 @@ func TestHandleToolCallRequest_ToolResultWithIsError(t *testing.T) {
840851
id := mustJSONRPCRequestID()
841852
req := &jsonrpc.Request{ID: id, Method: "tools/call"}
842853

843-
err := proxy.handleToolCallRequest(t.Context(), s, rr, req, params, nil, httpReq)
854+
_, err := proxy.handleToolCallRequest(t.Context(), s, rr, req, params, nil, httpReq)
844855
// isError: true means the tool executed successfully but returned an error result.
845856
// An error is returned for proper metrics tracking, but it's treated as an application-level
846857
// error (not a span exception) since the protocol worked correctly and the LLM needs to see these errors.
@@ -1365,7 +1376,7 @@ func TestMCPProxy_handleCompletionComplete(t *testing.T) {
13651376
},
13661377
} {
13671378
rr := httptest.NewRecorder()
1368-
err := proxy.handleCompletionComplete(t.Context(), &session{
1379+
_, err := proxy.handleCompletionComplete(t.Context(), &session{
13691380
reqCtx: proxy,
13701381
perBackendSessions: map[filterapi.MCPBackendName]*compositeSessionEntry{
13711382
"backend1": {sessionID: "test-session"},
@@ -1421,7 +1432,7 @@ func TestMCPPRoxy_handleResourceReadRequest(t *testing.T) {
14211432
t.Run("invalid resource name", func(t *testing.T) {
14221433
proxy := newTestMCPProxy()
14231434
rr := httptest.NewRecorder()
1424-
err := proxy.handleResourceReadRequest(t.Context(), nil, rr,
1435+
_, err := proxy.handleResourceReadRequest(t.Context(), nil, rr,
14251436
&jsonrpc.Request{Method: "resources/subscribe"}, &mcp.ReadResourceParams{
14261437
URI: "invalid-form",
14271438
},
@@ -1450,7 +1461,7 @@ func TestMCPPRoxy_handleResourceReadRequest(t *testing.T) {
14501461
perBackendSessions: map[filterapi.MCPBackendName]*compositeSessionEntry{"backend1": {sessionID: "test-session"}},
14511462
route: "test-route",
14521463
}
1453-
err := proxy.handleResourceReadRequest(t.Context(), s, rr, &jsonrpc.Request{ID: reqID, Method: "resources/read"}, &mcp.ReadResourceParams{
1464+
_, err := proxy.handleResourceReadRequest(t.Context(), s, rr, &jsonrpc.Request{ID: reqID, Method: "resources/read"}, &mcp.ReadResourceParams{
14541465
URI: downstreamResourceURI("file://foo-resource", "backend1"),
14551466
})
14561467
require.NoError(t, err)
@@ -1535,7 +1546,7 @@ func TestMCPProxy_handleClientToServerNotificationsProgress(t *testing.T) {
15351546
route: "test-route",
15361547
}
15371548
params := &mcp.ProgressNotificationParams{ProgressToken: tc.inputProgressToken}
1538-
err := proxy.handleClientToServerNotificationsProgress(t.Context(), s, rr,
1549+
_, err := proxy.handleClientToServerNotificationsProgress(t.Context(), s, rr,
15391550
&jsonrpc.Request{Method: "notifications/progress"}, params, nil)
15401551
if rr.Code != http.StatusOK {
15411552
require.Error(t, err)
@@ -1632,23 +1643,23 @@ func TestMCPProxy_handleClientToServerResponse(t *testing.T) {
16321643
t.Run("invalid IDs", func(t *testing.T) {
16331644
proxy := newTestMCPProxy()
16341645
rr := httptest.NewRecorder()
1635-
err := proxy.handleClientToServerResponse(t.Context(), nil, rr, &jsonrpc.Response{})
1646+
_, err := proxy.handleClientToServerResponse(t.Context(), nil, rr, &jsonrpc.Response{})
16361647
require.Error(t, err)
16371648
require.Equal(t, http.StatusBadRequest, rr.Code)
16381649
require.Contains(t, rr.Body.String(), "invalid response ID type: <nil>")
16391650

16401651
invalidID, err := jsonrpc.MakeID("invalidformatid")
16411652
require.NoError(t, err)
16421653
rr = httptest.NewRecorder()
1643-
err = proxy.handleClientToServerResponse(t.Context(), nil, rr, &jsonrpc.Response{ID: invalidID})
1654+
_, err = proxy.handleClientToServerResponse(t.Context(), nil, rr, &jsonrpc.Response{ID: invalidID})
16441655
require.Error(t, err)
16451656
require.Equal(t, http.StatusBadRequest, rr.Code)
16461657
require.Contains(t, rr.Body.String(), "invalid response ID format: invalidformatid")
16471658

16481659
invalidID2, err := jsonrpc.MakeID("__foo__")
16491660
require.NoError(t, err)
16501661
rr = httptest.NewRecorder()
1651-
err = proxy.handleClientToServerResponse(t.Context(), nil, rr, &jsonrpc.Response{ID: invalidID2})
1662+
_, err = proxy.handleClientToServerResponse(t.Context(), nil, rr, &jsonrpc.Response{ID: invalidID2})
16521663
require.ErrorContains(t, err, `invalid response ID type identifier: foo`)
16531664
require.Equal(t, http.StatusBadRequest, rr.Code)
16541665
require.Contains(t, rr.Body.String(), `invalid response ID type identifier`)
@@ -1719,7 +1730,7 @@ func TestMCPProxy_handleClientToServerResponse(t *testing.T) {
17191730
proxy.backendListenerAddr = testServer.URL
17201731

17211732
rr := httptest.NewRecorder()
1722-
err := proxy.handleClientToServerResponse(t.Context(), &session{
1733+
_, err := proxy.handleClientToServerResponse(t.Context(), &session{
17231734
reqCtx: proxy,
17241735
perBackendSessions: map[filterapi.MCPBackendName]*compositeSessionEntry{"backend1": {sessionID: "test-session"}},
17251736
route: "test-route",
@@ -1818,9 +1829,9 @@ func TestMCPServer_handleResourcesSubscriptionRequest(t *testing.T) {
18181829
}
18191830
switch pp := tc.p.(type) {
18201831
case *mcp.SubscribeParams:
1821-
err = proxy.handleResourcesSubscribeRequest(t.Context(), s, rr, req, pp, nil)
1832+
_, err = proxy.handleResourcesSubscribeRequest(t.Context(), s, rr, req, pp, nil)
18221833
case *mcp.UnsubscribeParams:
1823-
err = proxy.handleResourcesUnsubscribeRequest(t.Context(), s, rr, req, pp, nil)
1834+
_, err = proxy.handleResourcesUnsubscribeRequest(t.Context(), s, rr, req, pp, nil)
18241835
}
18251836
require.NoError(t, err)
18261837
require.Equal(t, http.StatusOK, rr.Code)
@@ -1837,7 +1848,7 @@ func Test_sendToAllBackendsAndAggregateResponsesImpl(t *testing.T) {
18371848
type testData struct {
18381849
Value string `json:"value"`
18391850
}
1840-
events := make(chan *sseEvent)
1851+
events := make(chan *backendEvent)
18411852
go func() {
18421853
for _, msg := range []jsonrpc.Message{
18431854
&jsonrpc.Response{ID: reqID, Result: []byte(`{"value": "foo"}`)},
@@ -1850,13 +1861,15 @@ func Test_sendToAllBackendsAndAggregateResponsesImpl(t *testing.T) {
18501861
// Error should be logged and ignored, not blocking the response.
18511862
&jsonrpc.Response{ID: reqID, Error: errors.New("some error")},
18521863
} {
1853-
events <- &sseEvent{backend: "a", messages: []jsonrpc.Message{msg}}
1864+
events <- &backendEvent{sseEvent: &sseEvent{backend: "a", messages: []jsonrpc.Message{msg}}}
18541865
}
18551866
close(events)
18561867
}()
18571868

18581869
rr := httptest.NewRecorder()
1870+
var testParams *mcp.ListToolsParams
18591871
err = sendToAllBackendsAndAggregateResponsesImpl(t.Context(), events, proxy, rr, s, &jsonrpc.Request{ID: reqID, Method: "test"},
1872+
testParams,
18601873
func(_ *session, res []broadCastResponse[testData]) testData {
18611874
var combined testData
18621875
for _, r := range res {

internal/mcpproxy/mcpproxy.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ import (
3333
// mcpRequestContext serves /mcp endpoint.
3434
type mcpRequestContext struct {
3535
*ProxyConfig
36-
metrics metrics.MCPMetrics
37-
requestHeaders http.Header
38-
originalPath string
36+
metrics metrics.MCPMetrics
37+
requestHeaders http.Header
38+
originalPath string
39+
perBackendMetricsRecorded bool
3940
}
4041

4142
// NewMCPProxy creates a new MCPProxy instance.
@@ -134,7 +135,8 @@ func extractMetaFromJSONRPCMessage(msg jsonrpc.Message) map[string]any {
134135

135136
// newSession creates a new session for a downstream client.
136137
// It multiplexes the initialize request to all backends defined in the MCPRoute associated with the downstream request.
137-
func (m *mcpRequestContext) newSession(ctx context.Context, p *mcp.InitializeParams, routeName filterapi.MCPRouteName, subject string, span tracingapi.MCPSpan) (*session, error) {
138+
// startAt is the time when the overall HTTP request started, used for recording request duration metrics.
139+
func (m *mcpRequestContext) newSession(ctx context.Context, p *mcp.InitializeParams, routeName filterapi.MCPRouteName, subject string, span tracingapi.MCPSpan, startAt time.Time) (*session, error) {
138140
m.l.Debug("creating new MCP session")
139141

140142
backends := m.routes[routeName]
@@ -162,16 +164,16 @@ func (m *mcpRequestContext) newSession(ctx context.Context, p *mcp.InitializePar
162164
if m.l.Enabled(ctx, slog.LevelDebug) {
163165
m.l.Debug("creating MCP session", slog.String("backend", backend.Name))
164166
}
165-
startAt := time.Now()
166-
initResult, err := m.initializeSession(ctx, routeName, backend, p)
167+
backendStartAt := time.Now()
168+
initResult, err := m.initializeSession(ctx, routeName, backend, p, startAt)
167169
if err != nil {
168170
m.l.Error("failed to create MCP session", slog.String("backend", backend.Name), slog.String("error", err.Error()))
169171
// If one backend fails, don't fail the overall connection. Create a session to the rest of the backends, as they
170172
// may provide the needed methods.
171173
// TODO: should we record a metric for this?
172174
return
173175
}
174-
m.metrics.RecordInitializationDuration(ctx, startAt, p)
176+
m.metrics.WithBackend(backend.Name).RecordInitializationDuration(ctx, backendStartAt, p)
175177
if m.l.Enabled(ctx, slog.LevelDebug) {
176178
m.l.Debug("created MCP session", slog.String("backend", backend.Name), slog.String("session_id", string(initResult.sessionID)))
177179
}
@@ -256,7 +258,7 @@ type initializeResult struct {
256258
result *mcp.InitializeResult
257259
}
258260

259-
func (m *mcpRequestContext) initializeSession(ctx context.Context, routeName filterapi.MCPRouteName, backend filterapi.MCPBackend, p *mcp.InitializeParams) (*initializeResult, error) {
261+
func (m *mcpRequestContext) initializeSession(ctx context.Context, routeName filterapi.MCPRouteName, backend filterapi.MCPBackend, p *mcp.InitializeParams, startAt time.Time) (*initializeResult, error) {
260262
// Send the initialize request to the MCP backend listener.
261263
reqID := mustJSONRPCRequestID()
262264
var (
@@ -344,7 +346,10 @@ func (m *mcpRequestContext) initializeSession(ctx context.Context, routeName fil
344346
if m.l.Enabled(ctx, slog.LevelDebug) {
345347
m.l.Debug("MCP session initialized", slog.Any("capabilities", initResult.Capabilities))
346348
}
347-
m.metrics.RecordServerCapabilities(ctx, initResult.Capabilities, p)
349+
backendMetrics := m.metrics.WithBackend(backend.Name)
350+
backendMetrics.RecordServerCapabilities(ctx, initResult.Capabilities, p)
351+
backendMetrics.RecordMethodCount(ctx, "initialize", p)
352+
backendMetrics.RecordRequestDuration(ctx, startAt, p)
348353
}
349354

350355
// Need to invoke "notifications/initialized" to complete the initialization.
@@ -364,6 +369,7 @@ func (m *mcpRequestContext) initializeSession(ctx context.Context, routeName fil
364369
body, _ := io.ReadAll(resp.Body)
365370
return nil, fmt.Errorf("MCP notifications/initialized request failed with status code %d, body=%s", resp.StatusCode, string(body))
366371
}
372+
m.metrics.WithBackend(backend.Name).RecordMethodCount(ctx, "notifications/initialized", p)
367373
}
368374
if m.l.Enabled(ctx, slog.LevelDebug) {
369375
m.l.Debug("sent MCP notifications/initialized", slog.String("backend", backend.Name), slog.String("session_id", sessionID))

internal/mcpproxy/mcpproxy_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"net/url"
1515
"sync"
1616
"testing"
17+
"time"
1718

1819
"github.com/modelcontextprotocol/go-sdk/jsonrpc"
1920
"github.com/modelcontextprotocol/go-sdk/mcp"
@@ -263,7 +264,7 @@ func TestNewSession_Success(t *testing.T) {
263264
proxy := newTestMCPProxy()
264265
proxy.backendListenerAddr = backendServer.URL
265266

266-
s, err := proxy.newSession(t.Context(), &mcp.InitializeParams{}, "test-route", "", nil)
267+
s, err := proxy.newSession(t.Context(), &mcp.InitializeParams{}, "test-route", "", nil, time.Now())
267268

268269
require.NoError(t, err)
269270
require.NotNil(t, s)
@@ -273,7 +274,7 @@ func TestNewSession_Success(t *testing.T) {
273274
func TestNewSession_NoBackend(t *testing.T) {
274275
proxy := newTestMCPProxy()
275276

276-
s, err := proxy.newSession(t.Context(), &mcp.InitializeParams{}, "test-route", "", nil)
277+
s, err := proxy.newSession(t.Context(), &mcp.InitializeParams{}, "test-route", "", nil, time.Now())
277278
require.ErrorContains(t, err, `failed to create MCP session to any backend`)
278279
require.Nil(t, s)
279280
}
@@ -303,7 +304,7 @@ data: {"jsonrpc":"2.0","id":"ff3964c5-4c79-4567-96e2-29e905754e58","result":{"ca
303304
proxy := newTestMCPProxy()
304305
proxy.backendListenerAddr = backendServer.URL
305306

306-
s, err := proxy.newSession(t.Context(), &mcp.InitializeParams{}, "test-route", "", nil)
307+
s, err := proxy.newSession(t.Context(), &mcp.InitializeParams{}, "test-route", "", nil, time.Now())
307308

308309
require.NoError(t, err)
309310
require.NotNil(t, s)
@@ -354,7 +355,7 @@ func TestInitializeSession_Success(t *testing.T) {
354355
proxy := newTestMCPProxy()
355356
proxy.backendListenerAddr = backendServer.URL
356357

357-
res, err := proxy.initializeSession(t.Context(), "route1", filterapi.MCPBackend{Name: "test-backend"}, &mcp.InitializeParams{})
358+
res, err := proxy.initializeSession(t.Context(), "route1", filterapi.MCPBackend{Name: "test-backend"}, &mcp.InitializeParams{}, time.Now())
358359

359360
require.NoError(t, err)
360361
require.Equal(t, gatewayToMCPServerSessionID("test-session-123"), res.sessionID)
@@ -372,7 +373,7 @@ func TestInitializeSession_InitializeFailure(t *testing.T) {
372373
proxy := newTestMCPProxy()
373374
proxy.backendListenerAddr = backendServer.URL
374375

375-
sessionID, err := proxy.initializeSession(t.Context(), "route1", filterapi.MCPBackend{Name: "test-backend"}, &mcp.InitializeParams{})
376+
sessionID, err := proxy.initializeSession(t.Context(), "route1", filterapi.MCPBackend{Name: "test-backend"}, &mcp.InitializeParams{}, time.Now())
376377

377378
require.Error(t, err)
378379
require.Empty(t, sessionID)
@@ -400,7 +401,7 @@ func TestInitializeSession_NotificationsInitializedFailure(t *testing.T) {
400401
proxy := newTestMCPProxy()
401402
proxy.backendListenerAddr = backendServer.URL
402403

403-
sessionID, err := proxy.initializeSession(t.Context(), "route1", filterapi.MCPBackend{Name: "test-backend"}, &mcp.InitializeParams{})
404+
sessionID, err := proxy.initializeSession(t.Context(), "route1", filterapi.MCPBackend{Name: "test-backend"}, &mcp.InitializeParams{}, time.Now())
404405

405406
require.Error(t, err)
406407
require.Empty(t, sessionID)

0 commit comments

Comments
 (0)