[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6DF56EDJQRYE0EXRAAM3V9X":3,"skill-same:01M6DF56EDJQRYE0EXRAAM3V9X":70},{"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":28,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":50,"commitSha":51,"skillDirectory":52,"forksCount":14,"repositoryHtmlUrl":53,"repositoryHomepageUrl":6,"ownerHtmlUrl":54,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":55,"install":56,"resources":69},"01M6DF56EDJQRYE0EXRAAM3V9X","x-api",null,"X\u002FTwitter API integration for posting tweets, threads, reading timelines, search, and analytics. Covers OAuth auth patterns, rate limits, and platform-native content posting. Use when the user wants to interact with X programmatically.","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\u002Fx-api\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"api","x api","auth","analytics","search","content","integration","OAuth","twitter","user","use","api integration","patterns","platform","posting","2026-11-10 10:12:30",false,"---\nname: x-api\ndescription: X\u002FTwitter API integration for posting tweets, threads, reading timelines, search, and analytics. Covers OAuth auth patterns, rate limits, and platform-native content posting. Use when the user wants to interact with X programmatically.\norigin: ECC\n---\n\n# X API\n\nProgrammatic interaction with X (Twitter) for posting, reading, searching, and analytics.\n\n## When to Activate\n\n- User wants to post tweets or threads programmatically\n- Reading timeline, mentions, or user data from X\n- Searching X for content, trends, or conversations\n- Building X integrations or bots\n- Analytics and engagement tracking\n- User says \"post to X\", \"tweet\", \"X API\", or \"Twitter API\"\n\n## Authentication\n\n### OAuth 2.0 Bearer Token (App-Only)\n\nBest for: read-heavy operations, search, public data.\n\n```bash\n# Environment setup\nexport X_BEARER_TOKEN=\"your-bearer-token\"\n```\n\n```python\nimport os\nimport requests\n\nbearer = os.environ[\"X_BEARER_TOKEN\"]\nheaders = {\"Authorization\": f\"Bearer {bearer}\"}\n\n# Search recent tweets\nresp = requests.get(\n    \"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\u002Fsearch\u002Frecent\",\n    headers=headers,\n    params={\"query\": \"claude code\", \"max_results\": 10}\n)\ntweets = resp.json()\n```\n\n### OAuth 1.0a (User Context)\n\nRequired for: posting tweets, managing account, DMs.\n\n```bash\n# Environment setup — source before use\nexport X_API_KEY=\"your-api-key\"\nexport X_API_SECRET=\"your-api-secret\"\nexport X_ACCESS_TOKEN=\"your-access-token\"\nexport X_ACCESS_SECRET=\"your-access-secret\"\n```\n\n```python\nimport os\nfrom requests_oauthlib import OAuth1Session\n\noauth = OAuth1Session(\n    os.environ[\"X_API_KEY\"],\n    client_secret=os.environ[\"X_API_SECRET\"],\n    resource_owner_key=os.environ[\"X_ACCESS_TOKEN\"],\n    resource_owner_secret=os.environ[\"X_ACCESS_SECRET\"],\n)\n```\n\n## Core Operations\n\n### Post a Tweet\n\n```python\nresp = oauth.post(\n    \"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\",\n    json={\"text\": \"Hello from Claude Code\"}\n)\nresp.raise_for_status()\ntweet_id = resp.json()[\"data\"][\"id\"]\n```\n\n### Post a Thread\n\n```python\ndef post_thread(oauth, tweets: list[str]) -> list[str]:\n    ids = []\n    reply_to = None\n    for text in tweets:\n        payload = {\"text\": text}\n        if reply_to:\n            payload[\"reply\"] = {\"in_reply_to_tweet_id\": reply_to}\n        resp = oauth.post(\"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\", json=payload)\n        tweet_id = resp.json()[\"data\"][\"id\"]\n        ids.append(tweet_id)\n        reply_to = tweet_id\n    return ids\n```\n\n### Read User Timeline\n\n```python\nresp = requests.get(\n    f\"https:\u002F\u002Fapi.x.com\u002F2\u002Fusers\u002F{user_id}\u002Ftweets\",\n    headers=headers,\n    params={\n        \"max_results\": 10,\n        \"tweet.fields\": \"created_at,public_metrics\",\n    }\n)\n```\n\n### Search Tweets\n\n```python\nresp = requests.get(\n    \"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\u002Fsearch\u002Frecent\",\n    headers=headers,\n    params={\n        \"query\": \"from:affaanmustafa -is:retweet\",\n        \"max_results\": 10,\n        \"tweet.fields\": \"public_metrics,created_at\",\n    }\n)\n```\n\n### Get User by Username\n\n```python\nresp = requests.get(\n    \"https:\u002F\u002Fapi.x.com\u002F2\u002Fusers\u002Fby\u002Fusername\u002Faffaanmustafa\",\n    headers=headers,\n    params={\"user.fields\": \"public_metrics,description,created_at\"}\n)\n```\n\n### Upload Media and Post\n\n```python\n# Media upload uses v1.1 endpoint\n\n# Step 1: Upload media\nmedia_resp = oauth.post(\n    \"https:\u002F\u002Fupload.twitter.com\u002F1.1\u002Fmedia\u002Fupload.json\",\n    files={\"media\": open(\"image.png\", \"rb\")}\n)\nmedia_id = media_resp.json()[\"media_id_string\"]\n\n# Step 2: Post with media\nresp = oauth.post(\n    \"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\",\n    json={\"text\": \"Check this out\", \"media\": {\"media_ids\": [media_id]}}\n)\n```\n\n## Rate Limits\n\nX API rate limits vary by endpoint, auth method, and account tier, and they change over time. Always:\n- Check the current X developer docs before hardcoding assumptions\n- Read `x-rate-limit-remaining` and `x-rate-limit-reset` headers at runtime\n- Back off automatically instead of relying on static tables in code\n\n```python\nimport time\n\nremaining = int(resp.headers.get(\"x-rate-limit-remaining\", 0))\nif remaining \u003C 5:\n    reset = int(resp.headers.get(\"x-rate-limit-reset\", 0))\n    wait = max(0, reset - int(time.time()))\n    print(f\"Rate limit approaching. Resets in {wait}s\")\n```\n\n## Error Handling\n\n```python\nresp = oauth.post(\"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\", json={\"text\": content})\nif resp.status_code == 201:\n    return resp.json()[\"data\"][\"id\"]\nelif resp.status_code == 429:\n    reset = int(resp.headers[\"x-rate-limit-reset\"])\n    raise Exception(f\"Rate limited. Resets at {reset}\")\nelif resp.status_code == 403:\n    raise Exception(f\"Forbidden: {resp.json().get('detail', 'check permissions')}\")\nelse:\n    raise Exception(f\"X API error {resp.status_code}: {resp.text}\")\n```\n\n## Security\n\n- **Never hardcode tokens.** Use environment variables or `.env` files.\n- **Never commit `.env` files.** Add to `.gitignore`.\n- **Rotate tokens** if exposed. Regenerate at developer.x.com.\n- **Use read-only tokens** when write access is not needed.\n- **Store OAuth secrets securely** — not in source code or logs.\n\n## Integration with Content Engine\n\nUse `content-engine` skill to generate platform-native content, then post via X API:\n1. Generate content with content-engine (X platform format)\n2. Validate length (280 chars for single tweet)\n3. Post via X API using patterns above\n4. Track engagement via public_metrics\n\n## Related Skills\n\n- `content-engine` — Generate platform-native content for X\n- `crosspost` — Distribute content across X, LinkedIn, and other platforms\n","# X API\n\nProgrammatic interaction with X (Twitter) for posting, reading, searching, and analytics.\n\n## When to Activate\n\n- User wants to post tweets or threads programmatically\n- Reading timeline, mentions, or user data from X\n- Searching X for content, trends, or conversations\n- Building X integrations or bots\n- Analytics and engagement tracking\n- User says \"post to X\", \"tweet\", \"X API\", or \"Twitter API\"\n\n## Authentication\n\n### OAuth 2.0 Bearer Token (App-Only)\n\nBest for: read-heavy operations, search, public data.\n\n```bash\n# Environment setup\nexport X_BEARER_TOKEN=\"your-bearer-token\"\n```\n\n```python\nimport os\nimport requests\n\nbearer = os.environ[\"X_BEARER_TOKEN\"]\nheaders = {\"Authorization\": f\"Bearer {bearer}\"}\n\n# Search recent tweets\nresp = requests.get(\n    \"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\u002Fsearch\u002Frecent\",\n    headers=headers,\n    params={\"query\": \"claude code\", \"max_results\": 10}\n)\ntweets = resp.json()\n```\n\n### OAuth 1.0a (User Context)\n\nRequired for: posting tweets, managing account, DMs.\n\n```bash\n# Environment setup — source before use\nexport X_API_KEY=\"your-api-key\"\nexport X_API_SECRET=\"your-api-secret\"\nexport X_ACCESS_TOKEN=\"your-access-token\"\nexport X_ACCESS_SECRET=\"your-access-secret\"\n```\n\n```python\nimport os\nfrom requests_oauthlib import OAuth1Session\n\noauth = OAuth1Session(\n    os.environ[\"X_API_KEY\"],\n    client_secret=os.environ[\"X_API_SECRET\"],\n    resource_owner_key=os.environ[\"X_ACCESS_TOKEN\"],\n    resource_owner_secret=os.environ[\"X_ACCESS_SECRET\"],\n)\n```\n\n## Core Operations\n\n### Post a Tweet\n\n```python\nresp = oauth.post(\n    \"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\",\n    json={\"text\": \"Hello from Claude Code\"}\n)\nresp.raise_for_status()\ntweet_id = resp.json()[\"data\"][\"id\"]\n```\n\n### Post a Thread\n\n```python\ndef post_thread(oauth, tweets: list[str]) -> list[str]:\n    ids = []\n    reply_to = None\n    for text in tweets:\n        payload = {\"text\": text}\n        if reply_to:\n            payload[\"reply\"] = {\"in_reply_to_tweet_id\": reply_to}\n        resp = oauth.post(\"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\", json=payload)\n        tweet_id = resp.json()[\"data\"][\"id\"]\n        ids.append(tweet_id)\n        reply_to = tweet_id\n    return ids\n```\n\n### Read User Timeline\n\n```python\nresp = requests.get(\n    f\"https:\u002F\u002Fapi.x.com\u002F2\u002Fusers\u002F{user_id}\u002Ftweets\",\n    headers=headers,\n    params={\n        \"max_results\": 10,\n        \"tweet.fields\": \"created_at,public_metrics\",\n    }\n)\n```\n\n### Search Tweets\n\n```python\nresp = requests.get(\n    \"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\u002Fsearch\u002Frecent\",\n    headers=headers,\n    params={\n        \"query\": \"from:affaanmustafa -is:retweet\",\n        \"max_results\": 10,\n        \"tweet.fields\": \"public_metrics,created_at\",\n    }\n)\n```\n\n### Get User by Username\n\n```python\nresp = requests.get(\n    \"https:\u002F\u002Fapi.x.com\u002F2\u002Fusers\u002Fby\u002Fusername\u002Faffaanmustafa\",\n    headers=headers,\n    params={\"user.fields\": \"public_metrics,description,created_at\"}\n)\n```\n\n### Upload Media and Post\n\n```python\n# Media upload uses v1.1 endpoint\n\n# Step 1: Upload media\nmedia_resp = oauth.post(\n    \"https:\u002F\u002Fupload.twitter.com\u002F1.1\u002Fmedia\u002Fupload.json\",\n    files={\"media\": open(\"image.png\", \"rb\")}\n)\nmedia_id = media_resp.json()[\"media_id_string\"]\n\n# Step 2: Post with media\nresp = oauth.post(\n    \"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\",\n    json={\"text\": \"Check this out\", \"media\": {\"media_ids\": [media_id]}}\n)\n```\n\n## Rate Limits\n\nX API rate limits vary by endpoint, auth method, and account tier, and they change over time. Always:\n- Check the current X developer docs before hardcoding assumptions\n- Read `x-rate-limit-remaining` and `x-rate-limit-reset` headers at runtime\n- Back off automatically instead of relying on static tables in code\n\n```python\nimport time\n\nremaining = int(resp.headers.get(\"x-rate-limit-remaining\", 0))\nif remaining \u003C 5:\n    reset = int(resp.headers.get(\"x-rate-limit-reset\", 0))\n    wait = max(0, reset - int(time.time()))\n    print(f\"Rate limit approaching. Resets in {wait}s\")\n```\n\n## Error Handling\n\n```python\nresp = oauth.post(\"https:\u002F\u002Fapi.x.com\u002F2\u002Ftweets\", json={\"text\": content})\nif resp.status_code == 201:\n    return resp.json()[\"data\"][\"id\"]\nelif resp.status_code == 429:\n    reset = int(resp.headers[\"x-rate-limit-reset\"])\n    raise Exception(f\"Rate limited. Resets at {reset}\")\nelif resp.status_code == 403:\n    raise Exception(f\"Forbidden: {resp.json().get('detail', 'check permissions')}\")\nelse:\n    raise Exception(f\"X API error {resp.status_code}: {resp.text}\")\n```\n\n## Security\n\n- **Never hardcode tokens.** Use environment variables or `.env` files.\n- **Never commit `.env` files.** Add to `.gitignore`.\n- **Rotate tokens** if exposed. Regenerate at developer.x.com.\n- **Use read-only tokens** when write access is not needed.\n- **Store OAuth secrets securely** — not in source code or logs.\n\n## Integration with Content Engine\n\nUse `content-engine` skill to generate platform-native content, then post via X API:\n1. Generate content with content-engine (X platform format)\n2. Validate length (280 chars for single tweet)\n3. Post via X API using patterns above\n4. Track engagement via public_metrics\n\n## Related Skills\n\n- `content-engine` — Generate platform-native content for X\n- `crosspost` — Distribute content across X, LinkedIn, and other platforms\n",{"name":5,"origin":49,"description":7},"ECC","main","a298c929b6cbd662e1fce54302ce520d5ceea1a5","skills\u002Fx-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":57,"prompt":67,"zipAvailable":68},[58,61,64],{"tool":59,"command":60},"npx","npx skills add Prekzursil\u002Fagent-skills-toolchain --skill x-api",{"tool":62,"command":63},"bunx","bunx skills add Prekzursil\u002Fagent-skills-toolchain --skill x-api",{"tool":65,"command":66},"pnpm","pnpm dlx skills add Prekzursil\u002Fagent-skills-toolchain --skill x-api","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Fskills\u002Fx-api\u002FSKILL.md",true,[],[71,92,121,148,162,177],{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":44},"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",[],[78,79,80,81,82,83,84,85,86,39,87,88,89,90,91],"clarify requirements","clarify","requirements","risk","options","task","prompts","goal","scanning","context","repo","injection","execution","file",{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":101,"publishedAt":44},"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",[98],{"categoryNo":99,"categoryName":100,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[102,103,104,105,106,107,108,109,110,111,112,113,114,115,39,116,117,118,119,120],"openmm md","how","decision","pick","linux","analyze","tool","stack","open","NVIDIA","gpu","license","workflow","windows","free","molecular dynamics","local","do","MCP",{"skillNo":122,"name":123,"nameZh":6,"description":124,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":133,"publishedAt":44},"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",[127,130],{"categoryNo":128,"categoryName":129,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":131,"categoryName":132,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",[134,135,136,137,138,139,140,141,142,143,103,144,145,146,147],"review","visual","visual review","pages","web","false","iteration","take","check","slides","ui","screenshot","playwright","screenshots",{"skillNo":149,"name":150,"nameZh":6,"description":151,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":152,"categories":153,"keywords":154,"publishedAt":44},"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",[],[150,155,156,157,158,159,160,161],"setup","report","project","installation","project setup","issues","state",{"skillNo":163,"name":164,"nameZh":6,"description":165,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":166,"categories":167,"keywords":169,"publishedAt":44},"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",[168],{"categoryNo":99,"categoryName":100,"taxonomyType":21,"taxonomyTypeDesc":22},[164,170,83,171,172,173,39,38,174,175,176],"start issue","issue","ready","work on issue","work","work on","development",{"skillNo":178,"name":155,"nameZh":6,"description":179,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":180,"categories":181,"keywords":182,"publishedAt":44},"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",[],[155,157,118,183,159,184],"files","interactive"]