Skip to content
Merged
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
14 changes: 14 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,20 @@ The animated logo creates a face-like character:
- Assume developer audience
- Keep it concise but complete

### Pull Request Guidelines

**PR Titles**: Use clear, descriptive titles focused on the change impact, not just restating commit messages. Examples:
- ❌ "feat: add message endpoint support for SSE MCP servers"
- ✅ "Add SSE message endpoint support"
- ❌ "fix: implement session-specific tool registration for stdio clients"
- ✅ "Fix stdio session tool handler conflicts"

**PR Descriptions**: Write terse prose for humans, not documentation. Avoid bullet lists unless they add genuine value. Focus on the problem solved and solution approach:
- Explain what was broken and how it's fixed
- Use conversational, developer-to-developer tone
- Skip implementation details unless critical for review
- Keep it concise but informative

### Common Issues

1. **Theme switching breaks**: Check CSS variable inheritance
Expand Down
59 changes: 55 additions & 4 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,22 @@ func (c *Client) AddToMCPServerWithTokenCheck(
serverName string,
setupBaseURL string,
tokenSetup *config.TokenSetupConfig,
) error {
return c.AddToMCPServerWithSession(ctx, clientInfo, mcpServer, userEmail, requiresToken, tokenStore, serverName, setupBaseURL, tokenSetup, nil)
}

// AddToMCPServerWithSession connects the client to an MCP server with optional session-specific tools
func (c *Client) AddToMCPServerWithSession(
ctx context.Context,
clientInfo mcp.Implementation,
mcpServer *server.MCPServer,
userEmail string,
requiresToken bool,
tokenStore storage.UserTokenStore,
serverName string,
setupBaseURL string,
tokenSetup *config.TokenSetupConfig,
session server.ClientSession,
) error {
if c.needManualStart {
err := c.client.Start(ctx)
Expand All @@ -176,7 +192,7 @@ func (c *Client) AddToMCPServerWithTokenCheck(
"server": c.name,
})

err = c.addToolsToServer(ctx, mcpServer, userEmail, requiresToken, tokenStore, serverName, setupBaseURL, tokenSetup)
err = c.addToolsToServer(ctx, mcpServer, userEmail, requiresToken, tokenStore, serverName, setupBaseURL, tokenSetup, session)
if err != nil {
return err
}
Expand Down Expand Up @@ -224,6 +240,7 @@ func (c *Client) addToolsToServer(
serverName string,
setupBaseURL string,
tokenSetup *config.TokenSetupConfig,
session server.ClientSession,
) error {
toolsRequest := mcp.ListToolsRequest{}
filterFunc := func(toolName string) bool {
Expand Down Expand Up @@ -263,6 +280,22 @@ func (c *Client) addToolsToServer(
})

totalTools := 0

var sessionWithTools server.SessionWithTools
var sessionTools map[string]server.ServerTool
if session != nil {
var ok bool
sessionWithTools, ok = session.(server.SessionWithTools)
if !ok {
return fmt.Errorf("session does not support session-specific tools")
}
sessionTools = make(map[string]server.ServerTool)
internal.LogInfoWithFields("client", "Using session-specific tool registration", map[string]interface{}{
"server": c.name,
"sessionID": session.SessionID(),
})
}

for {
tools, err := c.client.ListTools(ctx, toolsRequest)
if err != nil {
Expand All @@ -286,8 +319,9 @@ func (c *Client) addToolsToServer(
"description": tool.Description,
})
// Wrap the tool handler to check for user tokens if required
var handler server.ToolHandlerFunc
if requiresToken && tokenStore != nil {
wrappedHandler := c.wrapToolHandler(
handler = c.wrapToolHandler(
c.client.CallTool,
requiresToken,
tokenStore,
Expand All @@ -296,9 +330,17 @@ func (c *Client) addToolsToServer(
setupBaseURL,
tokenSetup,
)
mcpServer.AddTool(tool, wrappedHandler)
} else {
mcpServer.AddTool(tool, c.client.CallTool)
handler = c.client.CallTool
}

if sessionTools != nil {
sessionTools[tool.Name] = server.ServerTool{
Tool: tool,
Handler: handler,
}
} else {
mcpServer.AddTool(tool, handler)
}
}
}
Expand All @@ -308,6 +350,15 @@ func (c *Client) addToolsToServer(
toolsRequest.Params.Cursor = tools.NextCursor
}

if len(sessionTools) > 0 {
sessionWithTools.SetSessionTools(sessionTools)
internal.LogInfoWithFields("client", "Registered session-specific tools", map[string]interface{}{
"server": c.name,
"sessionID": session.SessionID(),
"toolCount": len(sessionTools),
})
}

internal.LogInfoWithFields("client", "Tool discovery completed", map[string]interface{}{
"server": c.name,
"totalTools": totalTools,
Expand Down
Loading
Loading