Skip to main content
Glama
query_component_candidates.py10.1 kB
""" 查詢組件候選工具 這個腳本可以查詢指定名稱的所有組件候選,並顯示詳細信息: - 組件名稱和 GUID - 所屬類別和子類別 - 所屬庫/插件名稱 - 是否廢棄 - 是否內置組件 - 描述 - 輸入輸出參數 """ import socket import json import sys from typing import Dict, Any, Optional def send_to_grasshopper(command_type: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: """向 Grasshopper MCP 發送命令""" if params is None: params = {} command = { "type": command_type, "parameters": params } try: client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(("localhost", 8080)) client.sendall((json.dumps(command) + "\n").encode("utf-8")) response_data = b"" while True: chunk = client.recv(4096) if not chunk: break response_data += chunk if response_data.endswith(b"\n"): break response = json.loads(response_data.decode("utf-8-sig").strip()) client.close() return response except Exception as e: return { "success": False, "error": f"與 Grasshopper 通信時出錯: {str(e)}" } def query_component_candidates(component_name: str): """ 查詢組件候選 參數: component_name: 要查詢的組件名稱(如 "Rectangle", "Number Slider") 返回: 包含所有候選組件信息的字典 """ print("=" * 80) print(f"查詢組件候選: '{component_name}'") print("=" * 80) result = send_to_grasshopper("get_component_candidates", { "name": component_name }) if result.get("success"): response_data = result.get("data") or result.get("result", {}) query = response_data.get("query", component_name) normalized_query = response_data.get("normalizedQuery", component_name) count = response_data.get("count", 0) candidates = response_data.get("candidates", []) print(f"\n查詢: '{query}'") print(f"標準化查詢: '{normalized_query}'") print(f"找到 {count} 個候選組件\n") if count == 0: print("未找到匹配的組件。") print("\n提示:") print("- 檢查組件名稱是否正確") print("- 嘗試使用部分名稱搜索") return None # 顯示每個候選組件的詳細信息 for i, candidate in enumerate(candidates, 1): print("=" * 80) print(f"候選 {i}/{count}: {candidate.get('name', 'N/A')}") print("=" * 80) # 基本信息 print(f" 名稱: {candidate.get('name', 'N/A')}") print(f" 完整名稱: {candidate.get('fullName', 'N/A')}") print(f" 類型名稱: {candidate.get('typeName', 'N/A')}") print(f" GUID: {candidate.get('guid', 'N/A')}") # 類別信息 print("\n 類別信息:") print(f" 類別: {candidate.get('category', 'N/A')}") print(f" 子類別: {candidate.get('subCategory', 'N/A')}") # 庫/插件信息 print("\n 庫/插件信息:") library = candidate.get('library', 'N/A') is_built_in = candidate.get('isBuiltIn', False) print(f" 庫名稱: {library}") if is_built_in: print(" ✓ 內置組件 (Built-in Grasshopper component)") else: print(" - 第三方插件組件") # 狀態信息 print("\n 狀態信息:") is_obsolete = candidate.get('obsolete', False) if is_obsolete: print(" ⚠️ 廢棄組件 (Obsolete/Deprecated)") print(" ⚠️ 不推薦使用") else: print(" ✓ 正常組件 (Not Obsolete)") print(" ✓ 推薦使用") # 描述 description = candidate.get('description', 'N/A') print("\n 描述:") if description and description != "No description available": # 如果描述太長,換行顯示 desc_lines = description.split('\n') for line in desc_lines[:5]: # 最多顯示5行 print(f" {line}") if len(desc_lines) > 5: print(f" ... (還有 {len(desc_lines) - 5} 行)") else: print(f" {description}") # 輸入參數 inputs = candidate.get('inputs', []) if inputs and len(inputs) > 0: print(f"\n 輸入參數 ({len(inputs)} 個):") for inp in inputs: if isinstance(inp, dict): inp_name = inp.get('name', 'N/A') inp_nickname = inp.get('nickname', '') inp_type = inp.get('type', 'N/A') inp_desc = inp.get('description', '') nickname_str = f" ({inp_nickname})" if inp_nickname else "" desc_str = f" - {inp_desc}" if inp_desc else "" print(f" - {inp_name}{nickname_str} [{inp_type}]{desc_str}") else: print(f" - {inp}") else: print("\n 輸入參數: 無") # 輸出參數 outputs = candidate.get('outputs', []) if outputs and len(outputs) > 0: print(f"\n 輸出參數 ({len(outputs)} 個):") for out in outputs: if isinstance(out, dict): out_name = out.get('name', 'N/A') out_nickname = out.get('nickname', '') out_type = out.get('type', 'N/A') out_desc = out.get('description', '') nickname_str = f" ({out_nickname})" if out_nickname else "" desc_str = f" - {out_desc}" if out_desc else "" print(f" - {out_name}{nickname_str} [{out_type}]{desc_str}") else: print(f" - {out}") else: print("\n 輸出參數: 無") print() # 總結和建議 print("=" * 80) print("總結和建議") print("=" * 80) # 統計 non_obsolete = [c for c in candidates if not c.get('obsolete', False)] built_in = [c for c in candidates if c.get('isBuiltIn', False)] recommended = [c for c in candidates if not c.get('obsolete', False) and c.get('isBuiltIn', False)] print("\n統計:") print(f" 總候選數: {count}") print(f" 非廢棄組件: {len(non_obsolete)}") print(f" 內置組件: {len(built_in)}") print(f" 推薦組件 (非廢棄 + 內置): {len(recommended)}") if len(recommended) > 0: print("\n✓ 推薦使用的組件:") for i, rec in enumerate(recommended, 1): print(f" {i}. {rec.get('name', 'N/A')} (GUID: {rec.get('guid', 'N/A')})") elif len(non_obsolete) > 0: print("\n✓ 可用的非廢棄組件:") for i, rec in enumerate(non_obsolete, 1): print(f" {i}. {rec.get('name', 'N/A')} (GUID: {rec.get('guid', 'N/A')})") else: print("\n⚠️ 警告: 所有候選組件都是廢棄的!") print(" 雖然可以繼續使用,但建議查找替代方案。") print("\n使用建議:") print(" 1. 優先使用非廢棄的內置組件") print(" 2. 如果只有一個候選,可以直接使用組件名稱創建") print(" 3. 如果有多個候選,使用 GUID 來精確指定:") print(" send_to_grasshopper('add_component', {") print(f" 'type': '{component_name}',") print(" 'x': 100,") print(" 'y': 100,") print(" 'guid': 'your-guid-here'") print(" })") return { "query": query, "normalizedQuery": normalized_query, "count": count, "candidates": candidates, "recommended": recommended, "nonObsolete": non_obsolete } else: error = result.get('error', '未知錯誤') print(f"\n✗ 查詢失敗: {error}") return None def main(): """主函數""" if len(sys.argv) > 1: component_name = sys.argv[1] else: # 如果沒有提供參數,使用默認值或提示用戶 print("組件候選查詢工具") print("=" * 80) print("\n使用方法:") print(" python query_component_candidates.py <組件名稱>") print("\n示例:") print(" python query_component_candidates.py Rectangle") print(" python query_component_candidates.py \"Number Slider\"") print(" python query_component_candidates.py Circle") print("\n" + "=" * 80) # 交互式輸入 component_name = input("\n請輸入要查詢的組件名稱 (或按 Enter 使用 'Rectangle'): ").strip() if not component_name: component_name = "Rectangle" try: result = query_component_candidates(component_name) if result: print("\n" + "=" * 80) print("查詢完成!") print("=" * 80) except KeyboardInterrupt: print("\n\n程式被使用者中斷") sys.exit(0) except Exception as e: print(f"\n發生錯誤: {str(e)}") import traceback traceback.print_exc() sys.exit(1) if __name__ == "__main__": main()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AmemiyaLai/grasshopper-mcp-workflow'

If you have feedback or need assistance with the MCP directory API, please join our Discord server