@@ -10,6 +10,34 @@ import (
1010 "github.com/zerodha/kite-mcp-server/kc"
1111)
1212
13+ // Context key for session type
14+ type contextKey string
15+
16+ const (
17+ sessionTypeKey contextKey = "session_type"
18+ )
19+
20+ // Session type constants
21+ const (
22+ SessionTypeSSE = "sse"
23+ SessionTypeMCP = "mcp"
24+ SessionTypeStdio = "stdio"
25+ SessionTypeUnknown = "unknown"
26+ )
27+
28+ // WithSessionType adds session type to context
29+ func WithSessionType (ctx context.Context , sessionType string ) context.Context {
30+ return context .WithValue (ctx , sessionTypeKey , sessionType )
31+ }
32+
33+ // SessionTypeFromContext extracts session type from context
34+ func SessionTypeFromContext (ctx context.Context ) string {
35+ if sessionType , ok := ctx .Value (sessionTypeKey ).(string ); ok {
36+ return sessionType
37+ }
38+ return SessionTypeUnknown // default fallback for undetermined sessions
39+ }
40+
1341// ToolHandler provides common functionality for all MCP tools
1442type ToolHandler struct {
1543 manager * kc.Manager
@@ -20,17 +48,21 @@ func NewToolHandler(manager *kc.Manager) *ToolHandler {
2048 return & ToolHandler {manager : manager }
2149}
2250
23- // trackToolCall increments the daily tool usage counter
24- func (h * ToolHandler ) trackToolCall (toolName string ) {
51+ // trackToolCall increments the daily tool usage counter with optional context for session type
52+ func (h * ToolHandler ) trackToolCall (ctx context. Context , toolName string ) {
2553 if h .manager .HasMetrics () {
26- h .manager .IncrementDailyMetric (fmt .Sprintf ("tool_calls_%s" , toolName ))
54+ sessionType := SessionTypeFromContext (ctx )
55+ metricName := fmt .Sprintf ("tool_calls_%s_%s" , toolName , sessionType )
56+ h .manager .IncrementDailyMetric (metricName )
2757 }
2858}
2959
30- // trackToolError increments the daily tool error counter with error type
31- func (h * ToolHandler ) trackToolError (toolName , errorType string ) {
60+ // trackToolError increments the daily tool error counter with error type and optional context for session type
61+ func (h * ToolHandler ) trackToolError (ctx context. Context , toolName , errorType string ) {
3262 if h .manager .HasMetrics () {
33- h .manager .IncrementDailyMetric (fmt .Sprintf ("tool_errors_%s_%s" , toolName , errorType ))
63+ sessionType := SessionTypeFromContext (ctx )
64+ metricName := fmt .Sprintf ("tool_errors_%s_%s_%s" , toolName , errorType , sessionType )
65+ h .manager .IncrementDailyMetric (metricName )
3466 }
3567}
3668
@@ -45,13 +77,13 @@ func (h *ToolHandler) WithSession(ctx context.Context, toolName string, fn func(
4577 kiteSession , isNew , err := h .manager .GetOrCreateSession (sessionID )
4678 if err != nil {
4779 h .manager .Logger .Error ("Failed to establish session" , "tool" , toolName , "session_id" , sessionID , "error" , err )
48- h .trackToolError (toolName , "session_error" )
80+ h .trackToolError (ctx , toolName , "session_error" )
4981 return mcp .NewToolResultError ("Failed to establish a session. Please try again." ), nil
5082 }
5183
5284 if isNew {
5385 h .manager .Logger .Info ("New session created, login required" , "tool" , toolName , "session_id" , sessionID )
54- h .trackToolError (toolName , "auth_required" )
86+ h .trackToolError (ctx , toolName , "auth_required" )
5587 return mcp .NewToolResultError ("Please log in first using the login tool" ), nil
5688 }
5789
@@ -300,12 +332,12 @@ func SimpleToolHandler(manager *kc.Manager, toolName string, apiCall func(*kc.Ki
300332 handler := NewToolHandler (manager )
301333 return func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
302334 // Track the tool call at the handler level
303- handler .trackToolCall (toolName )
335+ handler .trackToolCall (ctx , toolName )
304336 result , err := handler .HandleAPICall (ctx , toolName , apiCall )
305337 if err != nil {
306- handler .trackToolError (toolName , "execution_error" )
338+ handler .trackToolError (ctx , toolName , "execution_error" )
307339 } else if result != nil && result .IsError {
308- handler .trackToolError (toolName , "api_error" )
340+ handler .trackToolError (ctx , toolName , "api_error" )
309341 }
310342 return result , err
311343 }
@@ -316,13 +348,13 @@ func PaginatedToolHandler[T any](manager *kc.Manager, toolName string, apiCall f
316348 handler := NewToolHandler (manager )
317349 return func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
318350 // Track the tool call at the handler level
319- handler .trackToolCall (toolName )
351+ handler .trackToolCall (ctx , toolName )
320352 result , err := handler .WithSession (ctx , toolName , func (session * kc.KiteSessionData ) (* mcp.CallToolResult , error ) {
321353 // Get the data
322354 data , err := apiCall (session )
323355 if err != nil {
324356 handler .manager .Logger .Error ("API call failed" , "tool" , toolName , "error" , err )
325- handler .trackToolError (toolName , "api_error" )
357+ handler .trackToolError (ctx , toolName , "api_error" )
326358 return mcp .NewToolResultError (fmt .Sprintf ("Failed to execute %s" , toolName )), nil
327359 }
328360
@@ -346,9 +378,9 @@ func PaginatedToolHandler[T any](manager *kc.Manager, toolName string, apiCall f
346378 })
347379
348380 if err != nil {
349- handler .trackToolError (toolName , "execution_error" )
381+ handler .trackToolError (ctx , toolName , "execution_error" )
350382 } else if result != nil && result .IsError {
351- handler .trackToolError (toolName , "api_error" )
383+ handler .trackToolError (ctx , toolName , "api_error" )
352384 }
353385 return result , err
354386 }
0 commit comments