Skip to content

Commit 99b9a17

Browse files
Merge pull request #25 from NavidZ/llm-context-with-templates
fix(mcp): resolve workspace_list_data_collections timeout + skill refinements
2 parents 85b9571 + fa77c0f commit 99b9a17

1 file changed

Lines changed: 37 additions & 48 deletions

File tree

features/src/wb-mcp-server/main.go

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2726,54 +2726,40 @@ func handleCallTool(params CallToolParams) CallToolResult {
27262726
resourcesList = []interface{}{}
27272727
}
27282728

2729-
// Extract sourceWorkspaceIds from resourceLineage (which is an ARRAY inside metadata)
2730-
sourceWorkspaceIds := make(map[string]bool)
2731-
for _, r := range resourcesList {
2732-
resource, ok := r.(map[string]interface{})
2733-
if !ok {
2734-
continue
2735-
}
2736-
metadata, ok := resource["metadata"].(map[string]interface{})
2737-
if !ok {
2738-
continue
2739-
}
2740-
// resourceLineage is an array inside metadata
2741-
if lineageArray, ok := metadata["resourceLineage"].([]interface{}); ok && len(lineageArray) > 0 {
2742-
if firstLineage, ok := lineageArray[0].(map[string]interface{}); ok {
2743-
if sourceId, ok := firstLineage["sourceWorkspaceId"].(string); ok && sourceId != "" {
2744-
sourceWorkspaceIds[sourceId] = true
2745-
}
2746-
}
2747-
}
2729+
// Build a UUID → display name map with a single batch API call.
2730+
// This avoids the N+1 sequential lookups (one per collection) that caused timeouts.
2731+
collectionNames := make(map[string]string) // uuid → display name
2732+
batchBody := map[string]interface{}{
2733+
"limit": 1000,
2734+
"offset": 0,
2735+
"properties": []map[string]string{
2736+
{"key": "terra-type", "value": "data-collection"},
2737+
},
27482738
}
2749-
2750-
// Look up each source workspace to get the data collection name
2751-
dataCollectionNames := make(map[string]string) // sourceWorkspaceId -> display name
2752-
for sourceId := range sourceWorkspaceIds {
2753-
// Use API to get workspace details
2754-
wsUrl := fmt.Sprintf("%s/api/workspaces/v1/%s", workspaceBaseURL, sourceId)
2755-
wsResp, wsErr := makeAPIRequest("GET", wsUrl, nil)
2756-
if wsErr == nil {
2757-
var wsInfo map[string]interface{}
2758-
if json.Unmarshal(wsResp, &wsInfo) == nil {
2759-
// Try to get display name, fall back to id
2760-
if displayName, ok := wsInfo["displayName"].(string); ok && displayName != "" {
2761-
dataCollectionNames[sourceId] = displayName
2762-
} else if userFacingId, ok := wsInfo["userFacingId"].(string); ok && userFacingId != "" {
2763-
dataCollectionNames[sourceId] = userFacingId
2764-
} else {
2765-
dataCollectionNames[sourceId] = sourceId
2739+
if batchResp, batchErr := makeAPIRequest("POST", workspaceBaseURL+"/api/workspaces/v2/filtered", batchBody); batchErr == nil {
2740+
var batchData map[string]interface{}
2741+
if json.Unmarshal(batchResp, &batchData) == nil {
2742+
if wsList, ok := batchData["workspaces"].([]interface{}); ok {
2743+
for _, w := range wsList {
2744+
ws, ok := w.(map[string]interface{})
2745+
if !ok {
2746+
continue
2747+
}
2748+
uuid, _ := ws["id"].(string)
2749+
displayName, _ := ws["displayName"].(string)
2750+
if displayName == "" {
2751+
displayName, _ = ws["userFacingId"].(string)
2752+
}
2753+
if uuid != "" && displayName != "" {
2754+
collectionNames[uuid] = displayName
2755+
}
27662756
}
2767-
} else {
2768-
dataCollectionNames[sourceId] = sourceId
27692757
}
2770-
} else {
2771-
// If we can't access the source workspace, use the ID
2772-
dataCollectionNames[sourceId] = sourceId + " (inaccessible)"
27732758
}
27742759
}
2760+
// Fall back gracefully: if the batch call fails, groups will be keyed by UUID
27752761

2776-
// Group resources by data collection (using resourceLineage array inside metadata)
2762+
// Group resources by data collection, using display name where available
27772763
dataCollections := make(map[string]map[string]interface{})
27782764
localResources := []map[string]interface{}{}
27792765

@@ -2819,17 +2805,20 @@ func handleCallTool(params CallToolParams) CallToolResult {
28192805
}
28202806
}
28212807

2822-
// Group by data collection or mark as local
2808+
// Group by display name (falling back to UUID if name not resolved)
28232809
if sourceId != "" {
2824-
collectionName := dataCollectionNames[sourceId]
2825-
if dataCollections[collectionName] == nil {
2826-
dataCollections[collectionName] = map[string]interface{}{
2810+
groupKey := collectionNames[sourceId]
2811+
if groupKey == "" {
2812+
groupKey = sourceId
2813+
}
2814+
if dataCollections[groupKey] == nil {
2815+
dataCollections[groupKey] = map[string]interface{}{
28272816
"sourceWorkspaceId": sourceId,
28282817
"resources": []map[string]interface{}{},
28292818
}
28302819
}
2831-
resList := dataCollections[collectionName]["resources"].([]map[string]interface{})
2832-
dataCollections[collectionName]["resources"] = append(resList, resourceInfo)
2820+
resList := dataCollections[groupKey]["resources"].([]map[string]interface{})
2821+
dataCollections[groupKey]["resources"] = append(resList, resourceInfo)
28332822
} else {
28342823
localResources = append(localResources, resourceInfo)
28352824
}

0 commit comments

Comments
 (0)