[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6DDXY7ZC8YAEPPRX9B5X8ZH":3,"skill-same:01M6DDXY7ZC8YAEPPRX9B5X8ZH":78},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":31,"publishedAt":52,"linkOnly":53,"markdownContent":54,"markdownBody":55,"frontMatter":56,"refName":58,"commitSha":59,"skillDirectory":60,"forksCount":14,"repositoryHtmlUrl":61,"repositoryHomepageUrl":6,"ownerHtmlUrl":62,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":63,"install":64,"resources":77},"01M6DDXY7ZC8YAEPPRX9B5X8ZH","claude-api",null,"Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.","Prekzursil\u002Fagent-skills-toolchain","Prekzursil","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F54636077?v=4","01M6DACZ1PCQHD99SCR1YXG28B","Andrei Mihai Visalon","01M6DACZ670WZF535V3WYYSS4Z",0,"MIT","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Fskills\u002Fclaude-api\u002FSKILL.md",[18,23,26],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],"api","claude api","applications","caching","patterns","thinking","claude agent sdk","vision","use","prompt","tool","api patterns","prompt caching","anthropic claude","messages","tool use","streaming","sdk","python","typescript","2026-11-10 10:12:30",false,"---\nname: claude-api\ndescription: Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.\norigin: ECC\n---\n\n# Claude API\n\nBuild applications with the Anthropic Claude API and SDKs.\n\n## When to Activate\n\n- Building applications that call the Claude API\n- Code imports `anthropic` (Python) or `@anthropic-ai\u002Fsdk` (TypeScript)\n- User asks about Claude API patterns, tool use, streaming, or vision\n- Implementing agent workflows with Claude Agent SDK\n- Optimizing API costs, token usage, or latency\n\n## Model Selection\n\n| Model | ID | Best For |\n|-------|-----|----------|\n| Opus 4.1 | `claude-opus-4-1` | Complex reasoning, architecture, research |\n| Sonnet 4 | `claude-sonnet-4-0` | Balanced coding, most development tasks |\n| Haiku 3.5 | `claude-3-5-haiku-latest` | Fast responses, high-volume, cost-sensitive |\n\nDefault to Sonnet 4 unless the task requires deep reasoning (Opus) or speed\u002Fcost optimization (Haiku). For production, prefer pinned snapshot IDs over aliases.\n\n## Python SDK\n\n### Installation\n\n```bash\npip install anthropic\n```\n\n### Basic Message\n\n```python\nimport anthropic\n\nclient = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY from env\n\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    messages=[\n        {\"role\": \"user\", \"content\": \"Explain async\u002Fawait in Python\"}\n    ]\n)\nprint(message.content[0].text)\n```\n\n### Streaming\n\n```python\nwith client.messages.stream(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    messages=[{\"role\": \"user\", \"content\": \"Write a haiku about coding\"}]\n) as stream:\n    for text in stream.text_stream:\n        print(text, end=\"\", flush=True)\n```\n\n### System Prompt\n\n```python\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    system=\"You are a senior Python developer. Be concise.\",\n    messages=[{\"role\": \"user\", \"content\": \"Review this function\"}]\n)\n```\n\n## TypeScript SDK\n\n### Installation\n\n```bash\nnpm install @anthropic-ai\u002Fsdk\n```\n\n### Basic Message\n\n```typescript\nimport Anthropic from \"@anthropic-ai\u002Fsdk\";\n\nconst client = new Anthropic(); \u002F\u002F reads ANTHROPIC_API_KEY from env\n\nconst message = await client.messages.create({\n  model: \"claude-sonnet-4-0\",\n  max_tokens: 1024,\n  messages: [\n    { role: \"user\", content: \"Explain async\u002Fawait in TypeScript\" }\n  ],\n});\nconsole.log(message.content[0].text);\n```\n\n### Streaming\n\n```typescript\nconst stream = client.messages.stream({\n  model: \"claude-sonnet-4-0\",\n  max_tokens: 1024,\n  messages: [{ role: \"user\", content: \"Write a haiku\" }],\n});\n\nfor await (const event of stream) {\n  if (event.type === \"content_block_delta\" && event.delta.type === \"text_delta\") {\n    process.stdout.write(event.delta.text);\n  }\n}\n```\n\n## Tool Use\n\nDefine tools and let Claude call them:\n\n```python\ntools = [\n    {\n        \"name\": \"get_weather\",\n        \"description\": \"Get current weather for a location\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"location\": {\"type\": \"string\", \"description\": \"City name\"},\n                \"unit\": {\"type\": \"string\", \"enum\": [\"celsius\", \"fahrenheit\"]}\n            },\n            \"required\": [\"location\"]\n        }\n    }\n]\n\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    tools=tools,\n    messages=[{\"role\": \"user\", \"content\": \"What's the weather in SF?\"}]\n)\n\n# Handle tool use response\nfor block in message.content:\n    if block.type == \"tool_use\":\n        # Execute the tool with block.input\n        result = get_weather(**block.input)\n        # Send result back\n        follow_up = client.messages.create(\n            model=\"claude-sonnet-4-0\",\n            max_tokens=1024,\n            tools=tools,\n            messages=[\n                {\"role\": \"user\", \"content\": \"What's the weather in SF?\"},\n                {\"role\": \"assistant\", \"content\": message.content},\n                {\"role\": \"user\", \"content\": [\n                    {\"type\": \"tool_result\", \"tool_use_id\": block.id, \"content\": str(result)}\n                ]}\n            ]\n        )\n```\n\n## Vision\n\nSend images for analysis:\n\n```python\nimport base64\n\nwith open(\"diagram.png\", \"rb\") as f:\n    image_data = base64.standard_b64encode(f.read()).decode(\"utf-8\")\n\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    messages=[{\n        \"role\": \"user\",\n        \"content\": [\n            {\"type\": \"image\", \"source\": {\"type\": \"base64\", \"media_type\": \"image\u002Fpng\", \"data\": image_data}},\n            {\"type\": \"text\", \"text\": \"Describe this diagram\"}\n        ]\n    }]\n)\n```\n\n## Extended Thinking\n\nFor complex reasoning tasks:\n\n```python\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=16000,\n    thinking={\n        \"type\": \"enabled\",\n        \"budget_tokens\": 10000\n    },\n    messages=[{\"role\": \"user\", \"content\": \"Solve this math problem step by step...\"}]\n)\n\nfor block in message.content:\n    if block.type == \"thinking\":\n        print(f\"Thinking: {block.thinking}\")\n    elif block.type == \"text\":\n        print(f\"Answer: {block.text}\")\n```\n\n## Prompt Caching\n\nCache large system prompts or context to reduce costs:\n\n```python\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    system=[\n        {\"type\": \"text\", \"text\": large_system_prompt, \"cache_control\": {\"type\": \"ephemeral\"}}\n    ],\n    messages=[{\"role\": \"user\", \"content\": \"Question about the cached context\"}]\n)\n# Check cache usage\nprint(f\"Cache read: {message.usage.cache_read_input_tokens}\")\nprint(f\"Cache creation: {message.usage.cache_creation_input_tokens}\")\n```\n\n## Batches API\n\nProcess large volumes asynchronously at 50% cost reduction:\n\n```python\nimport time\n\nbatch = client.messages.batches.create(\n    requests=[\n        {\n            \"custom_id\": f\"request-{i}\",\n            \"params\": {\n                \"model\": \"claude-sonnet-4-0\",\n                \"max_tokens\": 1024,\n                \"messages\": [{\"role\": \"user\", \"content\": prompt}]\n            }\n        }\n        for i, prompt in enumerate(prompts)\n    ]\n)\n\n# Poll for completion\nwhile True:\n    status = client.messages.batches.retrieve(batch.id)\n    if status.processing_status == \"ended\":\n        break\n    time.sleep(30)\n\n# Get results\nfor result in client.messages.batches.results(batch.id):\n    print(result.result.message.content[0].text)\n```\n\n## Claude Agent SDK\n\nThe Agent SDK is a **separate package** — `claude-agent-sdk` on PyPI, `@anthropic-ai\u002Fclaude-agent-sdk` on npm. It is not part of the `anthropic` SDK: `import anthropic` gives you the raw Messages API, not an agent. The SDK owns the loop, executes tools, and applies permissions and hooks for you.\n\n```bash\npip install claude-agent-sdk\n```\n\n```python\nimport anyio\nfrom claude_agent_sdk import AssistantMessage, ClaudeAgentOptions, TextBlock, query\n\nasync def main():\n    options = ClaudeAgentOptions(system_prompt=\"You are a security reviewer.\")\n    async for message in query(\n        prompt=\"Review the auth module for security issues\",\n        options=options,\n    ):\n        if isinstance(message, AssistantMessage):\n            for block in message.content:\n                if isinstance(block, TextBlock):\n                    print(block.text)\n\nanyio.run(main)\n```\n\n`query()` is keyword-only and one-shot. Use `ClaudeSDKClient` for a stateful, interruptible conversation.\n\n### Manual agent loop (raw Messages API)\n\nWithout the Agent SDK you own the loop, and two rules are not optional:\n\n- Continue **only** while `stop_reason == \"tool_use\"`. Every other value (`end_turn`, `max_tokens`, `stop_sequence`, `refusal`, `pause_turn`) must exit the loop — testing `== \"end_turn\"` spins forever on all of them.\n- Answer **every** `tool_use` block with a `tool_result` carrying the same `tool_use_id`, in the very next user message. Appending the assistant turn without those results makes the next `messages.create()` fail with HTTP 400.\n\n```python\nimport anthropic\n\ntools = [{\n    \"name\": \"search_codebase\",\n    \"description\": \"Search the codebase for relevant code\",\n    \"input_schema\": {\n        \"type\": \"object\",\n        \"properties\": {\"query\": {\"type\": \"string\"}},\n        \"required\": [\"query\"]\n    }\n}]\n\nclient = anthropic.Anthropic()\nmessages = [{\"role\": \"user\", \"content\": \"Review the auth module for security issues\"}]\n\nwhile True:\n    response = client.messages.create(\n        model=\"claude-sonnet-4-0\",\n        max_tokens=4096,\n        tools=tools,\n        messages=messages,\n    )\n    if response.stop_reason != \"tool_use\":\n        break\n    messages.append({\"role\": \"assistant\", \"content\": response.content})\n    messages.append({\"role\": \"user\", \"content\": [\n        {\n            \"type\": \"tool_result\",\n            \"tool_use_id\": block.id,\n            \"content\": str(run_tool(block.name, block.input)),  # your dispatcher\n        }\n        for block in response.content\n        if block.type == \"tool_use\"\n    ]})\n```\n\n## Cost Optimization\n\n| Strategy | Savings | When to Use |\n|----------|---------|-------------|\n| Prompt caching | Up to 90% on cached tokens | Repeated system prompts or context |\n| Batches API | 50% | Non-time-sensitive bulk processing |\n| Haiku instead of Sonnet | ~75% | Simple tasks, classification, extraction |\n| Shorter max_tokens | Variable | When you know output will be short |\n| Streaming | None (same cost) | Better UX, same price |\n\n## Error Handling\n\n```python\nimport time\n\nfrom anthropic import APIError, RateLimitError, APIConnectionError\n\ntry:\n    message = client.messages.create(...)\nexcept RateLimitError:\n    # Back off and retry\n    time.sleep(60)\nexcept APIConnectionError:\n    # Network issue, retry with backoff\n    pass\nexcept APIError as e:\n    print(f\"API error {e.status_code}: {e.message}\")\n```\n\n## Environment Setup\n\n```bash\n# Required\nexport ANTHROPIC_API_KEY=\"your-api-key-here\"\n\n# Optional: set default model\nexport ANTHROPIC_MODEL=\"claude-sonnet-4-0\"\n```\n\nNever hardcode API keys. Always use environment variables.\n","# Claude API\n\nBuild applications with the Anthropic Claude API and SDKs.\n\n## When to Activate\n\n- Building applications that call the Claude API\n- Code imports `anthropic` (Python) or `@anthropic-ai\u002Fsdk` (TypeScript)\n- User asks about Claude API patterns, tool use, streaming, or vision\n- Implementing agent workflows with Claude Agent SDK\n- Optimizing API costs, token usage, or latency\n\n## Model Selection\n\n| Model | ID | Best For |\n|-------|-----|----------|\n| Opus 4.1 | `claude-opus-4-1` | Complex reasoning, architecture, research |\n| Sonnet 4 | `claude-sonnet-4-0` | Balanced coding, most development tasks |\n| Haiku 3.5 | `claude-3-5-haiku-latest` | Fast responses, high-volume, cost-sensitive |\n\nDefault to Sonnet 4 unless the task requires deep reasoning (Opus) or speed\u002Fcost optimization (Haiku). For production, prefer pinned snapshot IDs over aliases.\n\n## Python SDK\n\n### Installation\n\n```bash\npip install anthropic\n```\n\n### Basic Message\n\n```python\nimport anthropic\n\nclient = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY from env\n\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    messages=[\n        {\"role\": \"user\", \"content\": \"Explain async\u002Fawait in Python\"}\n    ]\n)\nprint(message.content[0].text)\n```\n\n### Streaming\n\n```python\nwith client.messages.stream(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    messages=[{\"role\": \"user\", \"content\": \"Write a haiku about coding\"}]\n) as stream:\n    for text in stream.text_stream:\n        print(text, end=\"\", flush=True)\n```\n\n### System Prompt\n\n```python\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    system=\"You are a senior Python developer. Be concise.\",\n    messages=[{\"role\": \"user\", \"content\": \"Review this function\"}]\n)\n```\n\n## TypeScript SDK\n\n### Installation\n\n```bash\nnpm install @anthropic-ai\u002Fsdk\n```\n\n### Basic Message\n\n```typescript\nimport Anthropic from \"@anthropic-ai\u002Fsdk\";\n\nconst client = new Anthropic(); \u002F\u002F reads ANTHROPIC_API_KEY from env\n\nconst message = await client.messages.create({\n  model: \"claude-sonnet-4-0\",\n  max_tokens: 1024,\n  messages: [\n    { role: \"user\", content: \"Explain async\u002Fawait in TypeScript\" }\n  ],\n});\nconsole.log(message.content[0].text);\n```\n\n### Streaming\n\n```typescript\nconst stream = client.messages.stream({\n  model: \"claude-sonnet-4-0\",\n  max_tokens: 1024,\n  messages: [{ role: \"user\", content: \"Write a haiku\" }],\n});\n\nfor await (const event of stream) {\n  if (event.type === \"content_block_delta\" && event.delta.type === \"text_delta\") {\n    process.stdout.write(event.delta.text);\n  }\n}\n```\n\n## Tool Use\n\nDefine tools and let Claude call them:\n\n```python\ntools = [\n    {\n        \"name\": \"get_weather\",\n        \"description\": \"Get current weather for a location\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"location\": {\"type\": \"string\", \"description\": \"City name\"},\n                \"unit\": {\"type\": \"string\", \"enum\": [\"celsius\", \"fahrenheit\"]}\n            },\n            \"required\": [\"location\"]\n        }\n    }\n]\n\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    tools=tools,\n    messages=[{\"role\": \"user\", \"content\": \"What's the weather in SF?\"}]\n)\n\n# Handle tool use response\nfor block in message.content:\n    if block.type == \"tool_use\":\n        # Execute the tool with block.input\n        result = get_weather(**block.input)\n        # Send result back\n        follow_up = client.messages.create(\n            model=\"claude-sonnet-4-0\",\n            max_tokens=1024,\n            tools=tools,\n            messages=[\n                {\"role\": \"user\", \"content\": \"What's the weather in SF?\"},\n                {\"role\": \"assistant\", \"content\": message.content},\n                {\"role\": \"user\", \"content\": [\n                    {\"type\": \"tool_result\", \"tool_use_id\": block.id, \"content\": str(result)}\n                ]}\n            ]\n        )\n```\n\n## Vision\n\nSend images for analysis:\n\n```python\nimport base64\n\nwith open(\"diagram.png\", \"rb\") as f:\n    image_data = base64.standard_b64encode(f.read()).decode(\"utf-8\")\n\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    messages=[{\n        \"role\": \"user\",\n        \"content\": [\n            {\"type\": \"image\", \"source\": {\"type\": \"base64\", \"media_type\": \"image\u002Fpng\", \"data\": image_data}},\n            {\"type\": \"text\", \"text\": \"Describe this diagram\"}\n        ]\n    }]\n)\n```\n\n## Extended Thinking\n\nFor complex reasoning tasks:\n\n```python\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=16000,\n    thinking={\n        \"type\": \"enabled\",\n        \"budget_tokens\": 10000\n    },\n    messages=[{\"role\": \"user\", \"content\": \"Solve this math problem step by step...\"}]\n)\n\nfor block in message.content:\n    if block.type == \"thinking\":\n        print(f\"Thinking: {block.thinking}\")\n    elif block.type == \"text\":\n        print(f\"Answer: {block.text}\")\n```\n\n## Prompt Caching\n\nCache large system prompts or context to reduce costs:\n\n```python\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-0\",\n    max_tokens=1024,\n    system=[\n        {\"type\": \"text\", \"text\": large_system_prompt, \"cache_control\": {\"type\": \"ephemeral\"}}\n    ],\n    messages=[{\"role\": \"user\", \"content\": \"Question about the cached context\"}]\n)\n# Check cache usage\nprint(f\"Cache read: {message.usage.cache_read_input_tokens}\")\nprint(f\"Cache creation: {message.usage.cache_creation_input_tokens}\")\n```\n\n## Batches API\n\nProcess large volumes asynchronously at 50% cost reduction:\n\n```python\nimport time\n\nbatch = client.messages.batches.create(\n    requests=[\n        {\n            \"custom_id\": f\"request-{i}\",\n            \"params\": {\n                \"model\": \"claude-sonnet-4-0\",\n                \"max_tokens\": 1024,\n                \"messages\": [{\"role\": \"user\", \"content\": prompt}]\n            }\n        }\n        for i, prompt in enumerate(prompts)\n    ]\n)\n\n# Poll for completion\nwhile True:\n    status = client.messages.batches.retrieve(batch.id)\n    if status.processing_status == \"ended\":\n        break\n    time.sleep(30)\n\n# Get results\nfor result in client.messages.batches.results(batch.id):\n    print(result.result.message.content[0].text)\n```\n\n## Claude Agent SDK\n\nThe Agent SDK is a **separate package** — `claude-agent-sdk` on PyPI, `@anthropic-ai\u002Fclaude-agent-sdk` on npm. It is not part of the `anthropic` SDK: `import anthropic` gives you the raw Messages API, not an agent. The SDK owns the loop, executes tools, and applies permissions and hooks for you.\n\n```bash\npip install claude-agent-sdk\n```\n\n```python\nimport anyio\nfrom claude_agent_sdk import AssistantMessage, ClaudeAgentOptions, TextBlock, query\n\nasync def main():\n    options = ClaudeAgentOptions(system_prompt=\"You are a security reviewer.\")\n    async for message in query(\n        prompt=\"Review the auth module for security issues\",\n        options=options,\n    ):\n        if isinstance(message, AssistantMessage):\n            for block in message.content:\n                if isinstance(block, TextBlock):\n                    print(block.text)\n\nanyio.run(main)\n```\n\n`query()` is keyword-only and one-shot. Use `ClaudeSDKClient` for a stateful, interruptible conversation.\n\n### Manual agent loop (raw Messages API)\n\nWithout the Agent SDK you own the loop, and two rules are not optional:\n\n- Continue **only** while `stop_reason == \"tool_use\"`. Every other value (`end_turn`, `max_tokens`, `stop_sequence`, `refusal`, `pause_turn`) must exit the loop — testing `== \"end_turn\"` spins forever on all of them.\n- Answer **every** `tool_use` block with a `tool_result` carrying the same `tool_use_id`, in the very next user message. Appending the assistant turn without those results makes the next `messages.create()` fail with HTTP 400.\n\n```python\nimport anthropic\n\ntools = [{\n    \"name\": \"search_codebase\",\n    \"description\": \"Search the codebase for relevant code\",\n    \"input_schema\": {\n        \"type\": \"object\",\n        \"properties\": {\"query\": {\"type\": \"string\"}},\n        \"required\": [\"query\"]\n    }\n}]\n\nclient = anthropic.Anthropic()\nmessages = [{\"role\": \"user\", \"content\": \"Review the auth module for security issues\"}]\n\nwhile True:\n    response = client.messages.create(\n        model=\"claude-sonnet-4-0\",\n        max_tokens=4096,\n        tools=tools,\n        messages=messages,\n    )\n    if response.stop_reason != \"tool_use\":\n        break\n    messages.append({\"role\": \"assistant\", \"content\": response.content})\n    messages.append({\"role\": \"user\", \"content\": [\n        {\n            \"type\": \"tool_result\",\n            \"tool_use_id\": block.id,\n            \"content\": str(run_tool(block.name, block.input)),  # your dispatcher\n        }\n        for block in response.content\n        if block.type == \"tool_use\"\n    ]})\n```\n\n## Cost Optimization\n\n| Strategy | Savings | When to Use |\n|----------|---------|-------------|\n| Prompt caching | Up to 90% on cached tokens | Repeated system prompts or context |\n| Batches API | 50% | Non-time-sensitive bulk processing |\n| Haiku instead of Sonnet | ~75% | Simple tasks, classification, extraction |\n| Shorter max_tokens | Variable | When you know output will be short |\n| Streaming | None (same cost) | Better UX, same price |\n\n## Error Handling\n\n```python\nimport time\n\nfrom anthropic import APIError, RateLimitError, APIConnectionError\n\ntry:\n    message = client.messages.create(...)\nexcept RateLimitError:\n    # Back off and retry\n    time.sleep(60)\nexcept APIConnectionError:\n    # Network issue, retry with backoff\n    pass\nexcept APIError as e:\n    print(f\"API error {e.status_code}: {e.message}\")\n```\n\n## Environment Setup\n\n```bash\n# Required\nexport ANTHROPIC_API_KEY=\"your-api-key-here\"\n\n# Optional: set default model\nexport ANTHROPIC_MODEL=\"claude-sonnet-4-0\"\n```\n\nNever hardcode API keys. Always use environment variables.\n",{"name":5,"origin":57,"description":7},"ECC","main","a298c929b6cbd662e1fce54302ce520d5ceea1a5","skills\u002Fclaude-api","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain","https:\u002F\u002Fgithub.com\u002FPrekzursil","2026-11-02 14:30:57",{"source":8,"skillName":5,"commands":65,"prompt":75,"zipAvailable":76},[66,69,72],{"tool":67,"command":68},"npx","npx skills add Prekzursil\u002Fagent-skills-toolchain --skill claude-api",{"tool":70,"command":71},"bunx","bunx skills add Prekzursil\u002Fagent-skills-toolchain --skill claude-api",{"tool":73,"command":74},"pnpm","pnpm dlx skills add Prekzursil\u002Fagent-skills-toolchain --skill claude-api","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Fskills\u002Fclaude-api\u002FSKILL.md",true,[],[79,100,126,153,167,183],{"skillNo":80,"name":81,"nameZh":6,"description":82,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":83,"categories":84,"keywords":85,"publishedAt":52},"01M6DF7D7478R55P46REYH4QAC","clarify-requirements","Resolve genuine pre-execution ambiguity by scanning repo context, generating 1-6 grounded options, and asking 1-3 focused questions via AskUserQuestion. NOT for mid-task use (injection risk); NOT when the goal is already unambiguous; use to disambiguate vague prompts before any file edits.","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Fworkspace-hooks\u002Fskills\u002Fclarify-requirements\u002FSKILL.md",[],[86,87,88,89,90,91,92,93,94,40,95,96,97,98,99],"clarify requirements","clarify","requirements","risk","options","task","prompts","goal","scanning","context","repo","injection","execution","file",{"skillNo":101,"name":102,"nameZh":6,"description":103,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":104,"categories":105,"keywords":107,"publishedAt":52},"01M6DF79CA4BHJS66J8EZDBPWJ","openmm-md","Run FREE, open-source, Windows-native GPU molecular dynamics via the openmm-md MCP (OpenMM + CUDA on the local NVIDIA GPU). Use for protein \u002F protein-ligand MD when you want a free stack or are on Windows without a Schrodinger license. Covers the full workflow (prepare, solvate, minimize, equilibrate, production, analyze, mmgbsa) AND an honest decision guide vs Schrodinger Desmond, including how to run Desmond legitimately on Linux or a cloud GPU with a real license. This is a deliberately LESSER free alternative and does NOT replace the schrodinger MCP tools. Do NOT use it to pick a free tool when a validated FEP+, WaterMap, IFD-MD, or Prime MM-GBSA result is actually required.","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Fmcp\u002Fopenmm-md-mcp\u002Fskill\u002Fopenmm-md\u002FSKILL.md",[106],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[108,109,110,111,112,113,42,114,115,116,117,118,119,120,40,121,122,123,124,125],"openmm md","how","decision","pick","linux","analyze","stack","open","NVIDIA","gpu","license","workflow","windows","free","molecular dynamics","local","do","MCP",{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":138,"publishedAt":52},"01M6DF76C1MG85VEWP8VZCBNMN","visual-review","Take screenshots of web pages and UI using Playwright for visual review and iteration","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Feditor\u002Fmetaswarm\u002Fskills\u002Fvisual-review\u002FSKILL.md",[132,135],{"categoryNo":133,"categoryName":134,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":136,"categoryName":137,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",[139,140,141,142,143,144,145,146,147,148,109,149,150,151,152],"review","visual","visual review","pages","web","false","iteration","take","check","slides","ui","screenshot","playwright","screenshots",{"skillNo":154,"name":155,"nameZh":6,"description":156,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":157,"categories":158,"keywords":159,"publishedAt":52},"01M6DF73AQVCBZKEN0YXEX9FXP","status","Diagnostic status report — shows metaswarm installation state, project setup, and potential issues","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Feditor\u002Fmetaswarm\u002Fskills\u002Fstatus\u002FSKILL.md",[],[155,160,161,162,163,164,165,166],"setup","report","project","installation","project setup","issues","state",{"skillNo":168,"name":169,"nameZh":6,"description":170,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":171,"categories":172,"keywords":174,"publishedAt":52},"01M6DF6X6C2XB0P6GX76P7TTYV","start","Use when starting work on any task, when the user mentions metaswarm, or when the user wants to begin tracked development work","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Feditor\u002Fmetaswarm\u002Fskills\u002Fstart\u002FSKILL.md",[173],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[169,175,91,176,177,178,40,179,180,181,182],"start issue","issue","ready","work on issue","user","work","work on","development",{"skillNo":184,"name":160,"nameZh":6,"description":185,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":186,"categories":187,"keywords":188,"publishedAt":52},"01M6DF6QMJ9AJKFKHHKRT005PQ","Interactive project setup — detects your project, configures metaswarm, writes project-local files","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Feditor\u002Fmetaswarm\u002Fskills\u002Fsetup\u002FSKILL.md",[],[160,162,123,189,164,190],"files","interactive"]