{"id":"9c1cf338-e83f-4d7b-b949-9f18b3032e99","entityType":"agent","slug":"clawhub-534422530-laosi-api-tester","name":"API Tester Pro","canonicalUrl":"https://www.xpersona.co/agent/clawhub-534422530-laosi-api-tester","canonicalPath":"/agent/clawhub-534422530-laosi-api-tester","generatedAt":"2026-10-11T16:02:59.878Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T13:07:26.630Z","emptyReason":null},"description":"API测试 - 构建/发送HTTP请求，验证响应状态码/�?体，性能基准(延迟/吞吐�?，支持REST和GraphQL Skill: API Tester Pro Owner: 534422530 Summary: API测试 - 构建/发送HTTP请求，验证响应状态码/�?体，性能基准(延迟/吞吐�?，支持REST和GraphQL Tags: api:2.0.0, development:1.0.0, http:2.0.0, latest:2.0.0, pro:2.0.0, rest:2.0.0, testing:2.0.0 Version history: v2.0.0 | 2026-05-29T23:31:22.710Z | auto Version 2.0.0 - Added hub.json to support skill hub integration. - Updated SKILL.md: new \"badge: premium\" field and minor edits. - Incremented version to 2","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.1K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s170k9770tgh0506hw0dwtb6pd83kwyq:laosi-api-tester","sourceUrl":"https://clawhub.ai/534422530/laosi-api-tester","homepage":"https://clawhub.ai/534422530/skills/laosi-api-tester","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/534422530/laosi-api-tester","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/534422530/skills/laosi-api-tester","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":61,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"API测试 - 构建/发送HTTP请求，验证响应状态码/�?体，性能基准(延迟/吞吐�?，支持REST和GraphQL Skill: API Tester Pro Owner: 534422530 Summary: API测试 - 构建/发送HTTP请求，验证响应状态码/�?体，性能基准(延迟/吞吐�?，支持REST和"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T13:07:26.630Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T13:07:26.630Z","emptyReason":null},"stars":null,"forks":null,"downloads":1060,"packageName":null,"latestVersion":"2.0.0","tractionLabel":"1.1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T13:07:26.570Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T13:07:26.630Z","lastCrawledAt":"2026-10-11T13:07:26.570Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T13:07:26.570Z","lastVerifiedAt":null,"highlights":[{"version":"2.0.0","createdAt":"2026-05-29T23:31:22.710Z","changelog":"Version 2.0.0 - Added hub.json to support skill hub integration. - Updated SKILL.md: new \"badge: premium\" field and minor edits. - Incremented version to 2.0.0. - No functional API or code changes detected.","fileCount":4,"zipByteSize":5058},{"version":"1.0.0","createdAt":"2026-05-29T00:47:26.569Z","changelog":"laosi-api-tester 1.0.0 - Initial release of API Tester, a tool for sending and validating HTTP requests. - Supports GET/POST/PUT/DELETE requests and GraphQL queries. - Allows custom request headers, body, and content types. - Provides response validation (status, headers, body, latency), performance benchmarking, and result history persistence. - Suitable for CI/CD, API documentation, performance regression, and integration testing.","fileCount":3,"zipByteSize":4683}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s170k9770tgh0506hw0dwtb6pd83kwyq:laosi-api-tester","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-534422530-laosi-api-tester/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-534422530-laosi-api-tester/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-534422530-laosi-api-tester/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-534422530-laosi-api-tester/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-534422530-laosi-api-tester/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-534422530-laosi-api-tester/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T16:02:59.878Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-534422530-laosi-api-tester/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-534422530-laosi-api-tester/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-534422530-laosi-api-tester/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-534422530-laosi-api-tester/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T13:07:26.630Z","emptyReason":null},"readme":"Skill: API Tester Pro\n\nOwner: 534422530\n\nSummary: API测试 - 构建/发送HTTP请求，验证响应状态码/�?体，性能基准(延迟/吞吐�?，支持REST和GraphQL\n\nTags: api:2.0.0, development:1.0.0, http:2.0.0, latest:2.0.0, pro:2.0.0, rest:2.0.0, testing:2.0.0\n\nVersion history:\n\nv2.0.0 | 2026-05-29T23:31:22.710Z | auto\n\nVersion 2.0.0\n\n- Added hub.json to support skill hub integration.\n- Updated SKILL.md: new \"badge: premium\" field and minor edits.\n- Incremented version to 2.0.0.\n- No functional API or code changes detected.\n\nv1.0.0 | 2026-05-29T00:47:26.569Z | auto\n\nlaosi-api-tester 1.0.0\n\n- Initial release of API Tester, a tool for sending and validating HTTP requests.\n- Supports GET/POST/PUT/DELETE requests and GraphQL queries.\n- Allows custom request headers, body, and content types.\n- Provides response validation (status, headers, body, latency), performance benchmarking, and result history persistence.\n- Suitable for CI/CD, API documentation, performance regression, and integration testing.\n\nArchive index:\n\nArchive v2.0.0: 4 files, 5058 bytes\n\nFiles: hub.json (567b), skill-card.md (2122b), SKILL.md (8335b), _meta.json (135b)\n\nFile v2.0.0:SKILL.md\n\n---\nbadge: premium\nname: api-tester\nversion: 2.0.0\ndescription: API测试 - 构建/发送HTTP请求，验证响应状态码/�?体，性能基准(延迟/吞吐�?，支持REST和GraphQL\ntags: [api, testing, http, rest, graphql, development]\nauthor: laosi\nsource: original\n---\n\n# API Tester - API接口测试\n\n> 激活词: 测试API / api test / 接口测试\n\n## 功能\n\n- 发�?GET/POST/PUT/DELETE 请求\n- 自定义请求头、Body (JSON/Form/Text)\n- 响应状态码、头、体验证\n- GraphQL 查询支持\n- 延迟测量和性能基准\n- 测试结果持久�?\n## Python 实现\n\n```python\nimport json, time, urllib.request, urllib.error\nfrom datetime import datetime\nfrom typing import Dict, Any, Optional, List\nfrom dataclasses import dataclass, field, asdict\n\n@dataclass\nclass APIRequest:\n    method: str = \"GET\"\n    url: str = \"\"\n    headers: Dict[str, str] = field(default_factory=dict)\n    body: Optional[str] = None\n    content_type: str = \"application/json\"\n    timeout: int = 10\n    \n    def to_urllib_request(self) -> urllib.request.Request:\n        \"\"\"转换为urllib请求对象\"\"\"\n        data = None\n        if self.body and self.method in (\"POST\", \"PUT\", \"PATCH\"):\n            data = self.body.encode(\"utf-8\") if isinstance(self.body, str) else self.body\n            if \"Content-Type\" not in self.headers:\n                self.headers[\"Content-Type\"] = self.content_type\n        \n        req = urllib.request.Request(\n            self.url,\n            data=data,\n            headers=self.headers,\n            method=self.method\n        )\n        return req\n\n@dataclass\nclass APIResponse:\n    status: int = 0\n    headers: Dict[str, str] = field(default_factory=dict)\n    body: str = \"\"\n    body_json: Optional[Dict] = None\n    latency_ms: float = 0.0\n    error: Optional[str] = None\n\nclass APITester:\n    def __init__(self):\n        self.history: List[Dict] = []\n        self.history_file = os.path.join(\n            os.path.dirname(__file__), \"api_tests.json\"\n        )\n        os.makedirs(os.path.dirname(self.history_file), exist_ok=True)\n    \n    def send(self, request: APIRequest) -> APIResponse:\n        \"\"\"发送单个API请求\"\"\"\n        resp = APIResponse()\n        start = time.time()\n        \n        try:\n            req = request.to_urllib_request()\n            with urllib.request.urlopen(req, timeout=request.timeout) as conn:\n                resp.status = conn.status\n                resp.headers = dict(conn.headers)\n                resp.body = conn.read().decode(\"utf-8\", errors=\"replace\")\n                try:\n                    resp.body_json = json.loads(resp.body)\n                except json.JSONDecodeError:\n                    pass\n        except urllib.error.HTTPError as e:\n            resp.status = e.code\n            resp.headers = dict(e.headers)\n            resp.body = e.read().decode(\"utf-8\", errors=\"replace\")\n            resp.error = f\"HTTP {e.code}: {e.reason}\"\n        except urllib.error.URLError as e:\n            resp.error = f\"URL Error: {e.reason}\"\n        except Exception as e:\n            resp.error = str(e)\n        \n        resp.latency_ms = round((time.time() - start) * 1000, 1)\n        \n        # 保存历史\n        entry = {\n            \"method\": request.method,\n            \"url\": request.url,\n            \"status\": resp.status,\n            \"latency_ms\": resp.latency_ms,\n            \"error\": resp.error,\n            \"timestamp\": datetime.now().isoformat(),\n        }\n        self._save_history(entry)\n        \n        return resp\n    \n    def batch(self, requests: List[APIRequest], concurrency: int = 1) -> List[APIResponse]:\n        \"\"\"批量发送请�?\"\"\n        results = []\n        for req in requests:\n            results.append(self.send(req))\n        return results\n    \n    def benchmark(self, url: str, count: int = 5, method: str = \"GET\") -> dict:\n        \"\"\"性能基准测试\"\"\"\n        latencies = []\n        errors = 0\n        for i in range(count):\n            req = APIRequest(method=method, url=url)\n            resp = self.send(req)\n            if resp.error:\n                errors += 1\n            else:\n                latencies.append(resp.latency_ms)\n        \n        return {\n            \"url\": url,\n            \"requests\": count,\n            \"errors\": errors,\n            \"latency\": {\n                \"min\": min(latencies) if latencies else None,\n                \"max\": max(latencies) if latencies else None,\n                \"avg\": round(sum(latencies) / len(latencies), 1) if latencies else None,\n                \"p50\": sorted(latencies)[len(latencies)//2] if latencies else None,\n                \"p99\": sorted(latencies)[int(len(latencies)*0.99)] if len(latencies) > 1 else None,\n            },\n            \"timestamp\": datetime.now().isoformat()\n        }\n    \n    def graphql(self, endpoint: str, query: str, variables: dict = None) -> APIResponse:\n        \"\"\"发送GraphQL查询\"\"\"\n        body = json.dumps({\"query\": query, \"variables\": variables or {}})\n        req = APIRequest(\n            method=\"POST\",\n            url=endpoint,\n            body=body,\n            content_type=\"application/json\"\n        )\n        return self.send(req)\n    \n    def validate(self, resp: APIResponse, rules: Dict[str, Any]) -> List[str]:\n        \"\"\"验证响应是否符合规则\"\"\"\n        failures = []\n        \n        if \"status\" in rules and resp.status != rules[\"status\"]:\n            failures.append(f\"Status: expected {rules['status']}, got {resp.status}\")\n        \n        if \"header_contains\" in rules:\n            for key, val in rules[\"header_contains\"].items():\n                actual = resp.headers.get(key)\n                if actual != val:\n                    failures.append(f\"Header {key}: expected '{val}', got '{actual}'\")\n        \n        if \"body_contains\" in rules:\n            for key in rules[\"body_contains\"]:\n                if resp.body_json and key not in resp.body_json:\n                    failures.append(f\"Body missing key: '{key}'\")\n        \n        if \"latency_max\" in rules and resp.latency_ms > rules[\"latency_max\"]:\n            failures.append(f\"Latency: {resp.latency_ms}ms > max {rules['latency_max']}ms\")\n        \n        return failures\n    \n    def _save_history(self, entry: dict):\n        entries = []\n        if os.path.exists(self.history_file):\n            with open(self.history_file, encoding=\"utf-8\") as f:\n                entries = json.load(f).get(\"tests\", [])\n        entries.append(entry)\n        with open(self.history_file, \"w\", encoding=\"utf-8\") as f:\n            json.dump({\"tests\": entries}, f, ensure_ascii=False, indent=2)\n\n# 使用示例\ntester = APITester()\n\n# 简单GET请求\nreq = APIRequest(method=\"GET\", url=\"https://httpbin.org/get\")\nresp = tester.send(req)\nprint(f\"GET {req.url} -> {resp.status} ({resp.latency_ms}ms)\")\nif resp.body_json:\n    print(f\"  Origin: {resp.body_json.get('origin', 'N/A')}\")\n\n# POST JSON\nreq2 = APIRequest(\n    method=\"POST\",\n    url=\"https://httpbin.org/post\",\n    body=json.dumps({\"name\": \"test\", \"value\": 42}),\n)\nresp2 = tester.send(req2)\nprint(f\"POST -> {resp2.status} ({resp2.latency_ms}ms)\")\n\n# GraphQL查询\ngql_resp = tester.graphql(\n    \"https://api.github.com/graphql\",\n    \"{ viewer { login } }\"\n)\nprint(f\"GraphQL -> {gql_resp.status}\")\n\n# 性能基准\nbench = tester.benchmark(\"https://httpbin.org/get\", count=3)\nprint(f\"基准: avg={bench['latency']['avg']}ms, errors={bench['errors']}\")\n\n# 验证\nrules = {\"status\": 200, \"latency_max\": 3000}\nfailures = tester.validate(resp, rules)\nprint(f\"验证: {'PASS' if not failures else 'FAIL: ' + str(failures)}\")\n```\n\n## 常用验证规则\n\n```python\nVALIDATION_RULES = {\n    \"health_check\": {\"status\": 200, \"latency_max\": 500},\n    \"api_ok\": {\"status\": 200, \"body_contains\": [\"data\", \"status\"]},\n    \"created\": {\"status\": 201, \"header_contains\": {\"Content-Type\": \"application/json\"}},\n    \"no_content\": {\"status\": 204},\n    \"redirect\": {\"status\": 302},\n    \"unauthorized\": {\"status\": 401},\n    \"not_found\": {\"status\": 404},\n    \"server_error\": {\"status\": 500, \"latency_max\": 5000},\n}\n```\n\n## 使用场景\n\n1. **CI/CD管道**: 部署后自动测试API健康检�?2. **接口文档**: 自动生成API请求示例\n3. **性能回归**: 每次部署后基准测试，发现性能退�?4. **集成测试**: 微服务间API契约验证\n\n## 依赖\n\n- Python 3.8+\n- 标准库（urllib, json, time�?\n\nFile v2.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn71pk44ca87scz3pstt90r66n80xhaa\",\n  \"slug\": \"laosi-api-tester\",\n  \"version\": \"2.0.0\",\n  \"publishedAt\": 1780097482710\n}\n\nFile v2.0.0:skill-card.md\n\n## Description:\n\nAPI Tester Pro helps agents construct and send HTTP, REST, and GraphQL requests, validate status codes, headers, response bodies, and latency, and summarize benchmark results.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[534422530](https://clawhub.ai/user/534422530)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineers use this skill to exercise APIs after deployment, generate request examples, check service health, validate API contracts, and compare basic latency measurements.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can send user-directed HTTP requests from the agent environment to arbitrary URLs, including sensitive internal or cloud-metadata addresses.\n\nMitigation: Use it only with trusted endpoints and apply host or network controls that block internal, loopback, link-local, and cloud-metadata ranges when appropriate.\n\nRisk: The implementation saves tested URLs and request history to api_tests.json, which may expose sensitive endpoints or query parameters.\n\nMitigation: Avoid placing secrets in URLs, prefer protected headers for credentials, and remove or protect api_tests.json after testing sensitive systems.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/534422530/skills/laosi-api-tester)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown with Python code blocks, request examples, validation rules, and structured result summaries]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [The bundled implementation may create api_tests.json containing tested URLs, status values, latency, errors, and timestamps.]\n\n## Skill Version(s):\n\n2.0.0 (source: server release metadata and skill frontmatter)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v2.0.0:hub.json\n\n{\r\n    \"description\":  \"Premium version with full implementation, examples, and enterprise support\",\r\n    \"minOpenClawVersion\":  \"1.2.0\",\r\n    \"version\":  \"2.0.0\",\r\n    \"tags\":  [\r\n                 \"api\",\r\n                 \"testing\",\r\n                 \"http\",\r\n                 \"rest\",\r\n                 \"pro\"\r\n             ],\r\n    \"author\":  \"laosi\",\r\n    \"name\":  \"api-tester\",\r\n    \"pricing\":  {\r\n                    \"price\":  1900,\r\n                    \"model\":  \"one-time\"\r\n                },\r\n    \"license\":  \"MIT\",\r\n    \"displayName\":  \"API Tester Pro\"\r\n}\n\nArchive v1.0.0: 3 files, 4683 bytes\n\nFiles: skill-card.md (2312b), SKILL.md (8328b), _meta.json (135b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: api-tester\nversion: 1.0.0\ndescription: API测试 - 构建/发送HTTP请求，验证响应状态码/头/体，性能基准(延迟/吞吐量)，支持REST和GraphQL\ntags: [api, testing, http, rest, graphql, development]\nauthor: laosi\nsource: original\n---\n\n# API Tester - API接口测试\n\n> 激活词: 测试API / api test / 接口测试\n\n## 功能\n\n- 发送 GET/POST/PUT/DELETE 请求\n- 自定义请求头、Body (JSON/Form/Text)\n- 响应状态码、头、体验证\n- GraphQL 查询支持\n- 延迟测量和性能基准\n- 测试结果持久化\n\n## Python 实现\n\n```python\nimport json, time, urllib.request, urllib.error\nfrom datetime import datetime\nfrom typing import Dict, Any, Optional, List\nfrom dataclasses import dataclass, field, asdict\n\n@dataclass\nclass APIRequest:\n    method: str = \"GET\"\n    url: str = \"\"\n    headers: Dict[str, str] = field(default_factory=dict)\n    body: Optional[str] = None\n    content_type: str = \"application/json\"\n    timeout: int = 10\n    \n    def to_urllib_request(self) -> urllib.request.Request:\n        \"\"\"转换为urllib请求对象\"\"\"\n        data = None\n        if self.body and self.method in (\"POST\", \"PUT\", \"PATCH\"):\n            data = self.body.encode(\"utf-8\") if isinstance(self.body, str) else self.body\n            if \"Content-Type\" not in self.headers:\n                self.headers[\"Content-Type\"] = self.content_type\n        \n        req = urllib.request.Request(\n            self.url,\n            data=data,\n            headers=self.headers,\n            method=self.method\n        )\n        return req\n\n@dataclass\nclass APIResponse:\n    status: int = 0\n    headers: Dict[str, str] = field(default_factory=dict)\n    body: str = \"\"\n    body_json: Optional[Dict] = None\n    latency_ms: float = 0.0\n    error: Optional[str] = None\n\nclass APITester:\n    def __init__(self):\n        self.history: List[Dict] = []\n        self.history_file = os.path.join(\n            os.path.dirname(__file__), \"api_tests.json\"\n        )\n        os.makedirs(os.path.dirname(self.history_file), exist_ok=True)\n    \n    def send(self, request: APIRequest) -> APIResponse:\n        \"\"\"发送单个API请求\"\"\"\n        resp = APIResponse()\n        start = time.time()\n        \n        try:\n            req = request.to_urllib_request()\n            with urllib.request.urlopen(req, timeout=request.timeout) as conn:\n                resp.status = conn.status\n                resp.headers = dict(conn.headers)\n                resp.body = conn.read().decode(\"utf-8\", errors=\"replace\")\n                try:\n                    resp.body_json = json.loads(resp.body)\n                except json.JSONDecodeError:\n                    pass\n        except urllib.error.HTTPError as e:\n            resp.status = e.code\n            resp.headers = dict(e.headers)\n            resp.body = e.read().decode(\"utf-8\", errors=\"replace\")\n            resp.error = f\"HTTP {e.code}: {e.reason}\"\n        except urllib.error.URLError as e:\n            resp.error = f\"URL Error: {e.reason}\"\n        except Exception as e:\n            resp.error = str(e)\n        \n        resp.latency_ms = round((time.time() - start) * 1000, 1)\n        \n        # 保存历史\n        entry = {\n            \"method\": request.method,\n            \"url\": request.url,\n            \"status\": resp.status,\n            \"latency_ms\": resp.latency_ms,\n            \"error\": resp.error,\n            \"timestamp\": datetime.now().isoformat(),\n        }\n        self._save_history(entry)\n        \n        return resp\n    \n    def batch(self, requests: List[APIRequest], concurrency: int = 1) -> List[APIResponse]:\n        \"\"\"批量发送请求\"\"\"\n        results = []\n        for req in requests:\n            results.append(self.send(req))\n        return results\n    \n    def benchmark(self, url: str, count: int = 5, method: str = \"GET\") -> dict:\n        \"\"\"性能基准测试\"\"\"\n        latencies = []\n        errors = 0\n        for i in range(count):\n            req = APIRequest(method=method, url=url)\n            resp = self.send(req)\n            if resp.error:\n                errors += 1\n            else:\n                latencies.append(resp.latency_ms)\n        \n        return {\n            \"url\": url,\n            \"requests\": count,\n            \"errors\": errors,\n            \"latency\": {\n                \"min\": min(latencies) if latencies else None,\n                \"max\": max(latencies) if latencies else None,\n                \"avg\": round(sum(latencies) / len(latencies), 1) if latencies else None,\n                \"p50\": sorted(latencies)[len(latencies)//2] if latencies else None,\n                \"p99\": sorted(latencies)[int(len(latencies)*0.99)] if len(latencies) > 1 else None,\n            },\n            \"timestamp\": datetime.now().isoformat()\n        }\n    \n    def graphql(self, endpoint: str, query: str, variables: dict = None) -> APIResponse:\n        \"\"\"发送GraphQL查询\"\"\"\n        body = json.dumps({\"query\": query, \"variables\": variables or {}})\n        req = APIRequest(\n            method=\"POST\",\n            url=endpoint,\n            body=body,\n            content_type=\"application/json\"\n        )\n        return self.send(req)\n    \n    def validate(self, resp: APIResponse, rules: Dict[str, Any]) -> List[str]:\n        \"\"\"验证响应是否符合规则\"\"\"\n        failures = []\n        \n        if \"status\" in rules and resp.status != rules[\"status\"]:\n            failures.append(f\"Status: expected {rules['status']}, got {resp.status}\")\n        \n        if \"header_contains\" in rules:\n            for key, val in rules[\"header_contains\"].items():\n                actual = resp.headers.get(key)\n                if actual != val:\n                    failures.append(f\"Header {key}: expected '{val}', got '{actual}'\")\n        \n        if \"body_contains\" in rules:\n            for key in rules[\"body_contains\"]:\n                if resp.body_json and key not in resp.body_json:\n                    failures.append(f\"Body missing key: '{key}'\")\n        \n        if \"latency_max\" in rules and resp.latency_ms > rules[\"latency_max\"]:\n            failures.append(f\"Latency: {resp.latency_ms}ms > max {rules['latency_max']}ms\")\n        \n        return failures\n    \n    def _save_history(self, entry: dict):\n        entries = []\n        if os.path.exists(self.history_file):\n            with open(self.history_file, encoding=\"utf-8\") as f:\n                entries = json.load(f).get(\"tests\", [])\n        entries.append(entry)\n        with open(self.history_file, \"w\", encoding=\"utf-8\") as f:\n            json.dump({\"tests\": entries}, f, ensure_ascii=False, indent=2)\n\n# 使用示例\ntester = APITester()\n\n# 简单GET请求\nreq = APIRequest(method=\"GET\", url=\"https://httpbin.org/get\")\nresp = tester.send(req)\nprint(f\"GET {req.url} -> {resp.status} ({resp.latency_ms}ms)\")\nif resp.body_json:\n    print(f\"  Origin: {resp.body_json.get('origin', 'N/A')}\")\n\n# POST JSON\nreq2 = APIRequest(\n    method=\"POST\",\n    url=\"https://httpbin.org/post\",\n    body=json.dumps({\"name\": \"test\", \"value\": 42}),\n)\nresp2 = tester.send(req2)\nprint(f\"POST -> {resp2.status} ({resp2.latency_ms}ms)\")\n\n# GraphQL查询\ngql_resp = tester.graphql(\n    \"https://api.github.com/graphql\",\n    \"{ viewer { login } }\"\n)\nprint(f\"GraphQL -> {gql_resp.status}\")\n\n# 性能基准\nbench = tester.benchmark(\"https://httpbin.org/get\", count=3)\nprint(f\"基准: avg={bench['latency']['avg']}ms, errors={bench['errors']}\")\n\n# 验证\nrules = {\"status\": 200, \"latency_max\": 3000}\nfailures = tester.validate(resp, rules)\nprint(f\"验证: {'PASS' if not failures else 'FAIL: ' + str(failures)}\")\n```\n\n## 常用验证规则\n\n```python\nVALIDATION_RULES = {\n    \"health_check\": {\"status\": 200, \"latency_max\": 500},\n    \"api_ok\": {\"status\": 200, \"body_contains\": [\"data\", \"status\"]},\n    \"created\": {\"status\": 201, \"header_contains\": {\"Content-Type\": \"application/json\"}},\n    \"no_content\": {\"status\": 204},\n    \"redirect\": {\"status\": 302},\n    \"unauthorized\": {\"status\": 401},\n    \"not_found\": {\"status\": 404},\n    \"server_error\": {\"status\": 500, \"latency_max\": 5000},\n}\n```\n\n## 使用场景\n\n1. **CI/CD管道**: 部署后自动测试API健康检查\n2. **接口文档**: 自动生成API请求示例\n3. **性能回归**: 每次部署后基准测试，发现性能退化\n4. **集成测试**: 微服务间API契约验证\n\n## 依赖\n\n- Python 3.8+\n- 标准库（urllib, json, time）\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn71pk44ca87scz3pstt90r66n80xhaa\",\n  \"slug\": \"laosi-api-tester\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1780015646569\n}\n\nFile v1.0.0:skill-card.md\n\n## Description: <br>\nBuilds and sends REST or GraphQL HTTP requests, validates response status, headers, body content, and latency, and records API test history. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[534422530](https://clawhub.ai/user/534422530) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and engineers use this skill to generate API test code and guidance for health checks, integration testing, API documentation examples, and latency regression checks. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: API requests may expose tokens, personal data, or sensitive endpoint details, especially when values are included in URLs or saved history. <br>\nMitigation: Avoid placing secrets or personal data in URLs, limit tests to intended systems, and periodically delete api_tests.json when history could reveal sensitive details. <br>\nRisk: Benchmark or batch tests could unintentionally exercise internal or production systems. <br>\nMitigation: Confirm target URLs and test scope before execution, and use conservative request counts and timeouts for production-adjacent systems. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/534422530/laosi-api-tester) <br>\n- [GraphQL API endpoint referenced by the skill](https://api.github.com/graphql) <br>\n- [HTTP test endpoint referenced by the skill](https://httpbin.org/get) <br>\n- [HTTP POST test endpoint referenced by the skill](https://httpbin.org/post) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Code, Markdown, Shell commands, Configuration instructions, Guidance] <br>\n**Output Format:** [Markdown with Python code blocks and concise testing guidance] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May include request examples, validation rules, benchmark summaries, and local history file guidance.] <br>\n\n## Skill Version(s): <br>\n1.0.0 (source: frontmatter and release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>","readmeExcerpt":"Skill: API Tester Pro Owner: 534422530 Summary: API测试 - 构建/发送HTTP请求，验证响应状态码/�?体，性能基准(延迟/吞吐�?，支持REST和GraphQL Tags: api:2.0.0, development:1.0.0, http:2.0.0, latest:2.0.0, pro:2.0.0, rest:2.0.0, testing:2.0.0 Version history: v2.0.0 | 2026-05-29T23:31:22.710Z | auto Version 2.0.0 - Added hub.json to support skill hub integration. - Updated SKILL.md: new \"badge: premium\" field and minor edits. - Incremented version to 2","codeSnippets":[],"executableExamples":[{"language":"python","snippet":"import json, time, urllib.request, urllib.error\nfrom datetime import datetime\nfrom typing import Dict, Any, Optional, List\nfrom dataclasses import dataclass, field, asdict\n\n@dataclass\nclass APIRequest:\n    method: str = \"GET\"\n    url: str = \"\"\n    headers: Dict[str, str] = field(default_factory=dict)\n    body: Optional[str] = None\n    content_type: str = \"application/json\"\n    timeout: int = 10\n    \n    def to_urllib_request(self) -> urllib.request.Request:\n        \"\"\"转换为urllib请求对象\"\"\"\n        data = None\n        if self.body and self.method in (\"POST\", \"PUT\", \"PATCH\"):\n            data = self.body.encode(\"utf-8\") if isinstance(self.body, str) else self.body\n            if \"Content-Type\" not in self.headers:\n                self.headers[\"Content-Type\"] = self.content_type\n        \n        req = urllib.request.Request(\n            self.url,\n            data=data,\n            headers=self.headers,\n            method=self.method\n        )\n        return req\n\n@dataclass\nclass APIResponse:\n    status: int = 0\n    headers: Dict[str, str] = field(default_factory=dict)\n    body: str = \"\"\n    body_json: Optional[Dict] = None\n    latency_ms: float = 0.0\n    error: Optional[str] = None\n\nclass APITester:\n    def __init__(self):\n        self.history: List[Dict] = []\n        self.history_file = os.path.join(\n            os.path.dirname(__file__), \"api_tests.json\"\n        )\n        os.makedirs(os.path.dirname(self.history_file), exist_ok=True)\n    \n    def send(self, request: APIRequest) -> APIResponse:\n        \"\"\"发送单个API请求\"\"\"\n        resp = APIResponse()\n        start = time.time()\n        \n        try:\n            req = request.to_urllib_request()\n            with urllib.request.urlopen(req, timeout=request.timeout) as conn:\n                resp.status = conn.status\n                resp.headers = dict(conn.headers)\n                resp.body = conn.read().decode(\"utf-8\", errors=\"replace\")\n                try:\n                    resp.body_json = json.loads(resp.body)\n             "},{"language":"python","snippet":"VALIDATION_RULES = {\n    \"health_check\": {\"status\": 200, \"latency_max\": 500},\n    \"api_ok\": {\"status\": 200, \"body_contains\": [\"data\", \"status\"]},\n    \"created\": {\"status\": 201, \"header_contains\": {\"Content-Type\": \"application/json\"}},\n    \"no_content\": {\"status\": 204},\n    \"redirect\": {\"status\": 302},\n    \"unauthorized\": {\"status\": 401},\n    \"not_found\": {\"status\": 404},\n    \"server_error\": {\"status\": 500, \"latency_max\": 5000},\n}"},{"language":"python","snippet":"import json, time, urllib.request, urllib.error\nfrom datetime import datetime\nfrom typing import Dict, Any, Optional, List\nfrom dataclasses import dataclass, field, asdict\n\n@dataclass\nclass APIRequest:\n    method: str = \"GET\"\n    url: str = \"\"\n    headers: Dict[str, str] = field(default_factory=dict)\n    body: Optional[str] = None\n    content_type: str = \"application/json\"\n    timeout: int = 10\n    \n    def to_urllib_request(self) -> urllib.request.Request:\n        \"\"\"转换为urllib请求对象\"\"\"\n        data = None\n        if self.body and self.method in (\"POST\", \"PUT\", \"PATCH\"):\n            data = self.body.encode(\"utf-8\") if isinstance(self.body, str) else self.body\n            if \"Content-Type\" not in self.headers:\n                self.headers[\"Content-Type\"] = self.content_type\n        \n        req = urllib.request.Request(\n            self.url,\n            data=data,\n            headers=self.headers,\n            method=self.method\n        )\n        return req\n\n@dataclass\nclass APIResponse:\n    status: int = 0\n    headers: Dict[str, str] = field(default_factory=dict)\n    body: str = \"\"\n    body_json: Optional[Dict] = None\n    latency_ms: float = 0.0\n    error: Optional[str] = None\n\nclass APITester:\n    def __init__(self):\n        self.history: List[Dict] = []\n        self.history_file = os.path.join(\n            os.path.dirname(__file__), \"api_tests.json\"\n        )\n        os.makedirs(os.path.dirname(self.history_file), exist_ok=True)\n    \n    def send(self, request: APIRequest) -> APIResponse:\n        \"\"\"发送单个API请求\"\"\"\n        resp = APIResponse()\n        start = time.time()\n        \n        try:\n            req = request.to_urllib_request()\n            with urllib.request.urlopen(req, timeout=request.timeout) as conn:\n                resp.status = conn.status\n                resp.headers = dict(conn.headers)\n                resp.body = conn.read().decode(\"utf-8\", errors=\"replace\")\n                try:\n                    resp.body_json = json.loads(resp.body)\n             "},{"language":"python","snippet":"VALIDATION_RULES = {\n    \"health_check\": {\"status\": 200, \"latency_max\": 500},\n    \"api_ok\": {\"status\": 200, \"body_contains\": [\"data\", \"status\"]},\n    \"created\": {\"status\": 201, \"header_contains\": {\"Content-Type\": \"application/json\"}},\n    \"no_content\": {\"status\": 204},\n    \"redirect\": {\"status\": 302},\n    \"unauthorized\": {\"status\": 401},\n    \"not_found\": {\"status\": 404},\n    \"server_error\": {\"status\": 500, \"latency_max\": 5000},\n}"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nbadge: premium\nname: api-tester\nversion: 2.0.0\ndescription: API测试 - 构建/发送HTTP请求，验证响应状态码/�?体，性能基准(延迟/吞吐�?，支持REST和GraphQL\ntags: [api, testing, http, rest, graphql, development]\nauthor: laosi\nsource: original\n---\n\n# API Tester - API接口测试\n\n> 激活词: 测试API / api test / 接口测试\n\n## 功能\n\n- 发�?GET/POST/PUT/DELETE 请求\n- 自定义请求头、Body (JSON/Form/Text)\n- 响应状态码、头、体验证\n- GraphQL 查询支持\n- 延迟测量和性能基准\n- 测试结果持久�?\n## Python 实现\n\n```python\nimport json, time, urllib.request, urllib.error\nfrom datetime import datetime\nfrom typing import Dict, Any, Optional, List\nfrom dataclasses import dataclass, field, asdict\n\n@dataclass\nclass APIRequest:\n    method: str = \"GET\"\n    url: str = \"\"\n    headers: Dict[str, str] = field(default_factory=dict)\n    body: Optional[str] = None\n    content_type: str = \"application/json\"\n    timeout: int = 10\n    \n    def to_urllib_request(self) -> urllib.request.Request:\n        \"\"\"转换为urllib请求对象\"\"\"\n        data = None\n        if self.body and self.method in (\"POST\", \"PUT\", \"PATCH\"):\n            data = self.body.encode(\"utf-8\") if isinstance(self.body, str) else self.body\n            if \"Content-Type\" not in self.headers:\n                self.headers[\"Content-Type\"] = self.content_type\n        \n        req = urllib.request.Request(\n            self.url,\n            data=data,\n            headers=self.headers,\n            method=self.method\n        )\n        return req\n\n@dataclass\nclass APIResponse:\n    status: int = 0\n    headers: Dict[str, str] = field(default_factory=dict)\n    body: str = \"\"\n    body_json: Optional[Dict] = None\n    latency_ms: float = 0.0\n    error: Optional[str] = None\n\nclass APITester:\n    def __init__(self):\n        self.history: List[Dict] = []\n        self.history_file = os.path.join(\n            os.path.dirname(__file__), \"api_tests.json\"\n        )\n        os.makedirs(os.path.dirname(self.history_file), exist_ok=True)\n    \n    def send(self, request: APIRequest) -> APIResponse:\n        \"\"\"发送单个API请求\"\"\"\n        resp = APIResponse()\n        start = time.time()\n        \n        try:\n            req = request.to_urllib_request()\n            with urllib.request.urlopen(req, timeout=request.timeout) as conn:\n                resp.status = conn.status\n                resp.headers = dict(conn.headers)\n                resp.body = conn.read().decode(\"utf-8\", errors=\"replace\")\n                try:\n                    resp.body_json = json.loads(resp.body)\n                except json.JSONDecodeError:\n                    pass\n        except urllib.error.HTTPError as e:\n            resp.status = e.code\n            resp.headers = dict(e.headers)\n            resp.body = e.read().decode(\"utf-8\", errors=\"replace\")\n            resp.error = f\"HTTP {e.code}: {e.reason}\"\n        except urllib.error.URLError as e:\n            resp.error = f\"URL Error: {e.reason}\"\n        except Exception as e:\n            resp.error = str(e)\n        \n        resp.latency_ms = round((time.time() - start) * 1000, 1)\n        \n        # 保存历史\n        entry = {\n            \"meth"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn71pk44ca87scz3pstt90r66n80xhaa\",\n  \"slug\": \"laosi-api-tester\",\n  \"version\": \"2.0.0\",\n  \"publishedAt\": 1780097482710\n}"},{"path":"skill-card.md","content":"## Description:\n\nAPI Tester Pro helps agents construct and send HTTP, REST, and GraphQL requests, validate status codes, headers, response bodies, and latency, and summarize benchmark results.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[534422530](https://clawhub.ai/user/534422530)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineers use this skill to exercise APIs after deployment, generate request examples, check service health, validate API contracts, and compare basic latency measurements.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can send user-directed HTTP requests from the agent environment to arbitrary URLs, including sensitive internal or cloud-metadata addresses.\n\nMitigation: Use it only with trusted endpoints and apply host or network controls that block internal, loopback, link-local, and cloud-metadata ranges when appropriate.\n\nRisk: The implementation saves tested URLs and request history to api_tests.json, which may expose sensitive endpoints or query parameters.\n\nMitigation: Avoid placing secrets in URLs, prefer protected headers for credentials, and remove or protect api_tests.json after testing sensitive systems.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/534422530/skills/laosi-api-tester)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown with Python code blocks, request examples, validation rules, and structured result summaries]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [The bundled implementation may create api_tests.json containing tested URLs, status values, latency, errors, and timestamps.]\n\n## Skill Version(s):\n\n2.0.0 (source: server release metadata and skill frontmatter)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."},{"path":"hub.json","content":"{\r\n    \"description\":  \"Premium version with full implementation, examples, and enterprise support\",\r\n    \"minOpenClawVersion\":  \"1.2.0\",\r\n    \"version\":  \"2.0.0\",\r\n    \"tags\":  [\r\n                 \"api\",\r\n                 \"testing\",\r\n                 \"http\",\r\n                 \"rest\",\r\n                 \"pro\"\r\n             ],\r\n    \"author\":  \"laosi\",\r\n    \"name\":  \"api-tester\",\r\n    \"pricing\":  {\r\n                    \"price\":  1900,\r\n                    \"model\":  \"one-time\"\r\n                },\r\n    \"license\":  \"MIT\",\r\n    \"displayName\":  \"API Tester Pro\"\r\n}"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"API测试 - 构建/发送HTTP请求，验证响应状态码/�?体，性能基准(延迟/吞吐�?，支持REST和GraphQL Skill: API Tester Pro Owner: 534422530 Summary: API测试 - 构建/发送HTTP请求，验证响应状态码/�?体，性能基准(延迟/吞吐�?，支持REST和GraphQL Tags: api:2.0.0, development:1.0.0, http:2.0.0, latest:2.0.0, pro:2.0.0, rest:2.0.0, testing:2.0.0 Version history: v2.0.0 | 2026-05-29T23:31:22.710Z | auto Version 2.0.0 - Added hub.json to support skill hub integration. - Updated SKILL.md: new \"badge: premium\" field and minor edits. - Incremented version to 2","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1088,"uniquenessScore":49,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T13:07:26.630Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T13:07:26.630Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T16:02:59.878Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}