{
  "canonical_name": "justoneapi/justoneapi-mcp",
  "compilation_id": "pack_af309b0c96c449aca33a2cbd78d8c768",
  "created_at": "2026-05-15T08:07:17.883943+00:00",
  "created_by": "project-pack-compiler",
  "feedback": {
    "carrier_selection_notes": [
      "viable_asset_types=mcp_config, recipe, host_instruction, eval, preflight",
      "recommended_asset_types=mcp_config, recipe, host_instruction, eval, preflight"
    ],
    "evidence_delta": {
      "confirmed_claims": [
        "identity_anchor_present",
        "capability_and_host_targets_present",
        "install_path_declared_or_better"
      ],
      "missing_required_fields": [],
      "must_verify_forwarded": [
        "Run or inspect `npm install -g justoneapi-mcp` in an isolated environment.",
        "Confirm the project exposes the claimed capability to at least one target host."
      ],
      "quickstart_execution_scope": "allowlisted_sandbox_smoke",
      "sandbox_command": "npm install -g justoneapi-mcp",
      "sandbox_container_image": "node:22-slim",
      "sandbox_execution_backend": "docker",
      "sandbox_planner_decision": "deterministic_isolated_install",
      "sandbox_validation_id": "sbx_f4d5a0cbf9cb4e11b48eca666e7b10fa"
    },
    "feedback_event_type": "project_pack_compilation_feedback",
    "learning_candidate_reasons": [],
    "template_gaps": []
  },
  "identity": {
    "canonical_id": "project_4a0509d240ec8b964a6bf5e9a612662f",
    "canonical_name": "justoneapi/justoneapi-mcp",
    "homepage_url": null,
    "license": "unknown",
    "repo_url": "https://github.com/justoneapi/justoneapi-mcp",
    "slug": "justoneapi-mcp",
    "source_packet_id": "phit_b59fcfe7e62a4d7f93abbf862c020a12",
    "source_validation_id": "dval_21f5de23e008417cbe3efcca12f1f7ba"
  },
  "merchandising": {
    "best_for": "需要工具连接与集成能力，并使用 mcp_host的用户",
    "github_forks": 3,
    "github_stars": 8,
    "one_liner_en": "Production-ready MCP server exposing JustOneAPI endpoints to AI agents with raw JSON responses.",
    "one_liner_zh": "Production-ready MCP server exposing JustOneAPI endpoints to AI agents with raw JSON responses.",
    "primary_category": {
      "category_id": "tool-integrations",
      "confidence": "high",
      "name_en": "Tool Integrations",
      "name_zh": "工具连接与集成",
      "reason": "matched_keywords:mcp, api, server"
    },
    "target_user": "使用 mcp_host 等宿主 AI 的用户",
    "title_en": "justoneapi-mcp",
    "title_zh": "justoneapi-mcp 能力包",
    "visible_tags": [
      {
        "label_en": "Browser Agents",
        "label_zh": "浏览器 Agent",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-browser-agents",
        "type": "product_domain"
      },
      {
        "label_en": "Web Task Automation",
        "label_zh": "网页任务自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-web-task-automation",
        "type": "user_job"
      },
      {
        "label_en": "Natural-language Web Actions",
        "label_zh": "自然语言网页操作",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-natural-language-web-actions",
        "type": "core_capability"
      },
      {
        "label_en": "Node-based Workflow",
        "label_zh": "节点式流程编排",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-node-based-workflow",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Evaluation Suite",
        "label_zh": "评测体系",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-evaluation-suite",
        "type": "selection_signal"
      }
    ]
  },
  "packet_id": "phit_b59fcfe7e62a4d7f93abbf862c020a12",
  "page_model": {
    "artifacts": {
      "artifact_slug": "justoneapi-mcp",
      "files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json",
        "REPO_INSPECTION.md",
        "CAPABILITY_CONTRACT.json",
        "EVIDENCE_INDEX.json",
        "CLAIM_GRAPH.json"
      ],
      "required_files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json"
      ]
    },
    "detail": {
      "capability_source": "Project Hit Packet + DownstreamValidationResult",
      "commands": [
        {
          "command": "npm install -g justoneapi-mcp",
          "label": "Node.js / npm · 官方安装入口",
          "source": "https://github.com/justoneapi/justoneapi-mcp#readme",
          "verified": true
        }
      ],
      "display_tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "自然语言网页操作",
        "节点式流程编排",
        "评测体系"
      ],
      "eyebrow": "工具连接与集成",
      "glance": [
        {
          "body": "判断自己是不是目标用户。",
          "label": "最适合谁",
          "value": "需要工具连接与集成能力，并使用 mcp_host的用户"
        },
        {
          "body": "先理解能力边界，再决定是否继续。",
          "label": "核心价值",
          "value": "Production-ready MCP server exposing JustOneAPI endpoints to AI agents with raw JSON responses."
        },
        {
          "body": "未完成验证前保持审慎。",
          "label": "继续前",
          "value": "publish to Doramagic.ai project surfaces"
        }
      ],
      "guardrail_source": "Boundary & Risk Card",
      "guardrails": [
        {
          "body": "Prompt Preview 只展示流程，不证明项目已安装或运行。",
          "label": "Check 1",
          "value": "不要把试用当真实运行"
        },
        {
          "body": "mcp_host",
          "label": "Check 2",
          "value": "确认宿主兼容"
        },
        {
          "body": "publish to Doramagic.ai project surfaces",
          "label": "Check 3",
          "value": "先隔离验证"
        }
      ],
      "mode": "mcp_config, recipe, host_instruction, eval, preflight",
      "pitfall_log": {
        "items": [
          {
            "body": "README/documentation is current enough for a first validation pass.",
            "category": "能力坑",
            "evidence": [
              "capability.assumptions | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | README/documentation is current enough for a first validation pass."
            ],
            "severity": "medium",
            "suggested_check": "将假设转成下游验证清单。",
            "title": "能力判断依赖假设",
            "user_impact": "假设不成立时，用户拿不到承诺的能力。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个运行相关的待验证问题：Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of 2-39)",
            "category": "运行坑",
            "evidence": [
              "community_evidence:github | cevd_3b8110f2a2a84250a1da5b96b5573463 | https://github.com/justoneapi/justoneapi-mcp/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。"
            ],
            "severity": "medium",
            "suggested_check": "来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。",
            "title": "来源证据：Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of…",
            "user_impact": "可能增加新用户试用和生产接入成本。"
          },
          {
            "body": "未记录 last_activity_observed。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | last_activity_observed missing"
            ],
            "severity": "medium",
            "suggested_check": "补 GitHub 最近 commit、release、issue/PR 响应信号。",
            "title": "维护活跃度未知",
            "user_impact": "新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "downstream_validation.risk_items | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "进入安全/权限治理复核队列。",
            "title": "下游验证发现风险项",
            "user_impact": "下游已经要求复核，不能在页面中弱化。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "risks.scoring_risks | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "把风险写入边界卡，并确认是否需要人工复核。",
            "title": "存在评分风险",
            "user_impact": "风险会影响是否适合普通用户安装。"
          },
          {
            "body": "issue_or_pr_quality=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | issue_or_pr_quality=unknown"
            ],
            "severity": "low",
            "suggested_check": "抽样最近 issue/PR，判断是否长期无人处理。",
            "title": "issue/PR 响应质量未知",
            "user_impact": "用户无法判断遇到问题后是否有人维护。"
          },
          {
            "body": "release_recency=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | release_recency=unknown"
            ],
            "severity": "low",
            "suggested_check": "确认最近 release/tag 和 README 安装命令是否一致。",
            "title": "发布节奏不明确",
            "user_impact": "安装命令和文档可能落后于代码，用户踩坑概率升高。"
          }
        ],
        "source": "ProjectPitfallLog + ProjectHitPacket + validation + community signals",
        "summary": "发现 7 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。",
        "title": "踩坑日志"
      },
      "snapshot": {
        "contributors": 2,
        "forks": 3,
        "license": "unknown",
        "note": "站点快照，非实时质量证明；用于开工前背景判断。",
        "stars": 8
      },
      "source_url": "https://github.com/justoneapi/justoneapi-mcp",
      "steps": [
        {
          "body": "不安装项目，先体验能力节奏。",
          "code": "preview",
          "title": "先试 Prompt"
        },
        {
          "body": "理解输入、输出、失败模式和边界。",
          "code": "manual",
          "title": "读说明书"
        },
        {
          "body": "把上下文交给宿主 AI 继续工作。",
          "code": "context",
          "title": "带给 AI"
        },
        {
          "body": "进入主力环境前先完成安装入口与风险边界验证。",
          "code": "verify",
          "title": "沙箱验证"
        }
      ],
      "subtitle": "Production-ready MCP server exposing JustOneAPI endpoints to AI agents with raw JSON responses.",
      "title": "justoneapi-mcp 能力包",
      "trial_prompt": "# justoneapi-mcp - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 justoneapi-mcp 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的工具连接与集成任务。\n我常用的宿主 AI：MCP Client\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: Production-ready MCP server exposing JustOneAPI endpoints to AI agents with raw JSON responses. 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. getting-started：Getting Started with JustOneAPI MCP。围绕“Getting Started with JustOneAPI MCP”模拟一次用户任务，不展示安装或运行结果。\n2. authentication：Authentication。围绕“Authentication”模拟一次用户任务，不展示安装或运行结果。\n3. system-architecture：System Architecture。围绕“System Architecture”模拟一次用户任务，不展示安装或运行结果。\n4. unified-search-tool：Unified Search Tool。围绕“Unified Search Tool”模拟一次用户任务，不展示安装或运行结果。\n5. configuration-reference：Configuration Reference。围绕“Configuration Reference”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. getting-started\n输入：用户提供的“Getting Started with JustOneAPI MCP”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. authentication\n输入：用户提供的“Authentication”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. system-architecture\n输入：用户提供的“System Architecture”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. unified-search-tool\n输入：用户提供的“Unified Search Tool”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. configuration-reference\n输入：用户提供的“Configuration Reference”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / getting-started：Step 1 必须围绕“Getting Started with JustOneAPI MCP”形成一个小中间产物，并等待用户确认。\n- Step 2 / authentication：Step 2 必须围绕“Authentication”形成一个小中间产物，并等待用户确认。\n- Step 3 / system-architecture：Step 3 必须围绕“System Architecture”形成一个小中间产物，并等待用户确认。\n- Step 4 / unified-search-tool：Step 4 必须围绕“Unified Search Tool”形成一个小中间产物，并等待用户确认。\n- Step 5 / configuration-reference：Step 5 必须围绕“Configuration Reference”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/justoneapi/justoneapi-mcp\n- https://github.com/justoneapi/justoneapi-mcp#readme\n- README.md\n- package.json\n- src/common/config.ts\n- src/common/http.ts\n- src/index.ts\n- src/tools/search/unified_search_v1.ts\n- TOOLS.md\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 justoneapi-mcp 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "voices": [
        {
          "body": "来源平台：github。github/github_issue: Clawhub skill family: 6 SKILL.md files have description-vs-body operatio（https://github.com/justoneapi/justoneapi-mcp/issues/2）。这些是项目级外部声音，不作为单独质量证明。",
          "items": [
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Clawhub skill family: 6 SKILL.md files have description-vs-body operatio",
              "url": "https://github.com/justoneapi/justoneapi-mcp/issues/2"
            }
          ],
          "status": "已收录 1 条来源",
          "title": "社区讨论"
        }
      ]
    },
    "homepage_card": {
      "category": "工具连接与集成",
      "desc": "Production-ready MCP server exposing JustOneAPI endpoints to AI agents with raw JSON responses.",
      "effort": "安装已验证",
      "forks": 3,
      "icon": "link",
      "name": "justoneapi-mcp 能力包",
      "risk": "需复核",
      "slug": "justoneapi-mcp",
      "stars": 8,
      "tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "自然语言网页操作",
        "节点式流程编排",
        "评测体系"
      ],
      "thumb": "gray",
      "type": "MCP 配置"
    },
    "manual": {
      "markdown": "# https://github.com/justoneapi/justoneapi-mcp 项目说明书\n\n生成时间：2026-05-15 07:48:52 UTC\n\n## 目录\n\n- [Getting Started with JustOneAPI MCP](#getting-started)\n- [Authentication](#authentication)\n- [System Architecture](#system-architecture)\n- [HTTP Client Implementation](#http-client)\n- [Unified Search Tool](#unified-search-tool)\n- [Kuaishou Video Search Tool](#kuaishou-video-search)\n- [Tool Naming Conventions and Standards](#tool-conventions)\n- [Configuration Reference](#configuration-reference)\n- [MCP Host Integration](#mcp-integration)\n- [Error Handling](#error-handling)\n\n<a id='getting-started'></a>\n\n## Getting Started with JustOneAPI MCP\n\n### 相关页面\n\n相关主题：[Authentication](#authentication), [MCP Host Integration](#mcp-integration)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n</details>\n\n# Getting Started with JustOneAPI MCP\n\n## Overview\n\nJustOneAPI MCP Server is a Model Context Protocol (MCP) server that exposes JustOneAPI endpoints to AI assistants like Claude Desktop, Cursor, and other MCP-compatible hosts. The server acts as a thin transport layer that handles authentication, retries, timeouts, and error normalization while returning raw JSON responses from upstream platforms.\n\n**Key Characteristics:**\n\n- Returns unmodified upstream JSON responses for maximum data fidelity\n- No field parsing or schema normalization\n- Designed for AI agents and developer workflows\n- Supports multiple Chinese social media and news platforms\n\n资料来源：[README.md:1-20]()\n\n## Architecture\n\n### System Components\n\n```mermaid\ngraph TD\n    A[MCP Host<br/>Claude Desktop/Cursor] --> B[JustOneAPI MCP Server]\n    B --> C[JustOneAPI REST API]\n    C --> D[Upstream Platforms]\n    \n    D --> E[Weibo]\n    D --> F[WeChat]\n    D --> G[Zhihu]\n    D --> H[Douyin]\n    D --> I[Xiaohongshu]\n    D --> J[Bilibili]\n    D --> K[Kuaishou]\n    D --> L[News]\n    \n    B --> M[Authentication]\n    B --> N[Retry Logic]\n    B --> O[Error Normalization]\n```\n\n### Technology Stack\n\n| Component | Technology | Version |\n|-----------|------------|---------|\n| Runtime | Node.js | >= 18.0.0 |\n| MCP SDK | @modelcontextprotocol/sdk | ^1.25.1 |\n| Validation | Zod | ^4.3.4 |\n| Environment | dotenv | ^17.2.3 |\n| Language | TypeScript | ^5.9.3 |\n\n资料来源：[package.json:18-26]()\n\n## Prerequisites\n\nBefore using JustOneAPI MCP, ensure you have:\n\n1. **Node.js 18.0.0 or higher** installed\n2. **JustOneAPI Token** obtained from [justoneapi.com](https://dashboard.justoneapi.com/en/login)\n3. **MCP-compatible host** (Claude Desktop, Cursor, or other)\n\n## Installation\n\n### Option 1: npx (Recommended)\n\nThe simplest method requires no installation. Configure your MCP host to run the package directly via npx.\n\n资料来源：[README.md:85-95]()\n\n### Option 2: Local Installation\n\nFor production environments, install the package locally:\n\n```bash\nnpm install -g justoneapi-mcp\n```\n\n## Configuration\n\n### Claude Desktop Configuration\n\nEdit the configuration file for your operating system:\n\n| OS | Configuration Path |\n|----|---------------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n**Configuration Example:**\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_actual_token_here\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md:85-102]()\n\n### Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | - | Your JustOneAPI authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint URL |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after first attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |\n\n资料来源：[README.md:138-147]()\n\n## Available Tools\n\n### Tool Naming Convention\n\nAll tools follow the pattern: `{platform}_{action}_{version}`\n\n### Current Tools\n\n| Tool | Description | Version |\n|------|-------------|---------|\n| `unified_search_v1` | Unified search across multiple platforms | v1 |\n| `kuaishou_search_video_v2` | Platform-specific video search | v2 |\n\n资料来源：[README.md:55-58]()\n\n## Using the Unified Search\n\n### Featured Tool: unified_search_v1\n\nSearch across multiple Chinese social media and news platforms in a single request.\n\n**Supported Platforms:**\n\n- Weibo\n- WeChat\n- Zhihu\n- Douyin\n- Xiaohongshu\n- Bilibili\n- Kuaishou\n- News (aggregated)\n\n资料来源：[README.md:36-37]()\n\n### Parameters\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `keyword` | string | Yes | Search keyword with advanced syntax |\n| `source` | string | No | Platform filter (default: `ALL`) |\n| `start` | string | First page only | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `end` | string | First page only | End time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `nextCursor` | string | Pagination only | Cursor from previous response |\n\n资料来源：[TOOLS.md:21-28]()\n\n### Search Syntax\n\n```mermaid\ngraph LR\n    A[Search Input] --> B{Syntax Type}\n    B --> C[Single: deepseek]\n    B --> D[AND: deepseek chatgpt]\n    B --> E[OR: deepseek~chatgpt]\n    B --> F[NOT: deepseek -chatgpt]\n```\n\n| Syntax | Example | Description |\n|--------|---------|-------------|\n| Single keyword | `deepseek` | Simple search |\n| AND search | `deepseek chatgpt` | Both keywords must appear |\n| OR search | `deepseek~chatgpt` | Either keyword can appear |\n| NOT search | `deepseek -chatgpt` | Exclude keyword |\n\n资料来源：[README.md:48-55]()\n\n### Platform Options\n\n| Value | Description |\n|-------|-------------|\n| `ALL` | Search all platforms (default) |\n| `NEWS` | News articles only |\n| `WEIBO` | Weibo posts |\n| `WEIXIN` | WeChat public accounts |\n| `ZHIHU` | Zhihu Q&A |\n| `DOUYIN` | Douyin videos |\n| `XIAOHONGSHU` | Xiaohongshu posts |\n| `BILIBILI` | Bilibili videos |\n| `KUAISHOU` | Kuaishou videos |\n\n资料来源：[src/tools/search/unified_search_v1.ts:12-19]()\n\n## Usage Examples\n\n### Natural Language Queries\n\nSimply ask your MCP host to perform searches:\n\n```\nSearch for \"AI\" discussions on Chinese social media from last week\n```\n\n```\nFind posts about deepseek on Weibo from January 1st to 5th\n```\n\n```\nSearch for chatgpt OR 机器学习 on all platforms, exclude 广告\n```\n\n### Code-Level Usage\n\n**First Page Request:**\n\n```json\n{\n  \"keyword\": \"AI\",\n  \"source\": \"ALL\",\n  \"start\": \"2025-01-01 00:00:00\",\n  \"end\": \"2025-01-02 23:59:59\"\n}\n```\n\n**Pagination Request:**\n\n```json\n{\n  \"keyword\": \"AI\",\n  \"nextCursor\": \"eyJsYXN0SWQiOiIxMjM0NTY3ODkwIn0=\"\n}\n```\n\n资料来源：[README.md:40-46]()\n\n## Response Format\n\nAll tools return raw JSON from upstream APIs without modification.\n\n### Success Response\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-12-31T14:55:21Z\",\n  \"data\": {\n    // Platform-specific data structure\n  }\n}\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `code` | integer | 0 indicates success, non-zero indicates error |\n| `message` | string/null | Error message if applicable |\n| `recordTime` | string | ISO timestamp of the response |\n| `data` | object | Platform-specific payload |\n\n### Error Response\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n资料来源：[README.md:60-75]()\n\n## Error Handling\n\nThe MCP normalizes all errors into stable MCP error codes.\n\n### Error Codes Reference\n\n| Error Code | Description | Recommended Action |\n|------------|-------------|-------------------|\n| `INVALID_TOKEN` | Token is invalid or inactive | Update `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | Data collection failed | Retry after a short delay |\n| `RATE_LIMITED` | Too many requests | Slow down and retry later |\n| `DAILY_QUOTA_EXCEEDED` | Daily usage limit reached | Wait until tomorrow or upgrade plan |\n| `INSUFFICIENT_BALANCE` | Account balance too low | Top up your account |\n| `PERMISSION_DENIED` | No access to this resource | Contact support |\n| `VALIDATION_ERROR` | Invalid request parameters | Check input values |\n| `INTERNAL_ERROR` | Server error | Retry later |\n| `NETWORK_TIMEOUT` | Request timed out | Check network or retry |\n| `NETWORK_ERROR` | Network connection failed | Check internet connection |\n| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |\n\n资料来源：[README.md:109-130]()\n\n### Error Format Example\n\n```\nERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\n```\n\n资料来源：[README.md:132-134]()\n\n## Pagination\n\nWhen search results have more pages, responses include a `nextCursor` field.\n\n### How to Paginate\n\nSimply ask for more results:\n\n- \"Show me the next page of results\"\n- \"Get more results from the previous search\"\n- \"Continue with the next page\"\n\nThe MCP host automatically:\n\n1. Extracts the `nextCursor` from the previous response\n2. Uses it to fetch the next page\n3. Continues until no more results are available\n\n**Note:** When using `nextCursor` for pagination, you don't need to provide `start`, `end`, or `source` again—the cursor already contains this information.\n\n资料来源：[README.md:76-95]()\n\n## Design Philosophy\n\n### Transport, Not Transformation\n\nJustOneAPI MCP prioritizes:\n\n- **Stability** — Minimal abstraction over upstream APIs\n- **Transparency** — Raw data fidelity without modification\n- **Compatibility** — Long-term compatibility through unchanged responses\n\n### What This MCP Does\n\n- Exposes JustOneAPI endpoints as MCP tools\n- Handles authentication, retries, timeouts, and error normalization\n- Returns raw upstream JSON without field parsing\n- Designed for AI agents and developer workflows\n\n### What This MCP Does NOT Do\n\n- No field parsing or schema normalization\n- No data restructuring\n- No assumptions about upstream response structure\n\n资料来源：[README.md:10-24]()\n\n## Advanced Configuration\n\n### Complete Configuration Example\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\",\n        \"JUSTONEAPI_TIMEOUT_MS\": \"30000\",\n        \"JUSTONEAPI_DEBUG\": \"true\"\n      }\n    }\n  }\n}\n```\n\n### Retry Behavior\n\nThe HTTP client implements automatic retry for:\n\n- Timeout errors (AbortError)\n- HTTP 5xx responses\n- Network failures (ECONNRESET, ECONNREFUSED, ENOTFOUND)\n\n| Attempt | Delay |\n|---------|-------|\n| 1 | Immediate |\n| 2 | 250ms backoff |\n| 3+ | 250ms × attempt |\n\n资料来源：[src/common/http.ts:30-40]()\n\n## Discovery and Verification\n\n### Listing Available Tools\n\n**In Claude Desktop:**\n\n```\nPlease list all available tools from justoneapi-mcp\n```\n\n**In Cursor or other MCP hosts:**\n\nUse your host's tool discovery feature to see all available tools and their parameters.\n\nEach tool includes:\n- Complete parameter descriptions\n- Input validation with Zod schemas\n- Detailed error messages\n- Example values in parameter descriptions\n\n资料来源：[README.md:30-38]()\n\n## Next Steps\n\nAfter setup:\n\n1. **Obtain an API token** from [justoneapi.com](https://dashboard.justoneapi.com/en/login)\n2. **Configure your MCP host** with the token\n3. **Try the unified search** with a simple query\n4. **Explore pagination** for large result sets\n5. **Review error codes** for troubleshooting\n\n## License\n\nMIT License\n\n资料来源：[README.md:152]()\n\n## External Resources\n\n- [JustOneAPI Dashboard](https://dashboard.justoneapi.com/en/login)\n- [JustOneAPI Official Site](https://justoneapi.com)\n- [npm Package](https://www.npmjs.com/package/justoneapi-mcp)\n- [GitHub Repository](https://github.com/justoneapi/justoneapi-mcp)\n\n---\n\n<a id='authentication'></a>\n\n## Authentication\n\n### 相关页面\n\n相关主题：[Getting Started with JustOneAPI MCP](#getting-started), [Configuration Reference](#configuration-reference)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)\n</details>\n\n# Authentication\n\n## Overview\n\nThe justoneapi-mcp server implements a token-based authentication mechanism for securing API access to the JustOneAPI platform. All requests to upstream APIs are authenticated using a bearer-style token passed via query parameters. The authentication system performs early validation at startup and before each API call to ensure credentials are present and properly configured.\n\nThe authentication layer serves as the gatekeeper for all MCP tools, including `unified_search_v1` and `kuaishou_search_video_v2`. It validates the token's presence, encodes it safely for transmission, and provides clear error messages when authentication fails.\n\n## Architecture\n\n```mermaid\ngraph TD\n    A[MCP Host Request] --> B{Token Present?}\n    B -->|No| C[Startup Validation<br/>src/index.ts:45-52]\n    B -->|Yes| D[requireToken Call]\n    \n    D --> E{Token Valid?}\n    E -->|Empty/Whitespace| F[INVALID_TOKEN Error]\n    E -->|Valid| G[Encode Token]\n    \n    G --> H[Append to Query Params]\n    H --> I[HTTP Request via getJson]\n    \n    I --> J{Response Code = 0?}\n    J -->|Yes| K[Return Data]\n    J -->|No| L[Error Mapping<br/>src/common/errors.ts]\n    \n    style F fill:#ffcccc\n    style K fill:#ccffcc\n```\n\n## Configuration\n\n### Environment Variables\n\nAuthentication is configured through environment variables in the MCP server configuration.\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | — | Your JustOneAPI authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint base URL |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after initial attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |\n\n### Token Configuration File\n\nThe token configuration is managed in `src/common/config.ts`.\n\n```typescript\n// src/common/config.ts:1-15\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN;\n  if (!token || !token.trim()) {\n    throw new Error(\n      \"JUSTONEAPI_TOKEN environment variable is required. \" +\n        \"Get your token at https://justoneapi.com\"\n    );\n  }\n  return token;\n}\n```\n\nThe `requireToken()` function validates that the token exists and is not empty or whitespace-only. If validation fails, it throws an error with instructions for obtaining a token. 资料来源：[src/common/config.ts:1-15]()\n\n### Startup Validation\n\nThe server performs authentication validation during startup to fail fast if credentials are missing.\n\n```typescript\n// src/index.ts:45-52\nasync function main() {\n  // Validate configuration on startup\n  if (!process.env.JUSTONEAPI_TOKEN?.trim()) {\n    console.error(\n      \"[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\\n\" +\n        \"Please set the JUSTONEAPI_TOKEN environment variable in your MCP host configuration\"\n    );\n    process.exit(1);\n  }\n  // ... continue with server initialization\n}\n```\n\n资料来源：[src/index.ts:45-52]()\n\n## Token Transmission\n\n### Query Parameter Encoding\n\nTokens are transmitted via URL query parameters for all API requests. The token is URL-encoded to handle special characters safely.\n\n```typescript\n// src/tools/search/unified_search_v1.ts:35-36\nexport async function unifiedSearchV1(input: z.infer<typeof UnifiedSearchV1Input>) {\n  const token = encodeURIComponent(requireToken());\n  const keyword = encodeURIComponent(input.keyword);\n  \n  // Build query parameters\n  const params = new URLSearchParams();\n  params.append(\"token\", token);\n  params.append(\"keyword\", keyword);\n  // ...\n}\n```\n\n资料来源：[src/tools/search/unified_search_v1.ts:35-36]()\n\n### HTTP Request Flow\n\nAll authenticated requests flow through the `getJson()` helper in `src/common/http.ts`.\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Host\n    participant Server as justoneapi-mcp\n    participant API as JustOneAPI\n    \n    MCP->>Server: Tool Request\n    Server->>Server: requireToken()\n    Note over Server: Validate token exists\n    Server->>Server: getJson(pathWithQuery)\n    Server->>API: GET with token in query\n    API-->>Server: JSON Response\n    Server->>Server: Check response.code\n    alt code != 0\n        Server->>Server: toMcpErrorPayload()\n    end\n    Server-->>MCP: Result or Error\n```\n\nThe `getJson()` function includes the following security and reliability features:\n\n| Feature | Implementation | Purpose |\n|---------|---------------|---------|\n| Early token validation | `requireToken()` at start | Fail fast on missing credentials |\n| Timeout handling | `AbortController` | Prevent hanging requests |\n| Automatic retry | Configurable via `JUSTONEAPI_RETRY` | Handle transient failures |\n| Safe logging | `toSafeUrlForLog()` | Mask tokens in debug output |\n\n```typescript\n// src/common/http.ts:40-55\nexport async function getJson(pathWithQuery: string): Promise<UpstreamResponse> {\n  // ensure token exists early (so we can return INVALID_TOKEN)\n  requireToken();\n\n  const url = `${config.baseUrl}${pathWithQuery}`;\n\n  const attempts = 1 + Math.max(0, Number.isFinite(config.retry) ? config.retry : 0);\n  let lastErr: ApiError | unknown;\n\n  for (let attempt = 1; attempt <= attempts; attempt++) {\n    const controller = new AbortController();\n    const timer = setTimeout(() => controller.abort(), config.timeoutMs);\n    // ...\n  }\n}\n```\n\n资料来源：[src/common/http.ts:40-55]()\n\n## Error Handling\n\n### Token-Related Error Codes\n\nWhen authentication fails, the server returns normalized MCP error codes.\n\n| Error Code | Upstream Equivalent | Description | Resolution |\n|------------|---------------------|-------------|------------|\n| `INVALID_TOKEN` | — | Token missing or invalid | Update `JUSTONEAPI_TOKEN` |\n| `RATE_LIMITED` | 302 | Too many requests | Slow down and retry |\n| `DAILY_QUOTA_EXCEEDED` | — | Usage limit reached | Wait or upgrade plan |\n| `INSUFFICIENT_BALANCE` | — | Account balance low | Top up account |\n\n### Error Mapping\n\nThe `mapUpstreamCode()` function in `src/common/errors.ts` maps upstream error codes to MCP error codes.\n\n```typescript\n// src/common/errors.ts:1-30\nfunction mapUpstreamCode(code: number): JOAErrorCode {\n  switch (code) {\n    case 10001:\n      return \"INVALID_TOKEN\";\n    case 10002:\n      return \"INSUFFICIENT_BALANCE\";\n    case 10003:\n      return \"PERMISSION_DENIED\";\n    // ... other mappings\n    default:\n      return \"UPSTREAM_ERROR\";\n  }\n}\n```\n\n资料来源：[src/common/errors.ts:1-30]()\n\n### Error Payload Construction\n\n```typescript\n// src/common/errors.ts:60-75\nexport function toMcpErrorPayload(e: unknown): {\n  code: JOAErrorCode;\n  message: string;\n  upstreamCode?: number;\n  httpStatus?: number;\n} {\n  const error = e as {\n    name?: string;\n    message?: string;\n    upstreamCode?: number;\n    httpStatus?: number;\n    code?: string;\n    cause?: unknown;\n  };\n  \n  // Timeout from AbortController\n  if (error.name === \"AbortError\") {\n    return { code: \"NETWORK_TIMEOUT\", message: buildUserMessage(\"NETWORK_TIMEOUT\") };\n  }\n\n  // Our own thrown upstreamCode (business code)\n  if (error.upstreamCode !== undefined) {\n    const upstreamCode = Number(error.upstreamCode);\n    const mcpCode = mapUpstreamCode(upstreamCode);\n    return {\n      code: mcpCode,\n      message: buildUserMessage(mcpCode, error.message),\n      upstreamCode,\n      httpStatus: typeof error.httpStatus === \"number\" ? error.httpStatus : undefined,\n    };\n  }\n  // ...\n}\n```\n\n资料来源：[src/common/errors.ts:60-75]()\n\n### Error Response Format\n\nAll errors are returned in a standardized format:\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\nExample error responses:\n\n| Scenario | Response Format |\n|----------|-----------------|\n| Invalid token | `ERROR[INVALID_TOKEN] (upstream=N/A): Token is invalid or inactive. Update your JUSTONEAPI_TOKEN` |\n| Rate limited | `ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.` |\n| Network timeout | `ERROR[NETWORK_TIMEOUT] (upstream=N/A): Request timed out. Check network or retry.` |\n\n## Security Considerations\n\n### Token Masking in Logs\n\nDebug logging masks tokens to prevent accidental exposure.\n\n```typescript\n// src/common/config.ts:50-65\nexport function toSafeUrlForLog(fullUrl: string): string {\n  try {\n    const u = new URL(fullUrl);\n    if (u.searchParams.has(\"token\")) {\n      u.searchParams.set(\"token\", maskToken(u.searchParams.get(\"token\") ?? \"\"));\n    }\n    return u.toString();\n  } catch {\n    // Fallback: best-effort masking\n    return fullUrl.replace(/token=([^&]+)/g, (_m, g1) => `token=${maskToken(g1)}`);\n  }\n}\n```\n\n资料来源：[src/common/config.ts:50-65]()\n\n### Retry Behavior with Tokens\n\nRetry logic applies only to transient failures, not authentication errors:\n\n```typescript\n// src/common/http.ts:70-80\nconst retryable =\n  error.name === \"AbortError\" ||\n  (typeof httpStatus === \"number\" && httpStatus >= 500) ||\n  error.code === \"ECONNRESET\" ||\n  error.code === \"ECONNREFUSED\" ||\n  error.code === \"ENOTFOUND\";\n```\n\n| Retryable | Not Retryable |\n|-----------|---------------|\n| Timeout (`AbortError`) | HTTP 4xx errors |\n| HTTP 5xx errors | Business code != 0 |\n| Network reset | Invalid token |\n\n## Configuration Examples\n\n### Claude Desktop Configuration\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_actual_token_here\"\n      }\n    }\n  }\n}\n```\n\n### Custom Timeout and Debug Settings\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_actual_token_here\",\n        \"JUSTONEAPI_TIMEOUT_MS\": \"30000\",\n        \"JUSTONEAPI_DEBUG\": \"true\"\n      }\n    }\n  }\n}\n```\n\nWhen debug mode is enabled, logs appear with masked tokens:\n\n```\n[justoneapi] GET https://api.justoneapi.com/api/search/v1?token=sk_***&keyword=AI (attempt 1/2)\n```\n\n## Obtaining a Token\n\n1. Visit [https://justoneapi.com](https://justoneapi.com)\n2. Create an account or sign in at [https://dashboard.justoneapi.com](https://dashboard.justoneapi.com/en/login)\n3. Generate an API token from your dashboard\n4. Configure the token in your MCP host\n\n## Related Documentation\n\n- [README.md](README.md) — Installation and quick start guide\n- [TOOLS.md](TOOLS.md) — Complete tool reference with authentication parameters\n\n---\n\n<a id='system-architecture'></a>\n\n## System Architecture\n\n### 相关页面\n\n相关主题：[HTTP Client Implementation](#http-client), [Unified Search Tool](#unified-search-tool), [Kuaishou Video Search Tool](#kuaishou-video-search)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)\n- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n</details>\n\n# System Architecture\n\n## Overview\n\nThe justoneapi-mcp is a Model Context Protocol (MCP) server that provides a bridge between AI assistants and the JustOneAPI social media search platform. The system enables natural language querying across multiple Chinese social media platforms including Weibo, WeChat, Zhihu, Douyin, Xiaohongshu, Bilibili, Kuaishou, and news sources.\n\nThe architecture follows a **transport-oriented design philosophy**, prioritizing stability, transparency, and raw data fidelity over convenience. The MCP server returns unmodified upstream API responses to ensure maximum data fidelity and long-term compatibility.\n\n## High-Level Architecture\n\n```mermaid\ngraph TD\n    subgraph \"MCP Host Environment\"\n        A[MCP Client<br/>Claude Desktop/Cursor]\n    end\n    \n    subgraph \"justoneapi-mcp Server\"\n        B[MCP SDK Server]\n        C[Tool Handlers]\n        D[Common Libraries]\n        E[HTTP Client]\n    end\n    \n    subgraph \"External Services\"\n        F[JustOneAPI<br/>api.justoneapi.com]\n        G[Chinese Social Media<br/>Platforms]\n    end\n    \n    A -->|MCP Protocol| B\n    B --> C\n    C --> D\n    D --> E\n    E -->|HTTPS| F\n    F -->|API Responses| G\n    \n    style A fill:#e1f5fe\n    style F fill:#fff3e0\n    style G fill:#f3e5f5\n```\n\n## Core Components\n\n### Component Overview\n\n| Component | File Location | Purpose |\n|-----------|---------------|---------|\n| MCP Server | `src/index.ts` | Entry point, tool registration, request routing |\n| Tool Handlers | `src/tools/*` | Individual tool implementations |\n| HTTP Client | `src/common/http.ts` | HTTP request management with retry logic |\n| Configuration | `src/common/config.ts` | Token management, URL sanitization |\n| Error Handling | `src/common/errors.ts` | Error code mapping and payload transformation |\n\n### Module Dependency Graph\n\n```mermaid\ngraph LR\n    subgraph \"Entry Point\"\n        A[src/index.ts]\n    end\n    \n    subgraph \"Tool Layer\"\n        B[unified_search_v1.ts]\n        C[kuaishou_search_video_v2.ts]\n    end\n    \n    subgraph \"Common Layer\"\n        D[config.ts]\n        E[http.ts]\n        F[errors.ts]\n    end\n    \n    subgraph \"External\"\n        G[JustOneAPI]\n    end\n    \n    A --> B\n    A --> C\n    B --> D\n    B --> E\n    B --> F\n    C --> D\n    C --> E\n    C --> F\n    E --> F\n    E --> G\n    \n    style A fill:#ffecb3\n    style D fill:#c8e6c9\n    style E fill:#c8e6c9\n    style F fill:#c8e6c9\n    style G fill:#fff3e0\n```\n\n## Tool Registration System\n\n### Request Flow\n\n```mermaid\nsequenceDiagram\n    participant Client as MCP Client\n    participant Server as MCP Server\n    participant Handler as Tool Handler\n    participant HTTP as HTTP Client\n    participant API as JustOneAPI\n    \n    Client->>Server: Tool Request (unified_search_v1)\n    Server->>Handler: Forward Input\n    Handler->>Handler: Validate with Zod Schema\n    Handler->>HTTP: GET /api/search/v1\n    HTTP->>HTTP: Token encoding\n    HTTP->>API: Request with token\n    API-->>HTTP: JSON Response\n    HTTP-->>Handler: Raw JSON\n    Handler-->>Server: JSON Response\n    Server-->>Client: MCP Response\n```\n\n### Tool Registration Pattern\n\nTools are registered in `src/index.ts` using the MCP SDK's `registerTool` method. Each tool registration includes:\n\n1. **Tool name** - Unique identifier following `{platform}_{action}_{version}` pattern\n2. **Input schema** - Zod schema for parameter validation\n3. **Handler function** - Async function that processes requests\n\n```typescript\n// Registration pattern from src/index.ts:55-72\nserver.registerTool(\n  \"unified_search_v1\",\n  {\n    description: \"Unified search across multiple platforms...\",\n    inputSchema: UnifiedSearchV1Input.shape,\n  },\n  async (input) => {\n    try {\n      const data = await unifiedSearchV1(input);\n      return {\n        content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n      };\n    } catch (e: unknown) {\n      const m = toMcpErrorPayload(e);\n      return {\n        isError: true,\n        content: [{ type: \"text\", text: `ERROR[${m.code}]: ${m.message}` }],\n      };\n    }\n  }\n);\n```\n\n## HTTP Client Architecture\n\n### Retry Strategy\n\nThe HTTP client in `src/common/http.ts` implements an intelligent retry mechanism with exponential backoff.\n\n```mermaid\ngraph TD\n    A[Request] --> B{Attempt < Max?}\n    B -->|Yes| C{Check Retryable?}\n    C -->|AbortError| D[Retry]\n    C -->|HTTP 5xx| D\n    C -->|ECONNRESET| D\n    C -->|ECONNREFUSED| D\n    C -->|ENOTFOUND| D\n    C -->|No| E[Throw Error]\n    D --> F[Wait 250ms × Attempt]\n    F --> G[Retry Request]\n    G --> B\n    B -->|No| H[Throw Last Error]\n    \n    style E fill:#ffcdd2\n    style H fill:#ffcdd2\n    style D fill:#c8e6c9\n```\n\n### Retryable Conditions\n\n| Condition | Type | Retry Behavior |\n|-----------|------|----------------|\n| `AbortError` | Timeout | ✅ Retry |\n| HTTP 5xx | Server Error | ✅ Retry |\n| `ECONNRESET` | Connection Reset | ✅ Retry |\n| `ECONNREFUSED` | Connection Refused | ✅ Retry |\n| `ENOTFOUND` | DNS Lookup Failed | ✅ Retry |\n| HTTP 4xx | Client Error | ❌ No Retry |\n| Business Errors | API Code | ❌ No Retry |\n\n资料来源：[src/common/http.ts:29-36]()\n\n## Error Handling System\n\n### Error Flow\n\n```mermaid\ngraph TD\n    A[Exception Thrown] --> B{Error Type?}\n    B -->|AbortError| C[NETWORK_TIMEOUT]\n    B -->|upstreamCode exists| D[Map Upstream Code]\n    B -->|httpStatus exists| E[UPSTREAM_ERROR]\n    B -->|cause or network code| F[NETWORK_ERROR]\n    B -->|Unknown| G[UPSTREAM_ERROR]\n    \n    D --> H[Return MCP Error Payload]\n    C --> H\n    E --> H\n    F --> H\n    G --> H\n    \n    style C fill:#fff9c4\n    style D fill:#fff9c4\n    style E fill:#fff9c4\n    style F fill:#fff9c4\n```\n\n### Error Code Mapping\n\n| MCP Error Code | Upstream Code | Description | User Action |\n|----------------|---------------|-------------|-------------|\n| `INVALID_TOKEN` | N/A | Token invalid/inactive | Update `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | N/A | Data collection failed | Retry after delay |\n| `RATE_LIMITED` | 302 | Too many requests | Slow down, retry later |\n| `DAILY_QUOTA_EXCEEDED` | N/A | Daily limit reached | Wait until tomorrow |\n| `INSUFFICIENT_BALANCE` | N/A | Low account balance | Top up account |\n| `PERMISSION_DENIED` | N/A | No access to resource | Contact support |\n| `VALIDATION_ERROR` | N/A | Invalid parameters | Check input values |\n| `INTERNAL_ERROR` | N/A | Server error | Retry later |\n| `NETWORK_TIMEOUT` | N/A | Request timed out | Check network |\n| `NETWORK_ERROR` | N/A | Connection failed | Check internet |\n| `UPSTREAM_ERROR` | N/A | Unspecified upstream | Retry or contact support |\n\n## Configuration Management\n\n### Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | ✅ Yes | - | API authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint base URL |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after first attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |\n\n### Token Management\n\nThe `requireToken()` function in `src/common/config.ts` validates and retrieves the API token:\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN?.trim();\n  if (!token) {\n    throw new Error(\"JUSTONEAPI_TOKEN environment variable is required\");\n  }\n  return token;\n}\n```\n\n### URL Sanitization for Logging\n\nThe `toSafeUrlForLog()` function masks sensitive tokens in URLs before logging:\n\n```mermaid\ngraph LR\n    A[Full URL with token] --> B[Parse URL]\n    B --> C{Token param exists?}\n    C -->|Yes| D[Mask token value]\n    C -->|No| E[Return original]\n    D --> F[Return sanitized URL]\n    E --> F\n```\n\n## Tool Specifications\n\n### Available Tools\n\n| Tool Name | Purpose | Version |\n|-----------|---------|---------|\n| `unified_search_v1` | Multi-platform social media search | v1 |\n| `kuaishou_search_video_v2` | Kuaishou-specific video search | v2 |\n\n### Platform Support\n\nThe unified search supports the following platforms:\n\n| Platform | Identifier | Type |\n|----------|------------|------|\n| All Platforms | `ALL` | Default |\n| News | `NEWS` | News content |\n| Weibo | `WEIBO` | Social posts |\n| WeChat | `WEIXIN` | Articles |\n| Zhihu | `ZHIHU` | Q&A content |\n| Douyin | `DOUYIN` | Short videos |\n| Xiaohongshu | `XIAOHONGSHU` | Lifestyle content |\n| Bilibili | `BILIBILI` | Long-form videos |\n| Kuaishou | `KUAISHOU` | Short videos |\n\n### Search Syntax Support\n\n| Operator | Syntax | Description |\n|----------|--------|-------------|\n| Single keyword | `deepseek` | Basic search |\n| AND search | `deepseek chatgpt` | Both keywords required |\n| OR search | `deepseek~chatgpt` | Either keyword matches |\n| NOT search | `deepseek -chatgpt` | Exclude keyword |\n\n## Data Flow Architecture\n\n### Unified Search Flow\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant Handler as unified_search_v1\n    participant HTTP as getJson\n    participant API as JustOneAPI\n    \n    User->>Handler: {keyword, source, start, end}\n    Handler->>Handler: Encode parameters\n    Handler->>HTTP: GET /api/search/v1?token=...&keyword=...\n    HTTP->>API: HTTPS Request\n    API-->>HTTP: {code, message, data, nextCursor}\n    HTTP-->>Handler: Raw JSON response\n    Handler-->>User: JSON with raw data\n    \n    Note over User,API: Raw upstream data returned unchanged\n```\n\n## Technology Stack\n\n### Production Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `@modelcontextprotocol/sdk` | ^1.25.1 | MCP protocol implementation |\n| `zod` | ^4.3.4 | Schema validation |\n| `dotenv` | ^17.2.3 | Environment variable loading |\n\n### Development Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `typescript` | ^5.9.3 | Type safety |\n| `eslint` | ^9.39.2 | Code linting |\n| `prettier` | ^3.7.4 | Code formatting |\n| `ts-node` | ^10.9.2 | TypeScript execution |\n\n### Node.js Requirement\n\n- **Minimum version**: Node.js 18.0.0\n- **Runtime**: ES2022+ module system\n\n## Startup and Initialization\n\n### Configuration Validation\n\nOn server startup, the main function validates that required configuration exists:\n\n```mermaid\ngraph TD\n    A[Server Start] --> B{JUSTONEAPI_TOKEN set?}\n    B -->|No| C[Exit with Error]\n    B -->|Yes| D[Start MCP Server]\n    D --> E[Register Tools]\n    E --> F[Listen for Requests]\n    \n    style C fill:#ffcdd2\n    style F fill:#c8e6c9\n```\n\nThe token validation occurs in `src/index.ts` before the MCP server begins accepting connections, ensuring early failure with clear error messages.\n\n## Design Philosophy\n\nThe architecture embodies the **\"Transport, not transformation\"** principle:\n\n1. **Maximum Data Fidelity** - Raw upstream responses are returned unmodified\n2. **No Field Parsing** - Data structures remain as received from upstream APIs\n3. **No Data Restructuring** - No normalization or transformation of response formats\n4. **Long-term Compatibility** - Stable interface despite upstream API changes\n\n---\n\n<a id='http-client'></a>\n\n## HTTP Client Implementation\n\n### 相关页面\n\n相关主题：[System Architecture](#system-architecture), [Error Handling](#error-handling), [Configuration Reference](#configuration-reference)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n</details>\n\n# HTTP Client Implementation\n\n## Overview\n\nThe HTTP Client Implementation provides a centralized, reusable HTTP communication layer for the JustOneAPI MCP server. It handles all outbound API requests with built-in retry logic, timeout management, error normalization, and secure logging. The implementation follows a \"transport, not transformation\" philosophy, returning raw upstream responses to maintain maximum data fidelity.\n\n**Key Responsibilities:**\n- Execute HTTP GET requests to the JustOneAPI backend\n- Manage request timeouts using AbortController\n- Implement automatic retry with exponential backoff for transient failures\n- Normalize errors into structured MCP error codes\n- Ensure secure logging by masking sensitive tokens\n\n资料来源：[src/common/http.ts:48-68]()\n\n## Architecture\n\n```mermaid\ngraph TD\n    A[Tool Handler] --> B[API Function<br/>e.g., unifiedSearchV1]\n    B --> C[getJson]\n    C --> D{Token Validation}\n    D -->|Invalid| E[INVALID_TOKEN Error]\n    D -->|Valid| F[Build URL]\n    F --> G[Fetch with Timeout]\n    G --> H{Response OK?}\n    H -->|No| I[Retry Logic]\n    I --> G\n    H -->|Yes| J[Parse JSON]\n    J --> K[Business Code OK?]\n    K -->|No| L[Error Mapping]\n    K -->|Yes| M[Return Response]\n    L --> N[MCP Error Payload]\n    \n    style E fill:#ff6b6b\n    style N fill:#ffa500\n    style M fill:#51cf66\n```\n\n### Request Flow\n\n1. **Token Validation** - Ensures `JUSTONEAPI_TOKEN` exists before making requests 资料来源：[src/common/http.ts:60]() [src/common/config.ts]()\n\n2. **URL Construction** - Builds full URL with base URL and query parameters 资料来源：[src/common/http.ts:62]()\n\n3. **Fetch Execution** - Makes HTTP request with AbortController timeout 资料来源：[src/common/http.ts:70-76]()\n\n4. **Response Processing** - Validates HTTP status and parses JSON 资料来源：[src/common/http.ts:78-88]()\n\n5. **Business Logic Check** - Validates upstream `code === 0` for success 资料来源：[src/common/errors.ts:1-18]()\n\n## Core Components\n\n### ApiError Type\n\nThe `ApiError` interface extends the standard `Error` type with additional properties for HTTP-level and business-level error information.\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `httpStatus` | `number \\| undefined` | HTTP status code from the fetch response |\n| `upstreamCode` | `number \\| undefined` | Business error code from upstream API response |\n| `payload` | `unknown \\| undefined` | Full response payload when available |\n| `code` | `string \\| undefined` | Node.js error code for network errors |\n| `cause` | `unknown \\| undefined` | Underlying error cause |\n\n资料来源：[src/common/http.ts:39-45]()\n\n### getJson Function\n\nThe main HTTP client function that performs GET requests with comprehensive error handling.\n\n```typescript\nexport async function getJson(pathWithQuery: string): Promise<UpstreamResponse>\n```\n\n**Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `pathWithQuery` | `string` | API endpoint path including query string |\n\n**Returns:** `Promise<UpstreamResponse>` - Parsed JSON response from the API\n\n**Behavior:**\n- Validates token presence before any network call\n- Supports configurable retry attempts (default: 1 retry after initial attempt)\n- Implements 250ms backoff between retries\n- Returns raw upstream JSON without transformation\n\n资料来源：[src/common/http.ts:48-68]()\n\n## Retry Logic\n\nThe HTTP client implements intelligent retry behavior for transient failures.\n\n### Retry Conditions\n\n| Condition | Retryable | Description |\n|-----------|-----------|-------------|\n| `AbortError` | Yes | Request timeout |\n| HTTP 5xx | Yes | Server-side errors |\n| `ECONNRESET` | Yes | Connection reset by peer |\n| `ECONNREFUSED` | Yes | Connection refused |\n| `ENOTFOUND` | Yes | DNS lookup failure |\n| HTTP 4xx | No | Client errors |\n| Business code != 0 | No | Application-level errors |\n\n```mermaid\ngraph LR\n    A[Request Attempt] --> B{Error Type?}\n    B -->|AbortError| C[Retry]\n    B -->|5xx| C\n    B -->|Network Error| C\n    B -->|4xx| D[No Retry]\n    B -->|Business Error| D\n    C --> E{Attempts<br/>Exhausted?}\n    E -->|No| A\n    E -->|Yes| F[Throw Error]\n    D --> F\n```\n\n**Retry Configuration:**\n- Maximum attempts: `1 + JUSTONEAPI_RETRY` (default: 2 total attempts)\n- Backoff delay: `250ms * attempt_number`\n\n资料来源：[src/common/http.ts:68-96]()\n\n## Timeout Management\n\nTimeouts are implemented using the AbortController API for native browser/Node.js compatibility.\n\n| Setting | Environment Variable | Default | Description |\n|---------|---------------------|---------|-------------|\n| Request Timeout | `JUSTONEAPI_TIMEOUT_MS` | `20000` | Timeout in milliseconds |\n\n**Implementation:**\n\n```typescript\nconst controller = new AbortController();\nconst timer = setTimeout(() => controller.abort(), config.timeoutMs);\n\nconst res = await fetch(url, { method: \"GET\", signal: controller.signal });\n// ... process response ...\nclearTimeout(timer); // Clean up timer\n```\n\nWhen a timeout occurs, an `AbortError` is thrown, which triggers the retry logic.\n\n资料来源：[src/common/http.ts:70-76]()\n\n## Error Handling\n\n### Error Code Mapping\n\nThe system maps upstream error codes to standardized MCP error codes.\n\n| Upstream Code | MCP Code | Description |\n|---------------|----------|-------------|\n| 301 | `INVALID_TOKEN` | Token is invalid or inactive |\n| 302 | `INVALID_TOKEN` | Token validation failed |\n| 401 | `INVALID_TOKEN` | Authentication required |\n| 402 | `INSUFFICIENT_BALANCE` | Account balance too low |\n| 403 | `PERMISSION_DENIED` | No access to resource |\n| 404 | `PERMISSION_DENIED` | Resource not found |\n| 422 | `VALIDATION_ERROR` | Invalid request parameters |\n| 429 | `RATE_LIMITED` | Too many requests |\n| 500 | `INTERNAL_ERROR` | Server error |\n| 503 | `UPSTREAM_ERROR` | Service unavailable |\n\n资料来源：[src/common/errors.ts:19-53]()\n\n### Error Payload Structure\n\nWhen an error occurs, the `toMcpErrorPayload` function converts the error to a structured format.\n\n```typescript\n{\n  code: JOAErrorCode;      // Normalized MCP error code\n  message: string;         // Human-readable message\n  upstreamCode?: number;  // Original upstream error code\n  httpStatus?: number;     // HTTP status code\n}\n```\n\n**Error Priority:**\n1. `AbortError` → `NETWORK_TIMEOUT`\n2. `upstreamCode` present → Maps to appropriate MCP code\n3. `httpStatus` present → `UPSTREAM_ERROR`\n4. `cause` or network error code → `NETWORK_ERROR`\n5. Fallback → `UPSTREAM_ERROR`\n\n资料来源：[src/common/errors.ts:55-91]()\n\n## Security Features\n\n### Token Masking\n\nAll API tokens are masked in logs to prevent credential leakage.\n\n```typescript\nexport function toSafeUrlForLog(fullUrl: string): string {\n  try {\n    const u = new URL(fullUrl);\n    if (u.searchParams.has(\"token\")) {\n      u.searchParams.set(\"token\", maskToken(u.searchParams.get(\"token\") ?? \"\"));\n    }\n    return u.toString();\n  } catch {\n    // Fallback: best-effort masking\n    return fullUrl.replace(/token=([^&]+)/g, (_m, g1) => `token=${maskToken(g1)}`);\n  }\n}\n```\n\n**Features:**\n- Primary method uses URL API for accurate parsing\n- Fallback regex for non-standard URLs\n- Two-level fallback to prevent logging failures\n\n资料来源：[src/common/config.ts:58-74]()\n\n### Debug Logging\n\nWhen `JUSTONEAPI_DEBUG=true`, requests are logged to stderr with masked tokens:\n\n```\n[justoneapi] GET https://api.justoneapi.com/api/search/v1?token=***&keyword=AI (attempt 1/2)\n```\n\n资料来源：[src/common/http.ts:72-74]()\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | - | API authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint base URL |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after initial attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging |\n\n资料来源：[README.md:103-110]()\n\n## Usage Examples\n\n### Basic Tool Implementation\n\nTools in this MCP server use the HTTP client through dedicated API functions:\n\n```typescript\n// From unified_search_v1.ts\nexport async function unifiedSearchV1(input: z.infer<typeof UnifiedSearchV1Input>) {\n  const token = encodeURIComponent(requireToken());\n  const keyword = encodeURIComponent(input.keyword);\n\n  const params = new URLSearchParams();\n  params.append(\"token\", token);\n  params.append(\"keyword\", keyword);\n\n  if (input.source) {\n    params.append(\"source\", input.source);\n  }\n\n  if (input.nextCursor) {\n    params.append(\"nextCursor\", input.nextCursor);\n  } else {\n    params.append(\"start\", input.start);\n    params.append(\"end\", input.end);\n  }\n\n  return await getJson(`/api/search/v1?${params.toString()}`);\n}\n```\n\n资料来源：[src/tools/search/unified_search_v1.ts:29-54]()\n\n### Error Response Format\n\nAll errors are returned in a consistent MCP format:\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n**Example:**\n```\nERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\n```\n\n资料来源：[README.md:86-89]()\n\n## Integration with MCP Server\n\nThe HTTP client is integrated into the MCP server's tool registration system:\n\n```typescript\nserver.registerTool(\n  \"unified_search_v1\",\n  {\n    description: \"Unified search across multiple platforms...\",\n    inputSchema: UnifiedSearchV1Input.shape,\n  },\n  async (input) => {\n    try {\n      const data = await unifiedSearchV1(input);\n      return {\n        content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n      };\n    } catch (e: unknown) {\n      const m = toMcpErrorPayload(e);\n      return {\n        isError: true,\n        content: [\n          {\n            type: \"text\",\n            text: `ERROR[${m.code}] (upstream=${m.upstreamCode ?? \"N/A\"}): ${m.message}`,\n          },\n        ],\n      };\n    }\n  }\n);\n```\n\n资料来源：[src/index.ts:50-70]()\n\n## Dependencies\n\nThe HTTP client implementation uses the following dependencies:\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `@modelcontextprotocol/sdk` | `^1.25.1` | MCP server framework |\n| `zod` | `^4.3.4` | Schema validation |\n| `dotenv` | `^17.2.3` | Environment variable loading |\n\n资料来源：[package.json:16-23]()\n\n---\n\n<a id='unified-search-tool'></a>\n\n## Unified Search Tool\n\n### 相关页面\n\n相关主题：[Kuaishou Video Search Tool](#kuaishou-video-search), [Tool Naming Conventions and Standards](#tool-conventions), [Error Handling](#error-handling)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n</details>\n\n# Unified Search Tool\n\n## Overview\n\nThe Unified Search Tool (`unified_search_v1`) is the primary MCP (Model Context Protocol) tool provided by justoneapi-mcp. It enables aggregated searching across multiple Chinese social media platforms and news sources through a single API interface.\n\n**Key Characteristics:**\n- Searches 8 platforms simultaneously in one request\n- Returns raw, unmodified JSON from upstream APIs\n- Supports advanced search syntax (AND, OR, NOT operators)\n- Implements cursor-based pagination\n- UTC+8 timezone for all date/time operations\n\n资料来源：[TOOLS.md:43-60]()\n\n## Architecture\n\n### System Context\n\n```mermaid\ngraph TD\n    subgraph \"MCP Host\"\n        A[Claude / Cursor]\n    end\n    \n    subgraph \"justoneapi-mcp\"\n        B[Server Entry<br/>src/index.ts]\n        C[Tool Handler<br/>unified_search_v1]\n        D[HTTP Client<br/>src/common/http.ts]\n        E[Error Handler<br/>src/common/errors.ts]\n    end\n    \n    subgraph \"External\"\n        F[JustOneAPI<br/>api.justoneapi.com]\n    end\n    \n    A -->|MCP Protocol| B\n    B --> C\n    C --> D\n    D -->|GET /api/search/v1| F\n    F -->|JSON Response| D\n    D --> E\n    \n    style F fill:#f9f,stroke:#333\n    style D fill:#bbf,stroke:#333\n    style E fill:#fbb,stroke:#333\n```\n\n### Request Flow\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Host\n    participant Server as justoneapi-mcp\n    participant HTTP as HTTP Client\n    participant API as JustOneAPI\n    \n    MCP->>Server: unified_search_v1(params)\n    Server->>HTTP: getJson(endpoint, params)\n    \n    loop Retry Logic (max 2 attempts)\n        HTTP->>API: GET /api/search/v1\n        API-->>HTTP: JSON Response\n        \n        alt Success (code=0)\n            HTTP-->>Server: data\n        else Retryable Error (5xx, timeout)\n            HTTP->>HTTP: Wait 250ms * attempt\n        end\n    end\n    \n    alt Non-retryable Error\n        Server->>Server: toMcpErrorPayload(e)\n        Server-->>MCP: ERROR[...]\n    else Success\n        Server-->>MCP: Raw JSON response\n    end\n```\n\n资料来源：[src/index.ts:29-47]()\n资料来源：[src/common/http.ts:1-44]()\n\n## Parameters\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `keyword` | string | Yes | Search keyword with advanced syntax support |\n| `source` | string | No | Platform filter (default: `ALL`) |\n| `start` | string | Conditional | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `end` | string | Conditional | End time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `nextCursor` | string | No | Pagination cursor from previous response |\n\n**Note:** `start` and `end` are required for the first page request. They must be omitted when using `nextCursor` for pagination.\n\n资料来源：[src/tools/search/unified_search_v1.ts:16-41]()\n\n## Supported Platforms\n\n| Platform ID | Description |\n|-------------|-------------|\n| `ALL` | Search all platforms (default) |\n| `NEWS` | News articles |\n| `WEIBO` | Sina Weibo |\n| `WEIXIN` | WeChat public accounts |\n| `ZHIHU` | Zhihu Q&A |\n| `DOUYIN` | Douyin (TikTok China) |\n| `XIAOHONGSHU` | Xiaohongshu (Little Red Book) |\n| `BILIBILI` | Bilibili video platform |\n| `KUAISHOU` | Kuaishou short video |\n\n资料来源：[src/tools/search/unified_search_v1.ts:9-16]()\n\n## Search Syntax\n\nThe unified search supports advanced query operators:\n\n| Operator | Syntax | Example | Description |\n|----------|--------|---------|-------------|\n| Single keyword | `word` | `deepseek` | Search for exact term |\n| AND (implicit) | `word1 word2` | `deepseek chatgpt` | Both terms must appear |\n| OR | `word1~word2` | `deepseek~chatgpt` | Either term may appear |\n| NOT | `word -exclude` | `deepseek -chatgpt` | Exclude term from results |\n\n**Syntax Rules:**\n- Single keyword: Plain text match\n- AND operator: Space-separated terms (implicit)\n- OR operator: Tilde (`~`) separator\n- NOT operator: Dash (`-`) prefix on exclusion term\n\n资料来源：[TOOLS.md:62-69]()\n\n## Pagination\n\n### Cursor-Based Pagination\n\n```mermaid\ngraph LR\n    A[First Request<br/>start, end] --> B[Response<br/>data + nextCursor]\n    B --> C{Next Page?}\n    C -->|Yes| D[Next Request<br/>nextCursor]\n    D --> E[Response<br/>data + nextCursor]\n    E --> C\n    C -->|No| F[Done]\n```\n\n### Pagination Rules\n\n1. **First Request:** Include `start` and `end` time parameters\n2. **Subsequent Requests:** Use `nextCursor` instead of time parameters\n3. **Final Page:** Response without `nextCursor` indicates completion\n\nWhen `nextCursor` is provided, `start`, `end`, and `source` parameters should be omitted—the cursor contains all necessary pagination context.\n\n资料来源：[TOOLS.md:32-42]()\n\n## Response Format\n\n### Success Response\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-01-02T14:55:21Z\",\n  \"data\": {\n    // Platform-specific data structure\n  }\n}\n```\n\n### Error Response\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n| Error Code | Description | Recovery Action |\n|------------|-------------|-----------------|\n| `INVALID_TOKEN` | Token invalid or inactive | Update `JUSTONEAPI_TOKEN` |\n| `RATE_LIMITED` | Too many requests | Slow down and retry |\n| `DAILY_QUOTA_EXCEEDED` | Daily limit reached | Wait or upgrade plan |\n| `INSUFFICIENT_BALANCE` | Low account balance | Top up account |\n| `VALIDATION_ERROR` | Invalid parameters | Check input values |\n| `NETWORK_TIMEOUT` | Request timed out | Check network/retry |\n| `NETWORK_ERROR` | Connection failed | Check internet |\n| `UPSTREAM_ERROR` | Server error | Retry or contact support |\n\n资料来源：[src/common/errors.ts:1-72]()\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | — | API authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout (ms) |\n| `JUSTONEAPI_RETRY` | No | `1` | Retry attempts |\n| `JUSTONEAPI_DEBUG` | No | `false` | Debug logging |\n\n### MCP Server Configuration\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\"\n      }\n    }\n  }\n}\n```\n\n## Usage Examples\n\n### Basic Multi-Platform Search\n\n```\nSearch for \"AI\" discussions on all platforms from January 1-5, 2025\n```\n\n**Generated Parameters:**\n```json\n{\n  \"keyword\": \"AI\",\n  \"source\": \"ALL\",\n  \"start\": \"2025-01-01 00:00:00\",\n  \"end\": \"2025-01-05 23:59:59\"\n}\n```\n\n### Platform-Specific Search\n\n```\nSearch for \"chatgpt\" on Weibo only, from December 1st to January 2nd\n```\n\n**Generated Parameters:**\n```json\n{\n  \"keyword\": \"chatgpt\",\n  \"source\": \"WEIBO\",\n  \"start\": \"2024-12-01 00:00:00\",\n  \"end\": \"2025-01-02 23:59:59\"\n}\n```\n\n### Complex Query with OR and NOT\n\n```\nSearch for posts containing \"deepseek\" OR \"机器学习\" but NOT \"广告\"\n```\n\n**Generated Parameters:**\n```json\n{\n  \"keyword\": \"deepseek~机器学习 -广告\",\n  \"source\": \"ZHIHU\",\n  \"start\": \"2025-01-01 00:00:00\",\n  \"end\": \"2025-01-31 23:59:59\"\n}\n```\n\n### Pagination Request\n\nWhen continuing from a previous response:\n\n```json\n{\n  \"keyword\": \"AI\",\n  \"nextCursor\": \"eyJsYXN0SWQiOiIxMjM0NTY3ODkwIn0=\"\n}\n```\n\n资料来源：[README.md:1-80]()\n\n## Design Philosophy\n\nThe Unified Search Tool follows the **\"Transport, not transformation\"** principle:\n\n- **Maximum data fidelity:** Returns unmodified upstream JSON responses\n- **No field parsing:** Raw response structure preserved\n- **No data restructuring:** Original field names and hierarchy maintained\n- **Long-term compatibility:** Interface stability prioritized over convenience\n\nThis approach ensures that clients receive complete, unmodified data for any downstream processing needs.\n\n资料来源：[README.md:95-105]()\n\n## Implementation\nError with Openai API: output new_sensitive (1027)\n\nPlease check that you have set the OPENAI_API_KEY environment variable with a valid API key.\n\n---\n\n<a id='kuaishou-video-search'></a>\n\n## Kuaishou Video Search Tool\n\n### 相关页面\n\n相关主题：[Unified Search Tool](#unified-search-tool), [Tool Naming Conventions and Standards](#tool-conventions)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n</details>\n\n# Kuaishou Video Search Tool\n\n## Overview\n\nThe **Kuaishou Video Search Tool** (`kuaishou_search_video_v2`) is a Model Context Protocol (MCP) tool that enables users to search for videos on Kuaishou, a major Chinese short-video platform. It integrates with the JustOneAPI service to provide programmatic access to Kuaishou's video search functionality.\n\n**Key Characteristics:**\n- Platform-specific search targeting Kuaishou exclusively\n- Pagination support for result browsing\n- Returns raw, untransformed JSON responses from the upstream API\n- Zod-based input validation with clear parameter descriptions\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:1-16]()\n\n## Architecture\n\n### System Context\n\nThe tool operates within the broader justoneapi-mcp server architecture, which uses the MCP SDK to expose tools to AI hosts like Claude Desktop or Cursor.\n\n```mermaid\ngraph TD\n    A[MCP Host<br/>Claude Desktop/Cursor] -->|registerTool| B[justoneapi-mcp Server]\n    B -->|registerTool| C[kuaishou_search_video_v2]\n    C -->|requireToken| D[Config Module]\n    C -->|HTTP GET| E[JustOneAPI Gateway]\n    E -->|Proxies to| F[Kuaishou API]\n    F -->|JSON Response| E\n    E -->|Raw JSON| C\n    C -->|Formatted Result| B\n    B -->|MCP Response| A\n```\n\n### Component Responsibilities\n\n| Component | File | Responsibility |\n|-----------|------|-----------------|\n| Tool Handler | `src/tools/kuaishou/search_video_v2.ts` | Input validation, API call orchestration |\n| HTTP Client | `src/common/http.ts` | Request execution with retry logic |\n| Error Handler | `src/common/errors.ts` | Error code mapping and formatting |\n| Config | `src/common/config.ts` | Token retrieval and validation |\n| Server Entry | `src/index.ts` | Tool registration with MCP SDK |\n\n资料来源：[src/index.ts:18-37]()\n\n## Input Parameters\n\nThe `KuaishouSearchVideoV2Input` schema defines the tool's input contract using Zod validation.\n\n### Parameter Specification\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `keyword` | `string` | Yes | - | Search keyword, e.g., `'dance'` |\n| `page` | `number` | No | `1` | Page number for pagination (must be ≥ 1) |\n\n### Zod Schema Definition\n\n```typescript\nexport const KuaishouSearchVideoV2Input = z.object({\n  keyword: z.string().min(1).describe(\"Search keyword, e.g. 'dance'\"),\n  page: z.number().int().min(1).default(1).describe(\"Page number, default 1\"),\n});\n```\n\n**Validation Rules:**\n- `keyword` must be a non-empty string (minimum 1 character)\n- `page` must be a positive integer; defaults to `1` if not provided\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:4-8]()\n\n## API Request Flow\n\n### Request Construction\n\nThe tool builds the API request by encoding parameters and appending them to the endpoint URL:\n\n```typescript\nexport async function kuaishouSearchVideoV2(input: z.infer<typeof KuaishouSearchVideoV2Input>) {\n  const token = encodeURIComponent(requireToken());\n  const keyword = encodeURIComponent(input.keyword);\n  const page = input.page;\n\n  return await getJson(\n    `/api/kuaishou/search-video/v2?token=${token}&keyword=${keyword}&page=${page}`\n  );\n}\n```\n\n### Request Flow Diagram\n\n```mermaid\nsequenceDiagram\n    participant Client as MCP Tool Handler\n    participant Config as Config Module\n    participant HTTP as HTTP Client\n    participant API as JustOneAPI Gateway\n\n    Client->>Config: requireToken()\n    Config-->>Client: Returns JUSTONEAPI_TOKEN\n    \n    Client->>Client: encodeURIComponent(token, keyword, page)\n    \n    Client->>HTTP: getJson(/api/kuaishou/search-video/v2?...)\n    HTTP->>API: GET Request\n    \n    alt Success (2xx)\n        API-->>HTTP: { code: 0, data: {...} }\n        HTTP-->>Client: Parsed JSON object\n    else Error (4xx/5xx)\n        API-->>HTTP: Error response\n        HTTP-->>Client: Throws ApiError\n    end\n```\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:10-16]()\n\n## Error Handling\n\nAll errors are normalized into MCP error codes with actionable messages.\n\n### Error Code Reference\n\n| Error Code | Description | User Action |\n|------------|-------------|-------------|\n| `INVALID_TOKEN` | Token is invalid or inactive | Update `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | Data collection failed | Retry after a short delay |\n| `RATE_LIMITED` | Too many requests | Slow down and retry later |\n| `DAILY_QUOTA_EXCEEDED` | Daily usage limit reached | Wait until tomorrow or upgrade plan |\n| `INSUFFICIENT_BALANCE` | Account balance too low | Top up account |\n| `VALIDATION_ERROR` | Invalid request parameters | Check input values |\n| `INTERNAL_ERROR` | Server error | Retry later |\n| `NETWORK_TIMEOUT` | Request timed out | Check network or retry |\n| `NETWORK_ERROR` | Network connection failed | Check internet connection |\n| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |\n\n### Error Response Format\n\nErrors are returned in a standardized format:\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\nExample:\n```\nERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\n```\n\n资料来源：[README.md:78-95]()\n\n### Error Processing in MCP Handler\n\n```typescript\nasync (input) => {\n  try {\n    const data = await kuaishouSearchVideoV2(input);\n    return {\n      content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n    };\n  } catch (e: unknown) {\n    const m = toMcpErrorPayload(e);\n    return {\n      isError: true,\n      content: [{\n        type: \"text\",\n        text: `ERROR[${m.code}] (upstream=${m.upstreamCode ?? \"N/A\"}): ${m.message}`,\n      }],\n    };\n  }\n}\n```\n\n资料来源：[src/index.ts:20-36]()\n\n## HTTP Retry Mechanism\n\nThe underlying HTTP client implements automatic retry logic for transient failures.\n\n### Retry Conditions\n\n| Condition | Retryable |\n|-----------|-----------|\n| Timeout (`AbortError`) | ✅ Yes |\n| HTTP 5xx status codes | ✅ Yes |\n| `ECONNRESET` | ✅ Yes |\n| `ECONNREFUSED` | ✅ Yes |\n| `ENOTFOUND` | ✅ Yes |\n| HTTP 4xx status codes | ❌ No |\n\n### Retry Strategy\n\n- **Attempts**: Configurable via `JUSTONEAPI_RETRY` (default: 1 retry after first attempt)\n- **Backoff**: 250ms × attempt number between retries\n- **Timeout**: Configurable via `JUSTONEAPI_TIMEOUT_MS` (default: 20000ms)\n\n```mermaid\ngraph TD\n    A[HTTP Request] --> B{Success?}\n    B -->|Yes| C[Return JSON]\n    B -->|No| D{Retryable Error?}\n    D -->|No| E[Throw Error]\n    D -->|Yes| F{Attempts Remaining?}\n    F -->|No| E\n    F -->|Yes| G[Wait 250ms × attempt]\n    G --> A\n```\n\n资料来源：[src/common/http.ts:32-42]()\n\n## Tool Registration\n\nThe tool is registered with the MCP server using the SDK's `registerTool` method.\n\n```typescript\nserver.registerTool(\n  \"kuaishou_search_video_v2\",\n  {\n    description:\n      \"Search Kuaishou videos by keyword. Returns the original raw JSON response from upstream without field normalization.\",\n    inputSchema: KuaishouSearchVideoV2Input.shape,\n  },\n  async (input) => {\n    // Implementation...\n  }\n);\n```\n\n**Registration Details:**\n- **Tool Name**: `kuaishou_search_video_v2`\n- **Schema**: `KuaishouSearchVideoV2Input.shape` (Zod-derived)\n- **Response Type**: Raw JSON text with indentation\n\n资料来源：[src/index.ts:18-37]()\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | - | Authentication token for JustOneAPI |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after first attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging |\n\n### Token Security\n\nThe configuration module masks tokens in log output for security:\n\n```typescript\nexport function toSafeUrlForLog(fullUrl: string): string {\n  try {\n    const u = new URL(fullUrl);\n    if (u.searchParams.has(\"token\")) {\n      u.searchParams.set(\"token\", maskToken(u.searchParams.get(\"token\") ?? \"\"));\n    }\n    return u.toString();\n  } catch {\n    return fullUrl.replace(/token=([^&]+)/g, (_m, g1) => `token=${maskToken(g1)}`);\n  }\n}\n```\n\n资料来源：[src/common/config.ts:27-41]()\n\n## Response Contract\n\n### Success Response Format\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-12-31T14:55:21Z\",\n  \"data\": {\n    // Platform-specific data structure from Kuaishou API\n  }\n}\n```\n\n### Field Descriptions\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `code` | `number` | `0` indicates success; non-zero indicates error |\n| `message` | `string \\| null` | Error description if code ≠ 0 |\n| `recordTime` | `string` | Timestamp of the response (ISO 8601) |\n| `data` | `object` | Raw response from upstream Kuaishou API |\n\n### Raw JSON Philosophy\n\nThe tool intentionally returns **unmodified upstream responses**:\n- ✅ Maximum data fidelity\n- ✅ No field parsing or normalization\n- ✅ No data restructuring\n- ✅ Long-term compatibility\n\n资料来源：[TOOLS.md:69-86]()\n\n## Usage Examples\n\n### Claude Desktop / Cursor\n\n```\nSearch for \"dance\" videos on Kuaishou, page 1\n```\n\n### MCP Host Tool Invocation\n\n```json\n{\n  \"name\": \"kuaishou_search_video_v2\",\n  \"input\": {\n    \"keyword\": \"dance\",\n    \"page\": 1\n  }\n}\n```\n\n### Expected Response Structure\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-01-15T10:30:00Z\",\n  \"data\": {\n    // Kuaishou video search results\n    // (exact structure determined by upstream API)\n  }\n}\n```\n\n## Dependencies\n\nThe tool relies on the following npm packages:\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `@modelcontextprotocol/sdk` | `^1.25.1` | MCP server and tool framework |\n| `zod` | `^4.3.4` | Schema validation and type inference |\n| `dotenv` | `^17.2.3` | Environment variable loading |\n\n资料来源：[package.json:18-26]()\n\n## Related Documentation\n\n| Document | Description |\n|----------|-------------|\n| [README.md](README.md) | Main project documentation |\n| [TOOLS.md](TOOLS.md) | Complete tools reference |\n| [unified_search_v1](./unified%20Search%20Tool.md) | Multi-platform search alternative |\n\n---\n\n<a id='tool-conventions'></a>\n\n## Tool Naming Conventions and Standards\n\n### 相关页面\n\n相关主题：[Unified Search Tool](#unified-search-tool), [Kuaishou Video Search Tool](#kuaishou-video-search)\n\n<details>\n<summary>Relevant Source Files</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n</details>\n\n# Tool Naming Conventions and Standards\n\n## Overview\n\nThe justoneapi-mcp project implements a standardized naming convention for all MCP (Model Context Protocol) tools. This convention ensures consistency, predictability, and scalability across the entire tool ecosystem. The naming standard follows a three-part pattern that clearly communicates the tool's scope, purpose, and version in a single identifier.\n\nThe primary objectives of this naming standard include:\n\n- **Discoverability**: Tools can be easily identified and located based on their naming pattern\n- **Versioning**: API evolution is managed through version suffixes\n- **Consistency**: All contributors follow the same pattern, reducing cognitive load\n- **Scalability**: New tools can be added following the established convention without ambiguity\n\n资料来源：[README.md:73]()\n\n## Naming Pattern Structure\n\nAll tools in the justoneapi-mcp server follow a unified naming pattern:\n\n```\n{platform}_{action}_{version}\n```\n\nThis three-component structure provides immediate context about each tool's purpose and scope.\n\n### Component Breakdown\n\n| Component | Purpose | Examples | Description |\n|-----------|---------|----------|-------------|\n| `platform` | Identifies the target service | `kuaishou`, `unified` | The platform or scope the tool operates on |\n| `action` | Describes the operation | `search`, `search_video` | What the tool does, can be compound with underscore |\n| `version` | Indicates API version | `v1`, `v2` | Version of the underlying API endpoint |\n\n### Syntax Rules\n\n1. **Delimiter**: Components are separated by underscores (`_`), not camelCase or hyphens\n2. **Lowercase**: All components use lowercase letters exclusively\n3. **Compound actions**: Multi-word actions use underscores (e.g., `search_video`)\n4. **Version format**: Version uses lowercase `v` followed by a number (e.g., `v1`, `v2`)\n\n资料来源：[README.md:74-76]()\n\n## Current Tool Registry\n\nThe following table lists all currently available tools in the justoneapi-mcp server:\n\n| Tool Name | Platform | Action | Version | Purpose |\n|-----------|----------|--------|---------|---------|\n| `unified_search_v1` | unified | search | v1 | Multi-platform search across Weibo, WeChat, Zhihu, Douyin, Xiaohongshu, Bilibili, Kuaishou, and News |\n| `kuaishou_search_video_v2` | kuaishou | search_video | v2 | Platform-specific video search for Kuaishou |\n\n资料来源：[src/index.ts:24-46]()\n\n## Platform Component Standards\n\n### Reserved Platform Identifiers\n\nThe platform component identifies the target service or search domain:\n\n| Platform | Description | Supported Actions |\n|----------|-------------|-------------------|\n| `unified` | Aggregated multi-platform search | `search` |\n| `kuaishou` | Kuaishou video platform | `search_video` |\n| `weibo` | Weibo social platform (planned) | `search` |\n| `zhihu` | Zhihu Q&A platform (planned) | `search` |\n| `douyin` | Douyin short video (planned) | `search_video` |\n| `bilibili` | Bilibili video platform (planned) | `search_video` |\n\n资料来源：[TOOLS.md:34-40]()\n\n### Naming Future Platforms\n\nWhen adding new platforms, follow these guidelines:\n\n1. Use the lowercase English name of the platform\n2. If the platform name contains multiple words, use the most common short form\n3. Avoid abbreviations unless they are universally recognized\n4. Ensure uniqueness across all existing platform names\n\n## Action Component Standards\n\n### Single-Word Actions\n\nSimple actions use a single lowercase word:\n\n- `search` - General search functionality\n- `analyze` - Data analysis operations\n- `fetch` - Data retrieval operations\n\n### Compound Actions\n\nActions with multiple components use underscores to separate words:\n\n| Action | Components | Meaning |\n|--------|------------|---------|\n| `search_video` | search + video | Video search functionality |\n| `search_user` | search + user | User profile search |\n| `fetch_trending` | fetch + trending | Trending content retrieval |\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:1-15]()\n\n## Version Component Standards\n\n### Versioning Strategy\n\nThe version component follows semantic versioning principles adapted for API evolution:\n\n| Version Pattern | Meaning | Upgrade Consideration |\n|----------------|---------|----------------------|\n| `v1` | Initial stable release | Breaking changes unlikely |\n| `v2` | Major version with potential breaking changes | Check changelog before upgrading |\n| `v{n}` | Future major versions | Each increment may introduce breaking changes |\n\n### Version Upgrade Triggers\n\nConsider incrementing the version when:\n\n- **Breaking API changes**: Parameter types, required fields, or return structure change\n- **Behavior changes**: Same inputs produce different outputs\n- **Deprecations**: Removing functionality from a tool\n- **Major architectural changes**: Internal refactoring affecting external behavior\n\n### Version Coexistence\n\nMultiple versions of the same tool may coexist, allowing gradual migration:\n\n- Old versions remain available for backward compatibility\n- New versions receive new features and improvements\n- Deprecation notices appear in documentation\n\n## Implementation Architecture\n\n### Tool Registration Flow\n\nThe following diagram illustrates how tools are registered and exposed through the MCP server:\n\n```mermaid\ngraph TD\n    A[Tool Definition File] --> B[Zod Input Schema]\n    A --> C[Tool Handler Function]\n    B --> D[registerTool in index.ts]\n    C --> D\n    D --> E[McpServer Instance]\n    E --> F[STDIO Transport]\n    F --> G[MCP Host Client]\n    \n    H[Tool Name: kuaishou_search_video_v2] --> D\n    I[Tool Name: unified_search_v1] --> D\n```\n\n### Tool Registration Code Structure\n\nTools are registered in `src/index.ts` using the MCP SDK's `registerTool` method:\n\n```typescript\nserver.registerTool(\n  \"kuaishou_search_video_v2\",\n  {\n    description: \"Search Kuaishou videos by keyword...\",\n    inputSchema: KuaishouSearchVideoV2Input.shape,\n  },\n  async (input) => {\n    try {\n      const data = await kuaishouSearchVideoV2(input);\n      return { content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }] };\n    } catch (e: unknown) {\n      const m = toMcpErrorPayload(e);\n      return { isError: true, content: [...] };\n    }\n  }\n);\n```\n\n资料来源：[src/index.ts:24-46]()\n\n## Input Schema Conventions\n\n### Zod-Based Validation\n\nAll tools use Zod schemas for input validation, ensuring type safety and automatic documentation:\n\n```typescript\nexport const KuaishouSearchVideoV2Input = z.object({\n  keyword: z.string().min(1).describe(\"Search keyword, e.g. 'dance'\"),\n  page: z.number().int().min(1).default(1).describe(\"Page number, default 1\"),\n});\n```\n\n### Schema Documentation Pattern\n\nEach parameter includes:\n\n| Field | Purpose | Methods |\n|-------|---------|---------|\n| `describe()` | Human-readable description | Required for all parameters |\n| `.min()` | Minimum value constraint | For strings and numbers |\n| `.default()` | Default value if omitted | Optional parameters |\n| `.optional()` | Marks non-required parameters | Optional parameters |\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:4-9]()\n\n## Unified Search Tool Specification\n\n### `unified_search_v1`\n\nThe unified search tool provides cross-platform search capabilities with advanced syntax support.\n\n#### Parameters\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `keyword` | string | Yes | Search keyword with syntax: single `word`, AND `word1 word2`, OR `word1~word2`, NOT `word -excluded` |\n| `source` | enum | No | Platform filter: `ALL`, `NEWS`, `WEIBO`, `WEIXIN`, `ZHIHU`, `DOUYIN`, `XIAOHONGSHU`, `BILIBILI`, `KUAISHOU` |\n| `start` | string | Conditional | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8). Required for first page |\n| `end` | string | Conditional | End time `yyyy-MM-dd HH:mm:ss` (UTC+8). Required for first page |\n| `nextCursor` | string | No | Pagination cursor from previous response |\n\n#### Search Syntax Examples\n\n| Syntax | Example | Meaning |\n|--------|---------|---------|\n| Single keyword | `deepseek` | Posts containing \"deepseek\" |\n| AND search | `deepseek chatgpt` | Posts containing both terms |\n| OR search | `deepseek~chatgpt` | Posts containing either term |\n| NOT search | `deepseek -chatgpt` | Posts with \"deepseek\" but not \"chatgpt\" |\n\n资料来源：[src/tools/search/unified_search_v1.ts:1-42]()\n\n## Platform-Specific Tool Specification\n\n### `kuaishou_search_video_v2`\n\nThe Kuaishou video search tool provides platform-specific video search functionality.\n\n#### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `keyword` | string | Yes | - | Search keyword, minimum 1 character |\n| `page` | number | No | 1 | Page number, must be positive integer |\n\n#### API Endpoint\n\n```\nGET /api/kuaishou/search-video/v2?token={token}&keyword={keyword}&page={page}\n```\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:1-15]()\n\n## Error Handling Integration\n\n### Standardized Error Codes\n\nAll tools return errors in a consistent format that includes the MCP error code:\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n### Error Code Mapping\n\n| MCP Code | Trigger Condition | Upstream Code | User Action |\n|----------|-------------------|---------------|-------------|\n| `INVALID_TOKEN` | Invalid or inactive token | - | Update `JUSTONEAPI_TOKEN` |\n| `RATE_LIMITED` | Too many requests | 302 | Slow down and retry |\n| `DAILY_QUOTA_EXCEEDED` | Daily limit reached | - | Wait until tomorrow |\n| `INSUFFICIENT_BALANCE` | Low account balance | - | Top up account |\n| `NETWORK_TIMEOUT` | Request timeout | - | Check network/retry |\n| `COLLECT_FAILED` | Data collection failed | - | Retry after delay |\n| `VALIDATION_ERROR` | Invalid parameters | - | Check input values |\n\n资料来源：[src/common/errors.ts:1-60]()\n\n### Error Handler Implementation\n\n```typescript\nexport function toMcpErrorPayload(e: unknown): {\n  code: JOAErrorCode;\n  message: string;\n  upstreamCode?: number;\n  httpStatus?: number;\n} {\n  const error = e as {\n    name?: string;\n    message?: string;\n    upstreamCode?: number;\n    httpStatus?: number;\n  };\n  \n  if (error.name === \"AbortError\") {\n    return { code: \"NETWORK_TIMEOUT\", message: buildUserMessage(\"NETWORK_TIMEOUT\") };\n  }\n  // ... additional error type handling\n}\n```\n\n## Best Practices\n\n### Creating New Tools\n\nFollow these steps to add a new tool:\n\n1. **Choose the name** following the `{platform}_{action}_{version}` pattern\n2. **Create the tool file** in `src/tools/{platform}/`\n3. **Define the Zod schema** with descriptive parameter documentation\n4. **Implement the handler** using `getJson` from `common/http.ts`\n5. **Register in `index.ts`** with description and input schema\n6. **Add tests** for input validation and error handling\n\n### File Naming Conventions\n\n| Tool Type | Location | File Name Pattern |\n|-----------|----------|-------------------|\n| Platform-specific | `src/tools/{platform}/` | `{action}_{version}.ts` |\n| Unified tools | `src/tools/search/` | `{action}_{version}.ts` |\n| Utility functions | `src/common/` | `{purpose}.ts` |\n\n### Documentation Requirements\n\nEach tool must document:\n\n- All parameters with types and descriptions\n- Required vs optional parameters\n- Default values where applicable\n- Error codes that may be returned\n- Example usage scenarios\n\n## Summary\n\nThe tool naming convention in justoneapi-mcp provides a clear, consistent, and scalable approach to defining MCP tools. By following the `{platform}_{action}_{version}` pattern, developers can quickly understand any tool's purpose and scope. The Zod-based schema validation ensures type safety, while standardized error handling provides consistent feedback across all operations.\n\nKey takeaways:\n\n- Use underscores to separate all components\n- Always include the version suffix (`v1`, `v2`, etc.)\n- Use compound action names with underscores when needed\n- Follow the established file structure for organization\n- Leverage Zod schemas for validation and documentation\n\n---\n\n<a id='configuration-reference'></a>\n\n## Configuration Reference\n\n### 相关页面\n\n相关主题：[Authentication](#authentication), [HTTP Client Implementation](#http-client)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n</details>\n\n# Configuration Reference\n\n## Overview\n\nThe justoneapi-mcp server provides a centralized configuration system that manages all runtime settings through environment variables. The configuration module serves as the single source of truth for API credentials, connection parameters, and debugging options.\n\nConfiguration is loaded from environment variables at startup and validated before the MCP server begins accepting requests. The system follows a \"fail-fast\" design pattern, terminating immediately if required parameters are missing.\n\n资料来源：[src/index.ts:58-64]()\n\n## Environment Variables\n\n### Required Variables\n\n| Variable | Type | Required | Description |\n|----------|------|----------|-------------|\n| `JUSTONEAPI_TOKEN` | string | **Yes** | Your JustOneAPI authentication token. Used for all API requests. |\n\nThe server validates the token presence on startup. If the token is missing or empty, the server exits with an error message directing users to set the environment variable.\n\n资料来源：[src/index.ts:58-68]()\n\n### Optional Variables\n\n| Variable | Type | Default | Description |\n|----------|------|---------|-------------|\n| `JUSTONEAPI_BASE_URL` | string | `https://api.justoneapi.com` | Base API endpoint for all requests |\n| `JUSTONEAPI_TIMEOUT_MS` | number | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | number | `1` | Number of retries after initial request failure |\n| `JUSTONEAPI_DEBUG` | boolean | `false` | Enable debug logging to stderr |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## Configuration Module Architecture\n\n### Module Structure\n\nThe configuration system consists of the following exported functions and objects:\n\n```typescript\n// Implemented in src/common/config.ts\nexport const config: Config;        // Runtime configuration object\nexport function requireToken(): string;    // Validates and returns token\nexport function toSafeUrlForLog(url: string): string;  // Sanitizes URLs for logging\n```\n\n### Configuration Object\n\nThe internal `Config` interface defines the shape of the runtime configuration:\n\n```typescript\ninterface Config {\n  token: string;\n  baseUrl: string;\n  timeoutMs: number;\n  retry: number;\n  debug: boolean;\n}\n```\n\n## Token Management\n\n### Token Validation\n\nThe `requireToken()` function performs strict validation on the token:\n\n1. Reads `JUSTONEAPI_TOKEN` from environment\n2. Trims whitespace from the value\n3. Checks if the token is empty\n4. Returns the validated token string\n\nIf validation fails, an error is thrown immediately, preventing server startup.\n\n资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n\n### Token Usage in HTTP Layer\n\nThe token is used in HTTP requests by encoding it for URL safety:\n\n```typescript\nconst token = encodeURIComponent(requireToken());\n```\n\nThis encoded token is appended to all API requests, including:\n\n- Unified search: `/api/search/v1?token=${token}&keyword=${keyword}`\n- Kuaishou video search: `/api/kuaishou/search-video/v2?token=${token}&keyword=${keyword}`\n\n资料来源：[src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n\n## HTTP Layer Integration\n\n### Request Flow\n\n```mermaid\ngraph TD\n    A[API Tool Called] --> B[getJson Function]\n    B --> C[requireToken Validation]\n    C --> D[Build URL with Config]\n    D --> E[Create AbortController]\n    E --> F[Execute Fetch Request]\n    F --> G{Success?}\n    G -->|Yes| H[Parse JSON Response]\n    G -->|No| I{Check Retryable Error}\n    I -->|Yes| J[Wait 250ms × Attempt]\n    J --> E\n    I -->|No| K[Throw Error]\n    H --> L[Return UpstreamResponse]\n    K --> M[Error Handler]\n```\n\n### Configuration Parameters Used\n\nThe HTTP module consumes configuration for request handling:\n\n| Parameter | Usage | Purpose |\n|-----------|-------|---------|\n| `config.baseUrl` | URL construction | Prepend to all API paths |\n| `config.timeoutMs` | Request timeout | Set AbortController timer |\n| `config.retry` | Retry logic | Calculate total attempt count |\n| `config.debug` | Logging | Print request details to stderr |\n\n资料来源：[src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n### Retry Mechanism\n\nThe retry logic uses the `JUSTONEAPI_RETRY` configuration value:\n\n```typescript\nconst attempts = 1 + Math.max(0, Number.isFinite(config.retry) ? config.retry : 0);\n```\n\nRetry occurs only for specific error types:\n\n| Error Type | Retryable |\n|------------|-----------|\n| `AbortError` (timeout) | ✅ Yes |\n| HTTP 5xx status | ✅ Yes |\n| `ECONNRESET` | ✅ Yes |\n| `ECONNREFUSED` | ✅ Yes |\n| `ENOTFOUND` | ✅ Yes |\n| HTTP 4xx status | ❌ No |\n| Business code ≠ 0 | ❌ No |\n\n资料来源：[src/common/http.ts:31-39]()\n\n### Timeout Configuration\n\nThe timeout is applied using AbortController:\n\n```typescript\nconst timer = setTimeout(() => controller.abort(), config.timeoutMs);\n```\n\nWith the default of 20000ms (20 seconds), requests exceeding this duration are cancelled and may be retried based on retry configuration.\n\n资料来源：[src/common/http.ts:44-45]()\n\n## Debug Logging\n\nWhen `JUSTONEAPI_DEBUG` is set to `true`, detailed request information is logged to stderr:\n\n```typescript\nif (config.debug) {\n  console.error(`[justoneapi] GET ${toSafeUrlForLog(url)} (attempt ${attempt}/${attempts})`);\n}\n```\n\n### URL Sanitization\n\nThe `toSafeUrlForLog()` function ensures tokens are never exposed in logs by sanitizing URLs before output.\n\n资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n\n## Error Handling Integration\n\nConfiguration errors are mapped to MCP error codes:\n\n| Upstream Code | MCP Error Code | User Message |\n|---------------|----------------|--------------|\n| - | `INVALID_TOKEN` | Token is invalid or inactive |\n| - | `NETWORK_TIMEOUT` | Request timed out |\n| - | `NETWORK_ERROR` | Network connection failed |\n| - | `INTERNAL_ERROR` | Server error |\n\n资料来源：[src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n## MCP Server Configuration\n\n### Claude Desktop Configuration\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\",\n        \"JUSTONEAPI_TIMEOUT_MS\": \"30000\",\n        \"JUSTONEAPI_DEBUG\": \"true\"\n      }\n    }\n  }\n}\n```\n\n### Configuration File Locations\n\n| Operating System | Config File Path |\n|-----------------|------------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## Dependencies\n\nThe configuration system depends on the following packages:\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `zod` | ^4.3.4 | Input validation schemas |\n| `dotenv` | ^17.2.3 | Environment variable loading |\n| `@modelcontextprotocol/sdk` | ^1.25.1 | MCP protocol implementation |\n\n资料来源：[package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n## Startup Validation\n\nThe server performs validation at startup in `src/index.ts`:\n\n```typescript\nasync function main() {\n  // Validate configuration on startup\n  if (!process.env.JUSTONEAPI_TOKEN?.trim()) {\n    console.error(\n      \"[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\\n\" +\n        \"Please set the JUSTONEAPI_TOKEN environment variable in your MCP host configuration\"\n    );\n    process.exit(1);\n  }\n  // ... server initialization\n}\n```\n\nThis ensures users receive immediate feedback about missing configuration before the server attempts any network operations.\n\n资料来源：[src/index.ts:58-68]()\n\n## Summary\n\nThe configuration system provides:\n\n- **Centralized management** via environment variables\n- **Fail-fast validation** on server startup\n- **Safe logging** with token sanitization\n- **Configurable timeouts** and retry behavior\n- **Debug capabilities** for troubleshooting\n\nAll configuration flows through a single module (`src/common/config.ts`) ensuring consistent behavior across the entire application.\n\n---\n\n<a id='mcp-integration'></a>\n\n## MCP Host Integration\n\n### 相关页面\n\n相关主题：[Getting Started with JustOneAPI MCP](#getting-started)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n</details>\n\n# MCP Host Integration\n\n## Overview\n\nMCP Host Integration refers to the process of connecting the **justoneapi-mcp** server to an MCP (Model Context Protocol) host application, enabling AI assistants like Claude Desktop, Cursor, or other MCP-compatible hosts to access Chinese social media search capabilities.\n\nThe integration follows the MCP specification, using JSON-RPC over stdio for communication between the host and server. This architecture allows any MCP-compatible host to discover and invoke the tools provided by justoneapi-mcp without custom integrations.\n\n资料来源：[README.md:1-50]()\n\n## Architecture\n\n### System Components\n\nThe MCP Host Integration consists of three primary layers:\n\n```mermaid\ngraph TD\n    A[\"MCP Host<br/>(Claude Desktop, Cursor)\"] --> B[\"justoneapi-mcp Server\"]\n    B --> C[\"JustOneAPI Backend\"]\n    B --> D[\"Zod Validation Layer\"]\n    \n    A --> E[\"StdioServerTransport\"]\n    E --> B\n    \n    style A fill:#e1f5fe\n    style B fill:#fff3e0\n    style C fill:#e8f5e9\n```\n\n| Component | Description | Technology |\n|-----------|-------------|------------|\n| MCP Host | Client application providing AI capabilities | Claude Desktop, Cursor, etc. |\n| Transport | Communication channel | stdio (Standard Input/Output) |\n| MCP Server | Tool registry and request handler | @modelcontextprotocol/sdk |\n| Validation | Input schema validation | Zod v4 |\n| API Client | Upstream API communication | Native fetch with retry logic |\n\n资料来源：[src/index.ts:1-20]()\n\n### Request Flow\n\n```mermaid\nsequenceDiagram\n    participant Host as MCP Host\n    participant Server as justoneapi-mcp\n    participant API as JustOneAPI\n    \n    Host->>Server: Tool invocation (JSON-RPC)\n    Server->>Server: Validate with Zod schema\n    Server->>API: HTTP request with token\n    API->>API: Process search request\n    API-->>Server: Raw JSON response\n    Server-->>Host: JSON-RPC response\n```\n\n## Supported MCP Hosts\n\nThe justoneapi-mcp server is compatible with any application implementing the MCP specification:\n\n| Host | Platform | Configuration Path |\n|------|----------|---------------------|\n| Claude Desktop | macOS, Windows, Linux | Platform-specific config |\n| Cursor | macOS, Windows, Linux | MCP settings |\n| Other MCP hosts | Any | Host-specific |\n\n资料来源：[README.md:50-80]()\n\n## Installation and Configuration\n\n### Quick Start with npx\n\nThe recommended installation method uses `npx` for zero-configuration deployment:\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md:60-75]()\n\n### Configuration Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | - | Your JustOneAPI authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after initial attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |\n\n资料来源：[README.md:130-145]()\n\n### Configuration File Locations\n\n| Operating System | Configuration Path |\n|------------------|-------------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n资料来源：[README.md:55-70]()\n\n## Tool Discovery\n\n### Discovery Mechanism\n\nWhen the MCP host starts, the justoneapi-mcp server automatically registers all available tools. The host queries the server's capabilities and receives a manifest of all callable tools with their input schemas.\n\n```mermaid\ngraph LR\n    A[Host Startup] --> B[Initialize Stdio Transport]\n    B --> C[Register Tools via SDK]\n    C --> D[Handle list_tools Request]\n    D --> E[Return Tool Manifest]\n    \n    F[User Request] --> G[Validate Input with Zod]\n    G --> H[Execute Tool Handler]\n    H --> I[Return JSON Response]\n```\n\n### Available Tools\n\n| Tool Name | Version | Description | Parameters |\n|-----------|---------|-------------|------------|\n| `unified_search_v1` | v1 | Multi-platform search | keyword, source, start, end, nextCursor |\n| `kuaishou_search_video_v2` | v2 | Kuaishou video search | keyword, nextCursor |\n\n资料来源：[TOOLS.md:15-50]()\n\n### Discovery Command\n\nTo discover available tools in Claude Desktop:\n\n```\nPlease list all available tools from justoneapi-mcp\n```\n\n资料来源：[README.md:35-45]()\n\n## Tool Input Validation\n\n### Schema Validation Flow\n\nAll tool inputs pass through Zod validation before execution:\n\n```mermaid\ngraph TD\n    A[User Input] --> B[Zod Schema Validation]\n    B -->|Valid| C[Execute Tool Handler]\n    B -->|Invalid| D[Return VALIDATION_ERROR]\n    C --> E[API Request]\n    E --> F[JSON Response]\n    \n    style D fill:#ffcdd2\n    style F fill:#c8e6c9\n```\n\n### Example: unified_search_v1 Schema\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `keyword` | string | Yes | Search keyword with syntax support |\n| `source` | enum | No | Platform filter (default: ALL) |\n| `start` | string | First page* | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `end` | string | First page* | End time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `nextCursor` | string | Pagination | Cursor from previous response |\n\n*Required for first page unless using `nextCursor`\n\n资料来源：[src/tools/search/unified_search_v1.ts:10-45]()\n\n### Search Syntax Support\n\n| Operator | Example | Behavior |\n|----------|---------|----------|\n| Single keyword | `deepseek` | Search for exact term |\n| AND | `deepseek chatgpt` | Both terms must appear |\n| OR | `deepseek~chatgpt` | Either term can appear |\n| NOT | `deepseek -chatgpt` | Exclude term |\n\n资料来源：[README.md:95-110]()\n\n## Error Handling Integration\n\n### Error Mapping\n\nThe server normalizes upstream errors into stable MCP error codes:\n\n| Error Code | Upstream Condition | User Action |\n|------------|-------------------|-------------|\n| `INVALID_TOKEN` | Invalid/inactive token | Update JUSTONEAPI_TOKEN |\n| `COLLECT_FAILED` | Data collection failed | Retry after delay |\n| `RATE_LIMITED` | Too many requests | Slow down and retry |\n| `DAILY_QUOTA_EXCEEDED` | Daily limit reached | Wait until tomorrow |\n| `INSUFFICIENT_BALANCE` | Low account balance | Top up account |\n| `PERMISSION_DENIED` | No access to resource | Contact support |\n| `VALIDATION_ERROR` | Invalid parameters | Check input values |\n| `INTERNAL_ERROR` | Server error | Retry later |\n| `NETWORK_TIMEOUT` | Request timed out | Check network/retry |\n| `NETWORK_ERROR` | Connection failed | Check internet |\n| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |\n\n资料来源：[src/common/errors.ts:50-80]()\n\n### Error Response Format\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\nExample:\n```\nERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\n```\n\n资料来源：[README.md:115-125]()\n\n### Retry Logic\n\nThe HTTP client implements automatic retry for transient failures:\n\n| Retry Trigger | Backoff Strategy |\n|--------------|------------------|\n| AbortError (timeout) | 250ms × attempt |\n| HTTP 5xx | 250ms × attempt |\n| ECONNRESET | 250ms × attempt |\n| ECONNREFUSED | 250ms × attempt |\n| ENOTFOUND | 250ms × attempt |\n\n资料来源：[src/common/http.ts:15-30]()\n\n## Session and Pagination\n\n### Cursor-Based Pagination\n\nSearch results use `nextCursor` for pagination to maintain state across requests:\n\n```mermaid\ngraph LR\n    A[First Request] -->|start + end| B[Page 1 Response]\n    B -->|nextCursor| C[Second Request]\n    C -->|nextCursor| D[Page 2 Response]\n    D -->|nextCursor| E[Continue...]\n    \n    style A fill:#e3f2fd\n    style D fill:#e8f5e9\n```\n\n### Continuing Results\n\nWhen results have more pages, simply ask:\n- \"Show me the next page of results\"\n- \"Get more results from the previous search\"\n- \"Continue with the next page\"\n\nThe MCP host automatically extracts `nextCursor` and fetches subsequent pages without requiring `start`, `end`, or `source` parameters again.\n\n资料来源：[README.md:78-92]()\n\n## Dependencies\n\n### Runtime Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| @modelcontextprotocol/sdk | ^1.25.1 | MCP server implementation |\n| zod | ^4.3.4 | Schema validation |\n| dotenv | ^17.2.3 | Environment configuration |\n\n### Development Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| typescript | ^5.9.3 | Type safety |\n| eslint | ^9.39.2 | Code linting |\n| prettier | ^3.7.4 | Code formatting |\n\n资料来源：[package.json:15-35]()\n\n## Design Philosophy\n\n### Transport, Not Transformation\n\nThe justoneapi-mcp server adheres to a \"Transport, not transformation\" principle:\n\n- **Maximum data fidelity** - Returns unmodified upstream responses\n- **No field parsing** - Raw JSON from APIs\n- **No data restructuring** - Preserves original schema\n- **Long-term compatibility** - Schema stability over convenience\n\nThis ensures that:\n1. No data is lost in translation\n2. Users receive complete API responses\n3. Breaking changes in upstream APIs are visible immediately\n4. Advanced users can access any field from the response\n\n资料来源：[README.md:155-165]()\n\n## Advanced Configuration Example\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\",\n        \"JUSTONEAPI_TIMEOUT_MS\": \"30000\",\n        \"JUSTONEAPI_DEBUG\": \"true\",\n        \"JUSTONEAPI_RETRY\": \"3\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md:145-155]()\n\n## Token Security\n\nThe server masks tokens in log output for security:\n\n```typescript\nfunction maskToken(token: string): string {\n  if (token.length <= 8) return \"****\";\n  return token.slice(0, 4) + \"****\" + token.slice(-4);\n}\n```\n\nSafe URL logging replaces the token parameter with masked value, ensuring credentials are never exposed in logs or error messages.\n\n资料来源：[src/common/config.ts:30-45]()\n\n---\n\n<a id='error-handling'></a>\n\n## Error Handling\n\n### 相关页面\n\n相关主题：[HTTP Client Implementation](#http-client), [Unified Search Tool](#unified-search-tool), [Configuration Reference](#configuration-reference)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n</details>\n\n# Error Handling\n\n## Overview\n\nThe justoneapi-mcp project implements a comprehensive error handling system designed to provide stability, transparency, and raw data fidelity. The error handling layer acts as a bridge between upstream API responses and MCP (Model Context Protocol) tool invocations, normalizing diverse error conditions into stable, actionable MCP error codes.\n\n**Key Design Principles:**\n\n- Transport, not transformation — the system prioritizes maximum data fidelity\n- Fail fast with clear validation (token requirement checked early)\n- Retry logic for transient failures\n- Safe logging that never exposes sensitive credentials\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n---\n\n## Error Code System\n\n### Core Error Codes\n\nThe system defines a comprehensive set of standardized error codes that map upstream errors to user-friendly MCP responses.\n\n| Error Code | Description | Recommended Action |\n|------------|-------------|-------------------|\n| `INVALID_TOKEN` | Token is invalid or inactive | Update your `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | Data collection failed | Retry after a short delay |\n| `RATE_LIMITED` | Too many requests | Slow down and retry later |\n| `DAILY_QUOTA_EXCEEDED` | Daily usage limit reached | Wait until tomorrow or upgrade plan |\n| `INSUFFICIENT_BALANCE` | Account balance too low | Top up your account |\n| `PERMISSION_DENIED` | No access to this resource | Contact support |\n| `VALIDATION_ERROR` | Invalid request parameters | Check input values |\n| `INTERNAL_ERROR` | Server error | Retry later |\n| `NETWORK_TIMEOUT` | Request timed out | Check network or retry |\n| `NETWORK_ERROR` | Network connection failed | Check internet connection |\n| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n### Upstream Code Mapping\n\nThe `mapUpstreamCode` function in `errors.ts` translates numeric upstream API codes into MCP error codes.\n\n```typescript\nfunction mapUpstreamCode(upstreamCode: number): JOAErrorCode {\n  switch (upstreamCode) {\n    case 302:\n      return \"RATE_LIMITED\";\n    case 401:\n      return \"INVALID_TOKEN\";\n    // ... other mappings\n    default:\n      return \"UPSTREAM_ERROR\";\n  }\n}\n```\n\n资料来源：[src/common/errors.ts:1-50](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n---\n\n## Architecture\n\n### Error Flow Diagram\n\n```mermaid\ngraph TD\n    A[API Request] --> B{HTTP Response OK?}\n    B -->|No| C[HTTP Level Error]\n    B -->|Yes| D{JSON Parse Success?}\n    D -->|No| E[Parse Error]\n    D -->|Yes| F{Business Code = 0?}\n    F -->|No| G[Business Level Error]\n    F -->|Yes| H[Success Response]\n    \n    C --> I[Create ApiError with httpStatus]\n    E --> J[Create ApiError with payload=text]\n    G --> K[Create ApiError with upstreamCode]\n    \n    I --> L[toMcpErrorPayload]\n    J --> L\n    K --> L\n    \n    L --> M[Return MCP Error Format]\n    \n    H --> N[Return JSON Data]\n```\n\n### Component Structure\n\n| Component | File | Responsibility |\n|-----------|------|-----------------|\n| Error Type Definitions | `src/common/errors.ts` | Error codes, mapping functions |\n| HTTP Client | `src/common/http.ts` | Request execution, retry logic |\n| Error Processing | `src/common/errors.ts` | Payload conversion, message building |\n| Tool Integration | `src/index.ts` | MCP error formatting for tool responses |\n\n资料来源：[src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts), [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n---\n\n## Error Detection and Classification\n\n### Detection Sources\n\nThe error handling system identifies errors from multiple sources:\n\n1. **Timeout Errors** — AbortError from AbortController\n2. **HTTP Status Errors** — Non-2xx responses\n3. **JSON Parse Failures** — Invalid JSON responses\n4. **Business Logic Errors** — Upstream API returns code != 0\n5. **Network Failures** — ECONNREFUSED, ENOTFOUND, ECONNRESET\n\n```typescript\n// Timeout from AbortController\nif (error.name === \"AbortError\") {\n  return { code: \"NETWORK_TIMEOUT\", message: buildUserMessage(\"NETWORK_TIMEOUT\") };\n}\n\n// Network-level failures\nif (error.cause || error.code === \"ECONNREFUSED\" || error.code === \"ENOTFOUND\") {\n  return { code: \"NETWORK_ERROR\", message: error.message ?? buildUserMessage(\"NETWORK_ERROR\") };\n}\n```\n\n资料来源：[src/common/errors.ts:52-73](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n### Error Payload Interface\n\n```typescript\ninterface ApiError extends Error {\n  httpStatus?: number;\n  upstreamCode?: number;\n  payload?: unknown;\n  code?: string;\n  cause?: unknown;\n}\n```\n\n资料来源：[src/common/http.ts:15-21](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n---\n\n## HTTP Client Error Handling\n\n### Retry Logic\n\nThe `getJson` function implements intelligent retry logic with exponential backoff.\n\n```mermaid\ngraph LR\n    A[Request] --> B{Attempt <= Max?}\n    B -->|Yes| C[Execute Fetch]\n    C --> D{Success?}\n    D -->|Yes| E[Return JSON]\n    D -->|No| F{Retryable?}\n    F -->|Yes| G[Wait 250ms * attempt]\n    F -->|No| H[Throw Error]\n    G --> B\n    H --> I[toMcpErrorPayload]\n```\n\n### Retryable Conditions\n\n| Condition | Retryable | Reason |\n|-----------|-----------|--------|\n| AbortError (timeout) | ✅ Yes | Transient timeout |\n| HTTP 5xx | ✅ Yes | Server-side issue |\n| ECONNRESET | ✅ Yes | Connection reset |\n| ECONNREFUSED | ✅ Yes | Server unavailable |\n| ENOTFOUND | ✅ Yes | DNS/network issue |\n| HTTP 4xx | ❌ No | Client error |\n| Business code != 0 | ❌ No | Data issue |\n\n```typescript\nconst retryable =\n  error.name === \"AbortError\" ||\n  (typeof httpStatus === \"number\" && httpStatus >= 500) ||\n  error.code === \"ECONNRESET\" ||\n  error.code === \"ECONNREFUSED\" ||\n  error.code === \"ENOTFOUND\";\n```\n\n资料来源：[src/common/http.ts:40-48](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n### Timeout Configuration\n\n| Configuration | Default | Description |\n|---------------|---------|-------------|\n| `JUSTONEAPI_TIMEOUT_MS` | 20000 | Request timeout in milliseconds |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n---\n\n## Error Processing Flow\n\n### The `toMcpErrorPayload` Function\n\nThis function transforms various error types into a standardized MCP error format:\n\n```typescript\nexport function toMcpErrorPayload(e: unknown): {\n  code: JOAErrorCode;\n  message: string;\n  upstreamCode?: number;\n  httpStatus?: number;\n}\n```\n\n**Processing Priority:**\n\n1. AbortError → `NETWORK_TIMEOUT`\n2. Upstream business code (if present) → Mapped MCP code\n3. HTTP status (if present) → `UPSTREAM_ERROR`\n4. Network errors (cause present or specific codes) → `NETWORK_ERROR`\n5. Default fallback → `UPSTREAM_ERROR`\n\n资料来源：[src/common/errors.ts:76-101](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n### User Message Building\n\nThe `buildUserMessage` function generates human-readable messages for each error code:\n\n```typescript\nfunction buildUserMessage(code: JOAErrorCode, base?: string | null): string {\n  switch (code) {\n    case \"NETWORK_TIMEOUT\":\n      return base ?? \"Request timed out. Check network or increase timeout.\";\n    case \"INVALID_TOKEN\":\n      return base ?? \"Invalid or inactive token. Check JUSTONEAPI_TOKEN.\";\n    // ... additional cases\n    default:\n      return base ?? \"Upstream error. Please retry later.\";\n  }\n}\n```\n\n资料来源：[src/common/errors.ts:25-74](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n---\n\n## Tool-Level Error Handling\n\n### MCP Tool Integration\n\nAll tools registered with the MCP server wrap their execution in try-catch blocks to ensure consistent error formatting.\n\n```typescript\nserver.registerTool(\n  \"unified_search_v1\",\n  {\n    description: \"Unified search across multiple platforms...\",\n    inputSchema: UnifiedSearchV1Input.shape,\n  },\n  async (input) => {\n    try {\n      const data = await unifiedSearchV1(input);\n      return {\n        content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n      };\n    } catch (e: unknown) {\n      const m = toMcpErrorPayload(e);\n      return {\n        isError: true,\n        content: [\n          {\n            type: \"text\",\n            text: `ERROR[${m.code}] (upstream=${m.upstreamCode ?? \"N/A\"}): ${m.message}`,\n          },\n        ],\n      };\n    }\n  }\n);\n```\n\n资料来源：[src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n### Error Response Format\n\nMCP tool errors are formatted as:\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n**Example Responses:**\n\n| Scenario | Response Format |\n|----------|-----------------|\n| Rate Limited | `ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.` |\n| Invalid Token | `ERROR[INVALID_TOKEN] (upstream=401): Invalid or inactive token. Check JUSTONEAPI_TOKEN.` |\n| Network Timeout | `ERROR[NETWORK_TIMEOUT] (upstream=N/A): Request timed out. Check network or increase timeout.` |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n---\n\n## Validation Errors\n\n### Early Validation\n\nThe system performs early validation to fail fast with clear error messages:\n\n**Token Validation:**\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN?.trim();\n  if (!token) {\n    const err = new Error(\"JUSTONEAPI_TOKEN is required\") as ApiError;\n    err.upstreamCode = 401;\n    throw err;\n  }\n  return token;\n}\n```\n\n资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n\n**Search Parameter Validation:**\n\n```typescript\n// First page: require start and end times\nif (!input.start || !input.end) {\n  throw new Error(\n    \"start and end times are required for the first page (unless using nextCursor for pagination)\"\n  );\n}\n```\n\n资料来源：[src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n\n---\n\n## Debugging Error Handling\n\n### Debug Mode\n\nEnable debug logging to trace error handling flow:\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\",\n        \"JUSTONEAPI_DEBUG\": \"true\"\n      }\n    }\n  }\n}\n```\n\n### Safe URL Logging\n\nThe system includes `toSafeUrlForLog` to prevent token leakage in logs:\n\n```typescript\nexport function toSafeUrlForLog(fullUrl: string): string {\n  if (u.searchParams.has(\"token\")) {\n    u.searchParams.set(\"token\", maskToken(u.searchParams.get(\"token\") ?? \"\"));\n  }\n  return u.toString();\n}\n```\n\n资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n\n---\n\n## Configuration Options\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | *(required)* | Your JustOneAPI token |\n| `JUSTONEAPI_BASE_URL` | `https://api.justoneapi.com` | API endpoint |\n| `JUSTONEAPI_TIMEOUT_MS` | `20000` | Request timeout (milliseconds) |\n| `JUSTONEAPI_RETRY` | `1` | Number of retries after first attempt |\n| `JUSTONEAPI_DEBUG` | `false` | Enable debug logging to stderr |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n---\n\n## Best Practices\n\n1. **Handle Rate Limits** — Implement exponential backoff when receiving `RATE_LIMITED`\n2. **Check Token Validity** — Ensure `JUSTONEAPI_TOKEN` is active before heavy usage\n3. **Monitor Quotas** — Track `DAILY_QUOTA_EXCEEDED` errors to avoid service interruption\n4. **Enable Debug Mode** — Use `JUSTONEAPI_DEBUG=true` when troubleshooting\n5. **Use Pagination** — Leverage `nextCursor` for large result sets to avoid timeout issues\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：justoneapi/justoneapi-mcp\n\n摘要：发现 7 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | README/documentation is current enough for a first validation pass.\n\n## 2. 运行坑 · 来源证据：Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of…\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个运行相关的待验证问题：Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of 2-39)\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3b8110f2a2a84250a1da5b96b5573463 | https://github.com/justoneapi/justoneapi-mcp/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。\n\n## 3. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | last_activity_observed missing\n\n## 4. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium\n\n## 5. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium\n\n## 6. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | issue_or_pr_quality=unknown\n\n## 7. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | release_recency=unknown\n\n<!-- canonical_name: justoneapi/justoneapi-mcp; human_manual_source: deepwiki_human_wiki -->\n",
      "markdown_key": "justoneapi-mcp",
      "pages": "draft",
      "source_refs": [
        {
          "evidence_id": "github_repo:1125683257",
          "kind": "repo",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/justoneapi/justoneapi-mcp"
        },
        {
          "evidence_id": "art_4db953f8a3eb48c299ebfe2af4ef2ddb",
          "kind": "docs",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/justoneapi/justoneapi-mcp#readme"
        }
      ],
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "justoneapi-mcp 说明书",
      "toc": [
        "https://github.com/justoneapi/justoneapi-mcp 项目说明书",
        "目录",
        "Getting Started with JustOneAPI MCP",
        "Overview",
        "Architecture",
        "Prerequisites",
        "Installation",
        "Configuration",
        "Doramagic 踩坑日志"
      ]
    }
  },
  "quality_gate": {
    "blocking_gaps": [],
    "category_confidence": "medium",
    "compile_status": "ready_for_review",
    "five_assets_present": true,
    "install_sandbox_verified": true,
    "missing_evidence": [],
    "next_action": "publish to Doramagic.ai project surfaces",
    "prompt_preview_boundary_ok": true,
    "publish_status": "publishable",
    "quick_start_verified": true,
    "repo_clone_verified": true,
    "repo_commit": "c1baa8f714b45b98cc15a1b6cfb6f65998a2647f",
    "repo_inspection_error": null,
    "repo_inspection_files": [
      "package.json",
      "README.md",
      "src/version.ts",
      "src/index.ts",
      "src/common/errors.ts",
      "src/common/config.ts",
      "src/common/http.ts",
      "src/tools/kuaishou/search_video_v2.ts",
      "src/tools/search/unified_search_v1.ts"
    ],
    "repo_inspection_verified": true,
    "review_reasons": [
      "community_discussion_evidence_below_public_threshold"
    ],
    "tag_count_ok": true,
    "unsupported_claims": []
  },
  "schema_version": "0.1",
  "user_assets": {
    "ai_context_pack": {
      "asset_id": "ai_context_pack",
      "filename": "AI_CONTEXT_PACK.md",
      "markdown": "# justoneapi-mcp - Doramagic AI Context Pack\n\n> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。\n\n## 充分原则\n\n- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。\n- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。\n\n## 给宿主 AI 的使用方式\n\n你正在读取 Doramagic 为 justoneapi-mcp 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。\n\n## Claim 消费规则\n\n- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。\n- **事实最低状态**：`supported`\n- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。\n- `weak`：只能作为低置信度线索，必须要求用户继续核实。\n- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。\n- `unverified`：不得作为事实使用，应明确说证据不足。\n- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。\n\n## 它最适合谁\n\n- **正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**：README 或插件配置提到多个宿主 AI。 证据：`README.md` Claim：`clm_0002` supported 0.86\n\n## 它能做什么\n\n- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n## 怎么开始\n\n- `npm install -g justoneapi-mcp` 证据：`README.md` Claim：`clm_0003` supported 0.86\n- `git clone <repository>` 证据：`README.md` Claim：`clm_0004` supported 0.86\n\n## 继续前判断卡\n\n- **当前建议**：需要管理员/安全审批\n- **为什么**：继续前可能涉及密钥、账号、外部服务或敏感上下文，建议先经过管理员或安全审批。\n\n### 30 秒判断\n\n- **现在怎么做**：需要管理员/安全审批\n- **最小安全下一步**：先跑 Prompt Preview；若涉及凭证或企业环境，先审批再试装\n- **先别相信**：工具权限边界不能在安装前相信。\n- **继续会触碰**：命令执行、本地环境或项目文件、环境变量 / API Key\n\n### 现在可以相信\n\n- **适合人群线索：正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86\n- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0003` supported 0.86\n\n### 现在还不能相信\n\n- **工具权限边界不能在安装前相信。**（unverified）：MCP/tool 类项目通常会触碰文件、网络、浏览器或外部 API，必须真实检查权限和日志。\n- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。\n- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。\n- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。\n- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。\n- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。\n- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。\n- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`README.md`\n\n### 继续会触碰什么\n\n- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`\n- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`\n- **环境变量 / API Key**：项目入口文档明确出现 API key、token、secret 或账号凭证配置。 原因：如果真实安装需要凭证，应先使用测试凭证并经过权限/合规判断。 证据：`README.md`, `README.zh-CN.md`, `src/common/config.ts`, `src/common/errors.ts` 等\n- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。\n\n### 最小安全下一步\n\n- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）\n- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）\n- **不要使用真实生产凭证**：环境变量/API key 一旦进入宿主或工具链，可能产生账号和合规风险。（适用：出现 API、TOKEN、KEY、SECRET 等环境线索时。）\n- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）\n\n### 退出方式\n\n- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。\n- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。\n- **准备撤销测试 API key 或 token**：测试凭证泄露或误用时，可以快速止损。\n- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。\n\n## 哪些只能预览\n\n- 解释项目适合谁和能做什么\n- 基于项目文档演示典型对话流程\n- 帮助用户判断是否值得安装或继续研究\n\n## 哪些必须安装后验证\n\n- 真实安装 Skill、插件或 CLI\n- 执行脚本、修改本地文件或访问外部服务\n- 验证真实输出质量、性能和兼容性\n\n## 边界与风险判断卡\n\n- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0005` inferred 0.45\n- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0006` supported 0.86\n- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。\n- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。\n- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。\n\n## 开工前工作上下文\n\n### 加载顺序\n\n- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。\n- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。\n- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。\n- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。\n- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。\n\n### 任务路由\n\n- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n### 上下文规模\n\n- 文件总数：20\n- 重要文件覆盖：13/20\n- 证据索引条目：13\n- 角色 / Skill 条目：3\n\n### 证据不足时的处理\n\n- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。\n- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。\n- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。\n- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。\n\n## Prompt Recipes\n\n### 适配判断\n\n- 目标：判断这个项目是否适合用户当前任务。\n- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。\n\n```text\n请基于 justoneapi-mcp 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。\n```\n\n### 安装前体验\n\n- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。\n- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。\n\n```text\n请把 justoneapi-mcp 当作安装前体验资产，而不是已安装工具或真实运行环境。\n\n请严格输出四段：\n1. 先问我 3 个必要问题。\n2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。\n3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。\n4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。\n\n硬性边界：\n- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。\n- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。\n- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。\n- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。\n- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。\n- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。\n\n```\n\n### 角色 / Skill 选择\n\n- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。\n- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。\n\n```text\n请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。\n```\n\n### 风险预检\n\n- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。\n- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。\n\n```text\n请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。\n```\n\n### 宿主 AI 开工指令\n\n- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。\n- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。\n\n```text\n请基于 justoneapi-mcp 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。\n```\n\n\n## 角色 / Skill 索引\n\n- 共索引 3 个角色 / Skill / 项目文档条目。\n\n- **JustOneAPI MCP Server**（project_doc）：! npm version https://badge.fury.io/js/justoneapi-mcp.svg https://www.npmjs.com/package/justoneapi-mcp ! License: MIT https://img.shields.io/badge/License-MIT-yellow.svg https://opensource.org/licenses/MIT 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`\n- **JustOneAPI MCP 服务器**（project_doc）：! npm version https://badge.fury.io/js/justoneapi-mcp.svg https://www.npmjs.com/package/justoneapi-mcp ! License: MIT https://img.shields.io/badge/License-MIT-yellow.svg https://opensource.org/licenses/MIT 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.zh-CN.md`\n- **JustOneAPI MCP Tools Reference**（project_doc）：Complete reference for all available tools in justoneapi-mcp. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`TOOLS.md`\n\n## 证据索引\n\n- 共索引 13 条证据。\n\n- **JustOneAPI MCP Server**（documentation）：! npm version https://badge.fury.io/js/justoneapi-mcp.svg https://www.npmjs.com/package/justoneapi-mcp ! License: MIT https://img.shields.io/badge/License-MIT-yellow.svg https://opensource.org/licenses/MIT 证据：`README.md`\n- **Package**（package_manifest）：{ \"name\": \"justoneapi-mcp\", \"version\": \"1.0.1\", \"type\": \"module\", \"description\": \"MCP server for JustOneAPI - expose API endpoints to AI assistants via Model Context Protocol\", \"main\": \"dist/index.js\", \"bin\": { \"justoneapi-mcp\": \"dist/index.js\" }, \"scripts\": { \"dev\": \"node --loader ts-node/esm src/index.ts\", \"build\": \"tsc\", \"start\": \"node dist/index.js\", \"lint\": \"eslint src/ / .ts\", \"lint:fix\": \"eslint src/ / .ts --fix\", \"format\": \"prettier --write \\\"src/ / .ts\\\"\", \"format:check\": \"prettier --check \\\"src/ / .ts\\\"\", \"prepublishOnly\": \"npm run build\" }, \"keywords\": \"mcp\", \"model-context-protocol\", \"justoneapi\", \"ai\", \"agent\", \"claude\", \"cursor\" , \"author\": \"Just One API \", \"license\": \"MIT\", \"… 证据：`package.json`\n- **License**（source_file）：Copyright c 2025 JustOneAPI MCP Contributors 证据：`LICENSE`\n- **JustOneAPI MCP 服务器**（documentation）：! npm version https://badge.fury.io/js/justoneapi-mcp.svg https://www.npmjs.com/package/justoneapi-mcp ! License: MIT https://img.shields.io/badge/License-MIT-yellow.svg https://opensource.org/licenses/MIT 证据：`README.zh-CN.md`\n- **JustOneAPI MCP Tools Reference**（documentation）：Complete reference for all available tools in justoneapi-mcp. 证据：`TOOLS.md`\n- **Tsconfig**（structured_config）：{ \"compilerOptions\": { \"target\": \"ES2022\", \"module\": \"NodeNext\", \"moduleResolution\": \"NodeNext\", \"strict\": true, \"esModuleInterop\": true, \"skipLibCheck\": true, \"outDir\": \"dist\", \"types\": \"node\" }, \"include\": \"src\" } 证据：`tsconfig.json`\n- **EditorConfig is awesome: https://EditorConfig.org**（source_file）：EditorConfig is awesome: https://EditorConfig.org 证据：`.editorconfig`\n- **Dependencies**（source_file）：Environment variables .env .env.local .env. .local 证据：`.gitignore`\n- **.npmignore**（source_file）：src/ .env .env. tsconfig.json node modules/ .git/ .gitignore .idea/ .log .swp .swo ~ .DS Store 证据：`.npmignore`\n- **.prettierrc**（source_file）：{ \"semi\": true, \"singleQuote\": false, \"tabWidth\": 2, \"trailingComma\": \"es5\", \"printWidth\": 100, \"arrowParens\": \"always\" } 证据：`.prettierrc`\n- **Eslint.Config**（source_file）：import tseslint from \"@typescript-eslint/eslint-plugin\"; import tsparser from \"@typescript-eslint/parser\"; import prettierConfig from \"eslint-config-prettier\"; 证据：`eslint.config.js`\n- **!/usr/bin/env node**（source_file）：!/usr/bin/env node import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"; import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\"; 证据：`src/index.ts`\n- **Version**（source_file）：import { readFileSync } from \"fs\"; import { fileURLToPath } from \"url\"; import { dirname, join } from \"path\"; 证据：`src/version.ts`\n\n## 宿主 AI 必须遵守的规则\n\n- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`README.md`, `package.json`, `LICENSE`\n- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`README.md`, `package.json`, `LICENSE`\n\n## 用户开工前应该回答的问题\n\n- 你准备在哪个宿主 AI 或本地环境中使用它？\n- 你只是想先体验工作流，还是准备真实安装？\n- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？\n\n## 验收标准\n\n- 所有能力声明都能回指到 evidence_refs 中的文件路径。\n- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。\n- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。\n\n---\n\n## Doramagic Context Augmentation\n\n下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。\n\n## Human Manual 骨架\n\n使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。\n\n宿主 AI 硬性规则：\n- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。\n- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。\n- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。\n\n- **Getting Started with JustOneAPI MCP**：importance `high`\n  - source_paths: README.md, package.json\n- **Authentication**：importance `high`\n  - source_paths: src/common/config.ts, src/common/http.ts\n- **System Architecture**：importance `high`\n  - source_paths: src/index.ts, src/common/config.ts, src/common/http.ts\n- **HTTP Client Implementation**：importance `medium`\n  - source_paths: src/common/http.ts\n- **Unified Search Tool**：importance `high`\n  - source_paths: src/tools/search/unified_search_v1.ts, TOOLS.md\n- **Kuaishou Video Search Tool**：importance `medium`\n  - source_paths: src/tools/kuaishou/search_video_v2.ts, TOOLS.md\n- **Tool Naming Conventions and Standards**：importance `medium`\n  - source_paths: src/tools/search/unified_search_v1.ts, src/tools/kuaishou/search_video_v2.ts\n- **Configuration Reference**：importance `high`\n  - source_paths: src/common/config.ts, package.json\n\n## Repo Inspection Evidence / 源码检查证据\n\n- repo_clone_verified: true\n- repo_inspection_verified: true\n- repo_commit: `c1baa8f714b45b98cc15a1b6cfb6f65998a2647f`\n- inspected_files: `package.json`, `README.md`, `src/version.ts`, `src/index.ts`, `src/common/errors.ts`, `src/common/config.ts`, `src/common/http.ts`, `src/tools/kuaishou/search_video_v2.ts`, `src/tools/search/unified_search_v1.ts`\n\n宿主 AI 硬性规则：\n- 没有 repo_clone_verified=true 时，不得声称已经读过源码。\n- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。\n- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。\n\n## Doramagic Pitfall Constraints / 踩坑约束\n\n这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。\n\n### Constraint 1: 能力判断依赖假设\n\n- Trigger: README/documentation is current enough for a first validation pass.\n- Host AI rule: 将假设转成下游验证清单。\n- Why it matters: 假设不成立时，用户拿不到承诺的能力。\n- Evidence: capability.assumptions | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | README/documentation is current enough for a first validation pass.\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 2: 来源证据：Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of…\n\n- Trigger: GitHub 社区证据显示该项目存在一个运行相关的待验证问题：Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of 2-39)\n- Host AI rule: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- Why it matters: 可能增加新用户试用和生产接入成本。\n- Evidence: community_evidence:github | cevd_3b8110f2a2a84250a1da5b96b5573463 | https://github.com/justoneapi/justoneapi-mcp/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 3: 维护活跃度未知\n\n- Trigger: 未记录 last_activity_observed。\n- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Evidence: evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | last_activity_observed missing\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 4: 下游验证发现风险项\n\n- Trigger: no_demo\n- Host AI rule: 进入安全/权限治理复核队列。\n- Why it matters: 下游已经要求复核，不能在页面中弱化。\n- Evidence: downstream_validation.risk_items | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 5: 存在评分风险\n\n- Trigger: no_demo\n- Host AI rule: 把风险写入边界卡，并确认是否需要人工复核。\n- Why it matters: 风险会影响是否适合普通用户安装。\n- Evidence: risks.scoring_risks | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 6: issue/PR 响应质量未知\n\n- Trigger: issue_or_pr_quality=unknown。\n- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。\n- Why it matters: 用户无法判断遇到问题后是否有人维护。\n- Evidence: evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | issue_or_pr_quality=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 7: 发布节奏不明确\n\n- Trigger: release_recency=unknown。\n- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。\n- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Evidence: evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | release_recency=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n",
      "summary": "给宿主 AI 的上下文和工作边界。",
      "title": "AI Context Pack / 带给我的 AI"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card / 安装前决策卡\n\n项目：justoneapi/justoneapi-mcp\n\n## Doramagic 试用结论\n\n当前结论：可以进入发布前推荐检查；首次使用仍应从最小权限、临时目录和可回滚配置开始。\n\n## 用户现在可以做\n\n- 可以先阅读 Human Manual，理解项目目的和主要工作流。\n- 可以复制 Prompt Preview 做安装前体验；这只验证交互感，不代表真实运行。\n- 可以把官方 Quick Start 命令放到隔离环境中验证，不要直接进主力环境。\n\n## 现在不要做\n\n- 不要把 Prompt Preview 当成项目实际运行结果。\n- 不要把 metadata-only validation 当成沙箱安装验证。\n- 不要把未验证能力写成“已支持、已跑通、可放心安装”。\n- 不要在首次试用时交出生产数据、私人文件、真实密钥或主力配置目录。\n\n## 安装前检查\n\n- 宿主 AI 是否匹配：mcp_host\n- 官方安装入口状态：已发现官方入口\n- 是否在临时目录、临时宿主或容器中验证：必须是\n- 是否能回滚配置改动：必须能\n- 是否需要 API Key、网络访问、读写文件或修改宿主配置：未确认前按高风险处理\n- 是否记录了安装命令、实际输出和失败日志：必须记录\n\n## 当前阻塞项\n\n- review_required: community_discussion_evidence_below_public_threshold\n\n## 项目专属踩坑\n\n- 能力判断依赖假设（medium）：假设不成立时，用户拿不到承诺的能力。 建议检查：将假设转成下游验证清单。\n- 来源证据：Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of…（medium）：可能增加新用户试用和生产接入成本。 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 维护活跃度未知（medium）：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 下游验证发现风险项（medium）：下游已经要求复核，不能在页面中弱化。 建议检查：进入安全/权限治理复核队列。\n- 存在评分风险（medium）：风险会影响是否适合普通用户安装。 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n\n## 风险与权限提示\n\n- no_demo: medium\n\n## 证据缺口\n\n- 暂未发现结构化证据缺口。\n",
      "summary": "安装、权限、验证和推荐前风险。",
      "title": "Boundary & Risk Card / 边界与风险卡"
    },
    "human_manual": {
      "asset_id": "human_manual",
      "filename": "HUMAN_MANUAL.md",
      "markdown": "# https://github.com/justoneapi/justoneapi-mcp 项目说明书\n\n生成时间：2026-05-15 07:48:52 UTC\n\n## 目录\n\n- [Getting Started with JustOneAPI MCP](#getting-started)\n- [Authentication](#authentication)\n- [System Architecture](#system-architecture)\n- [HTTP Client Implementation](#http-client)\n- [Unified Search Tool](#unified-search-tool)\n- [Kuaishou Video Search Tool](#kuaishou-video-search)\n- [Tool Naming Conventions and Standards](#tool-conventions)\n- [Configuration Reference](#configuration-reference)\n- [MCP Host Integration](#mcp-integration)\n- [Error Handling](#error-handling)\n\n<a id='getting-started'></a>\n\n## Getting Started with JustOneAPI MCP\n\n### 相关页面\n\n相关主题：[Authentication](#authentication), [MCP Host Integration](#mcp-integration)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n</details>\n\n# Getting Started with JustOneAPI MCP\n\n## Overview\n\nJustOneAPI MCP Server is a Model Context Protocol (MCP) server that exposes JustOneAPI endpoints to AI assistants like Claude Desktop, Cursor, and other MCP-compatible hosts. The server acts as a thin transport layer that handles authentication, retries, timeouts, and error normalization while returning raw JSON responses from upstream platforms.\n\n**Key Characteristics:**\n\n- Returns unmodified upstream JSON responses for maximum data fidelity\n- No field parsing or schema normalization\n- Designed for AI agents and developer workflows\n- Supports multiple Chinese social media and news platforms\n\n资料来源：[README.md:1-20]()\n\n## Architecture\n\n### System Components\n\n```mermaid\ngraph TD\n    A[MCP Host<br/>Claude Desktop/Cursor] --> B[JustOneAPI MCP Server]\n    B --> C[JustOneAPI REST API]\n    C --> D[Upstream Platforms]\n    \n    D --> E[Weibo]\n    D --> F[WeChat]\n    D --> G[Zhihu]\n    D --> H[Douyin]\n    D --> I[Xiaohongshu]\n    D --> J[Bilibili]\n    D --> K[Kuaishou]\n    D --> L[News]\n    \n    B --> M[Authentication]\n    B --> N[Retry Logic]\n    B --> O[Error Normalization]\n```\n\n### Technology Stack\n\n| Component | Technology | Version |\n|-----------|------------|---------|\n| Runtime | Node.js | >= 18.0.0 |\n| MCP SDK | @modelcontextprotocol/sdk | ^1.25.1 |\n| Validation | Zod | ^4.3.4 |\n| Environment | dotenv | ^17.2.3 |\n| Language | TypeScript | ^5.9.3 |\n\n资料来源：[package.json:18-26]()\n\n## Prerequisites\n\nBefore using JustOneAPI MCP, ensure you have:\n\n1. **Node.js 18.0.0 or higher** installed\n2. **JustOneAPI Token** obtained from [justoneapi.com](https://dashboard.justoneapi.com/en/login)\n3. **MCP-compatible host** (Claude Desktop, Cursor, or other)\n\n## Installation\n\n### Option 1: npx (Recommended)\n\nThe simplest method requires no installation. Configure your MCP host to run the package directly via npx.\n\n资料来源：[README.md:85-95]()\n\n### Option 2: Local Installation\n\nFor production environments, install the package locally:\n\n```bash\nnpm install -g justoneapi-mcp\n```\n\n## Configuration\n\n### Claude Desktop Configuration\n\nEdit the configuration file for your operating system:\n\n| OS | Configuration Path |\n|----|---------------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n**Configuration Example:**\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_actual_token_here\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md:85-102]()\n\n### Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | - | Your JustOneAPI authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint URL |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after first attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |\n\n资料来源：[README.md:138-147]()\n\n## Available Tools\n\n### Tool Naming Convention\n\nAll tools follow the pattern: `{platform}_{action}_{version}`\n\n### Current Tools\n\n| Tool | Description | Version |\n|------|-------------|---------|\n| `unified_search_v1` | Unified search across multiple platforms | v1 |\n| `kuaishou_search_video_v2` | Platform-specific video search | v2 |\n\n资料来源：[README.md:55-58]()\n\n## Using the Unified Search\n\n### Featured Tool: unified_search_v1\n\nSearch across multiple Chinese social media and news platforms in a single request.\n\n**Supported Platforms:**\n\n- Weibo\n- WeChat\n- Zhihu\n- Douyin\n- Xiaohongshu\n- Bilibili\n- Kuaishou\n- News (aggregated)\n\n资料来源：[README.md:36-37]()\n\n### Parameters\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `keyword` | string | Yes | Search keyword with advanced syntax |\n| `source` | string | No | Platform filter (default: `ALL`) |\n| `start` | string | First page only | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `end` | string | First page only | End time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `nextCursor` | string | Pagination only | Cursor from previous response |\n\n资料来源：[TOOLS.md:21-28]()\n\n### Search Syntax\n\n```mermaid\ngraph LR\n    A[Search Input] --> B{Syntax Type}\n    B --> C[Single: deepseek]\n    B --> D[AND: deepseek chatgpt]\n    B --> E[OR: deepseek~chatgpt]\n    B --> F[NOT: deepseek -chatgpt]\n```\n\n| Syntax | Example | Description |\n|--------|---------|-------------|\n| Single keyword | `deepseek` | Simple search |\n| AND search | `deepseek chatgpt` | Both keywords must appear |\n| OR search | `deepseek~chatgpt` | Either keyword can appear |\n| NOT search | `deepseek -chatgpt` | Exclude keyword |\n\n资料来源：[README.md:48-55]()\n\n### Platform Options\n\n| Value | Description |\n|-------|-------------|\n| `ALL` | Search all platforms (default) |\n| `NEWS` | News articles only |\n| `WEIBO` | Weibo posts |\n| `WEIXIN` | WeChat public accounts |\n| `ZHIHU` | Zhihu Q&A |\n| `DOUYIN` | Douyin videos |\n| `XIAOHONGSHU` | Xiaohongshu posts |\n| `BILIBILI` | Bilibili videos |\n| `KUAISHOU` | Kuaishou videos |\n\n资料来源：[src/tools/search/unified_search_v1.ts:12-19]()\n\n## Usage Examples\n\n### Natural Language Queries\n\nSimply ask your MCP host to perform searches:\n\n```\nSearch for \"AI\" discussions on Chinese social media from last week\n```\n\n```\nFind posts about deepseek on Weibo from January 1st to 5th\n```\n\n```\nSearch for chatgpt OR 机器学习 on all platforms, exclude 广告\n```\n\n### Code-Level Usage\n\n**First Page Request:**\n\n```json\n{\n  \"keyword\": \"AI\",\n  \"source\": \"ALL\",\n  \"start\": \"2025-01-01 00:00:00\",\n  \"end\": \"2025-01-02 23:59:59\"\n}\n```\n\n**Pagination Request:**\n\n```json\n{\n  \"keyword\": \"AI\",\n  \"nextCursor\": \"eyJsYXN0SWQiOiIxMjM0NTY3ODkwIn0=\"\n}\n```\n\n资料来源：[README.md:40-46]()\n\n## Response Format\n\nAll tools return raw JSON from upstream APIs without modification.\n\n### Success Response\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-12-31T14:55:21Z\",\n  \"data\": {\n    // Platform-specific data structure\n  }\n}\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `code` | integer | 0 indicates success, non-zero indicates error |\n| `message` | string/null | Error message if applicable |\n| `recordTime` | string | ISO timestamp of the response |\n| `data` | object | Platform-specific payload |\n\n### Error Response\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n资料来源：[README.md:60-75]()\n\n## Error Handling\n\nThe MCP normalizes all errors into stable MCP error codes.\n\n### Error Codes Reference\n\n| Error Code | Description | Recommended Action |\n|------------|-------------|-------------------|\n| `INVALID_TOKEN` | Token is invalid or inactive | Update `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | Data collection failed | Retry after a short delay |\n| `RATE_LIMITED` | Too many requests | Slow down and retry later |\n| `DAILY_QUOTA_EXCEEDED` | Daily usage limit reached | Wait until tomorrow or upgrade plan |\n| `INSUFFICIENT_BALANCE` | Account balance too low | Top up your account |\n| `PERMISSION_DENIED` | No access to this resource | Contact support |\n| `VALIDATION_ERROR` | Invalid request parameters | Check input values |\n| `INTERNAL_ERROR` | Server error | Retry later |\n| `NETWORK_TIMEOUT` | Request timed out | Check network or retry |\n| `NETWORK_ERROR` | Network connection failed | Check internet connection |\n| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |\n\n资料来源：[README.md:109-130]()\n\n### Error Format Example\n\n```\nERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\n```\n\n资料来源：[README.md:132-134]()\n\n## Pagination\n\nWhen search results have more pages, responses include a `nextCursor` field.\n\n### How to Paginate\n\nSimply ask for more results:\n\n- \"Show me the next page of results\"\n- \"Get more results from the previous search\"\n- \"Continue with the next page\"\n\nThe MCP host automatically:\n\n1. Extracts the `nextCursor` from the previous response\n2. Uses it to fetch the next page\n3. Continues until no more results are available\n\n**Note:** When using `nextCursor` for pagination, you don't need to provide `start`, `end`, or `source` again—the cursor already contains this information.\n\n资料来源：[README.md:76-95]()\n\n## Design Philosophy\n\n### Transport, Not Transformation\n\nJustOneAPI MCP prioritizes:\n\n- **Stability** — Minimal abstraction over upstream APIs\n- **Transparency** — Raw data fidelity without modification\n- **Compatibility** — Long-term compatibility through unchanged responses\n\n### What This MCP Does\n\n- Exposes JustOneAPI endpoints as MCP tools\n- Handles authentication, retries, timeouts, and error normalization\n- Returns raw upstream JSON without field parsing\n- Designed for AI agents and developer workflows\n\n### What This MCP Does NOT Do\n\n- No field parsing or schema normalization\n- No data restructuring\n- No assumptions about upstream response structure\n\n资料来源：[README.md:10-24]()\n\n## Advanced Configuration\n\n### Complete Configuration Example\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\",\n        \"JUSTONEAPI_TIMEOUT_MS\": \"30000\",\n        \"JUSTONEAPI_DEBUG\": \"true\"\n      }\n    }\n  }\n}\n```\n\n### Retry Behavior\n\nThe HTTP client implements automatic retry for:\n\n- Timeout errors (AbortError)\n- HTTP 5xx responses\n- Network failures (ECONNRESET, ECONNREFUSED, ENOTFOUND)\n\n| Attempt | Delay |\n|---------|-------|\n| 1 | Immediate |\n| 2 | 250ms backoff |\n| 3+ | 250ms × attempt |\n\n资料来源：[src/common/http.ts:30-40]()\n\n## Discovery and Verification\n\n### Listing Available Tools\n\n**In Claude Desktop:**\n\n```\nPlease list all available tools from justoneapi-mcp\n```\n\n**In Cursor or other MCP hosts:**\n\nUse your host's tool discovery feature to see all available tools and their parameters.\n\nEach tool includes:\n- Complete parameter descriptions\n- Input validation with Zod schemas\n- Detailed error messages\n- Example values in parameter descriptions\n\n资料来源：[README.md:30-38]()\n\n## Next Steps\n\nAfter setup:\n\n1. **Obtain an API token** from [justoneapi.com](https://dashboard.justoneapi.com/en/login)\n2. **Configure your MCP host** with the token\n3. **Try the unified search** with a simple query\n4. **Explore pagination** for large result sets\n5. **Review error codes** for troubleshooting\n\n## License\n\nMIT License\n\n资料来源：[README.md:152]()\n\n## External Resources\n\n- [JustOneAPI Dashboard](https://dashboard.justoneapi.com/en/login)\n- [JustOneAPI Official Site](https://justoneapi.com)\n- [npm Package](https://www.npmjs.com/package/justoneapi-mcp)\n- [GitHub Repository](https://github.com/justoneapi/justoneapi-mcp)\n\n---\n\n<a id='authentication'></a>\n\n## Authentication\n\n### 相关页面\n\n相关主题：[Getting Started with JustOneAPI MCP](#getting-started), [Configuration Reference](#configuration-reference)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)\n</details>\n\n# Authentication\n\n## Overview\n\nThe justoneapi-mcp server implements a token-based authentication mechanism for securing API access to the JustOneAPI platform. All requests to upstream APIs are authenticated using a bearer-style token passed via query parameters. The authentication system performs early validation at startup and before each API call to ensure credentials are present and properly configured.\n\nThe authentication layer serves as the gatekeeper for all MCP tools, including `unified_search_v1` and `kuaishou_search_video_v2`. It validates the token's presence, encodes it safely for transmission, and provides clear error messages when authentication fails.\n\n## Architecture\n\n```mermaid\ngraph TD\n    A[MCP Host Request] --> B{Token Present?}\n    B -->|No| C[Startup Validation<br/>src/index.ts:45-52]\n    B -->|Yes| D[requireToken Call]\n    \n    D --> E{Token Valid?}\n    E -->|Empty/Whitespace| F[INVALID_TOKEN Error]\n    E -->|Valid| G[Encode Token]\n    \n    G --> H[Append to Query Params]\n    H --> I[HTTP Request via getJson]\n    \n    I --> J{Response Code = 0?}\n    J -->|Yes| K[Return Data]\n    J -->|No| L[Error Mapping<br/>src/common/errors.ts]\n    \n    style F fill:#ffcccc\n    style K fill:#ccffcc\n```\n\n## Configuration\n\n### Environment Variables\n\nAuthentication is configured through environment variables in the MCP server configuration.\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | — | Your JustOneAPI authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint base URL |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after initial attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |\n\n### Token Configuration File\n\nThe token configuration is managed in `src/common/config.ts`.\n\n```typescript\n// src/common/config.ts:1-15\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN;\n  if (!token || !token.trim()) {\n    throw new Error(\n      \"JUSTONEAPI_TOKEN environment variable is required. \" +\n        \"Get your token at https://justoneapi.com\"\n    );\n  }\n  return token;\n}\n```\n\nThe `requireToken()` function validates that the token exists and is not empty or whitespace-only. If validation fails, it throws an error with instructions for obtaining a token. 资料来源：[src/common/config.ts:1-15]()\n\n### Startup Validation\n\nThe server performs authentication validation during startup to fail fast if credentials are missing.\n\n```typescript\n// src/index.ts:45-52\nasync function main() {\n  // Validate configuration on startup\n  if (!process.env.JUSTONEAPI_TOKEN?.trim()) {\n    console.error(\n      \"[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\\n\" +\n        \"Please set the JUSTONEAPI_TOKEN environment variable in your MCP host configuration\"\n    );\n    process.exit(1);\n  }\n  // ... continue with server initialization\n}\n```\n\n资料来源：[src/index.ts:45-52]()\n\n## Token Transmission\n\n### Query Parameter Encoding\n\nTokens are transmitted via URL query parameters for all API requests. The token is URL-encoded to handle special characters safely.\n\n```typescript\n// src/tools/search/unified_search_v1.ts:35-36\nexport async function unifiedSearchV1(input: z.infer<typeof UnifiedSearchV1Input>) {\n  const token = encodeURIComponent(requireToken());\n  const keyword = encodeURIComponent(input.keyword);\n  \n  // Build query parameters\n  const params = new URLSearchParams();\n  params.append(\"token\", token);\n  params.append(\"keyword\", keyword);\n  // ...\n}\n```\n\n资料来源：[src/tools/search/unified_search_v1.ts:35-36]()\n\n### HTTP Request Flow\n\nAll authenticated requests flow through the `getJson()` helper in `src/common/http.ts`.\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Host\n    participant Server as justoneapi-mcp\n    participant API as JustOneAPI\n    \n    MCP->>Server: Tool Request\n    Server->>Server: requireToken()\n    Note over Server: Validate token exists\n    Server->>Server: getJson(pathWithQuery)\n    Server->>API: GET with token in query\n    API-->>Server: JSON Response\n    Server->>Server: Check response.code\n    alt code != 0\n        Server->>Server: toMcpErrorPayload()\n    end\n    Server-->>MCP: Result or Error\n```\n\nThe `getJson()` function includes the following security and reliability features:\n\n| Feature | Implementation | Purpose |\n|---------|---------------|---------|\n| Early token validation | `requireToken()` at start | Fail fast on missing credentials |\n| Timeout handling | `AbortController` | Prevent hanging requests |\n| Automatic retry | Configurable via `JUSTONEAPI_RETRY` | Handle transient failures |\n| Safe logging | `toSafeUrlForLog()` | Mask tokens in debug output |\n\n```typescript\n// src/common/http.ts:40-55\nexport async function getJson(pathWithQuery: string): Promise<UpstreamResponse> {\n  // ensure token exists early (so we can return INVALID_TOKEN)\n  requireToken();\n\n  const url = `${config.baseUrl}${pathWithQuery}`;\n\n  const attempts = 1 + Math.max(0, Number.isFinite(config.retry) ? config.retry : 0);\n  let lastErr: ApiError | unknown;\n\n  for (let attempt = 1; attempt <= attempts; attempt++) {\n    const controller = new AbortController();\n    const timer = setTimeout(() => controller.abort(), config.timeoutMs);\n    // ...\n  }\n}\n```\n\n资料来源：[src/common/http.ts:40-55]()\n\n## Error Handling\n\n### Token-Related Error Codes\n\nWhen authentication fails, the server returns normalized MCP error codes.\n\n| Error Code | Upstream Equivalent | Description | Resolution |\n|------------|---------------------|-------------|------------|\n| `INVALID_TOKEN` | — | Token missing or invalid | Update `JUSTONEAPI_TOKEN` |\n| `RATE_LIMITED` | 302 | Too many requests | Slow down and retry |\n| `DAILY_QUOTA_EXCEEDED` | — | Usage limit reached | Wait or upgrade plan |\n| `INSUFFICIENT_BALANCE` | — | Account balance low | Top up account |\n\n### Error Mapping\n\nThe `mapUpstreamCode()` function in `src/common/errors.ts` maps upstream error codes to MCP error codes.\n\n```typescript\n// src/common/errors.ts:1-30\nfunction mapUpstreamCode(code: number): JOAErrorCode {\n  switch (code) {\n    case 10001:\n      return \"INVALID_TOKEN\";\n    case 10002:\n      return \"INSUFFICIENT_BALANCE\";\n    case 10003:\n      return \"PERMISSION_DENIED\";\n    // ... other mappings\n    default:\n      return \"UPSTREAM_ERROR\";\n  }\n}\n```\n\n资料来源：[src/common/errors.ts:1-30]()\n\n### Error Payload Construction\n\n```typescript\n// src/common/errors.ts:60-75\nexport function toMcpErrorPayload(e: unknown): {\n  code: JOAErrorCode;\n  message: string;\n  upstreamCode?: number;\n  httpStatus?: number;\n} {\n  const error = e as {\n    name?: string;\n    message?: string;\n    upstreamCode?: number;\n    httpStatus?: number;\n    code?: string;\n    cause?: unknown;\n  };\n  \n  // Timeout from AbortController\n  if (error.name === \"AbortError\") {\n    return { code: \"NETWORK_TIMEOUT\", message: buildUserMessage(\"NETWORK_TIMEOUT\") };\n  }\n\n  // Our own thrown upstreamCode (business code)\n  if (error.upstreamCode !== undefined) {\n    const upstreamCode = Number(error.upstreamCode);\n    const mcpCode = mapUpstreamCode(upstreamCode);\n    return {\n      code: mcpCode,\n      message: buildUserMessage(mcpCode, error.message),\n      upstreamCode,\n      httpStatus: typeof error.httpStatus === \"number\" ? error.httpStatus : undefined,\n    };\n  }\n  // ...\n}\n```\n\n资料来源：[src/common/errors.ts:60-75]()\n\n### Error Response Format\n\nAll errors are returned in a standardized format:\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\nExample error responses:\n\n| Scenario | Response Format |\n|----------|-----------------|\n| Invalid token | `ERROR[INVALID_TOKEN] (upstream=N/A): Token is invalid or inactive. Update your JUSTONEAPI_TOKEN` |\n| Rate limited | `ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.` |\n| Network timeout | `ERROR[NETWORK_TIMEOUT] (upstream=N/A): Request timed out. Check network or retry.` |\n\n## Security Considerations\n\n### Token Masking in Logs\n\nDebug logging masks tokens to prevent accidental exposure.\n\n```typescript\n// src/common/config.ts:50-65\nexport function toSafeUrlForLog(fullUrl: string): string {\n  try {\n    const u = new URL(fullUrl);\n    if (u.searchParams.has(\"token\")) {\n      u.searchParams.set(\"token\", maskToken(u.searchParams.get(\"token\") ?? \"\"));\n    }\n    return u.toString();\n  } catch {\n    // Fallback: best-effort masking\n    return fullUrl.replace(/token=([^&]+)/g, (_m, g1) => `token=${maskToken(g1)}`);\n  }\n}\n```\n\n资料来源：[src/common/config.ts:50-65]()\n\n### Retry Behavior with Tokens\n\nRetry logic applies only to transient failures, not authentication errors:\n\n```typescript\n// src/common/http.ts:70-80\nconst retryable =\n  error.name === \"AbortError\" ||\n  (typeof httpStatus === \"number\" && httpStatus >= 500) ||\n  error.code === \"ECONNRESET\" ||\n  error.code === \"ECONNREFUSED\" ||\n  error.code === \"ENOTFOUND\";\n```\n\n| Retryable | Not Retryable |\n|-----------|---------------|\n| Timeout (`AbortError`) | HTTP 4xx errors |\n| HTTP 5xx errors | Business code != 0 |\n| Network reset | Invalid token |\n\n## Configuration Examples\n\n### Claude Desktop Configuration\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_actual_token_here\"\n      }\n    }\n  }\n}\n```\n\n### Custom Timeout and Debug Settings\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_actual_token_here\",\n        \"JUSTONEAPI_TIMEOUT_MS\": \"30000\",\n        \"JUSTONEAPI_DEBUG\": \"true\"\n      }\n    }\n  }\n}\n```\n\nWhen debug mode is enabled, logs appear with masked tokens:\n\n```\n[justoneapi] GET https://api.justoneapi.com/api/search/v1?token=sk_***&keyword=AI (attempt 1/2)\n```\n\n## Obtaining a Token\n\n1. Visit [https://justoneapi.com](https://justoneapi.com)\n2. Create an account or sign in at [https://dashboard.justoneapi.com](https://dashboard.justoneapi.com/en/login)\n3. Generate an API token from your dashboard\n4. Configure the token in your MCP host\n\n## Related Documentation\n\n- [README.md](README.md) — Installation and quick start guide\n- [TOOLS.md](TOOLS.md) — Complete tool reference with authentication parameters\n\n---\n\n<a id='system-architecture'></a>\n\n## System Architecture\n\n### 相关页面\n\n相关主题：[HTTP Client Implementation](#http-client), [Unified Search Tool](#unified-search-tool), [Kuaishou Video Search Tool](#kuaishou-video-search)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)\n- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n</details>\n\n# System Architecture\n\n## Overview\n\nThe justoneapi-mcp is a Model Context Protocol (MCP) server that provides a bridge between AI assistants and the JustOneAPI social media search platform. The system enables natural language querying across multiple Chinese social media platforms including Weibo, WeChat, Zhihu, Douyin, Xiaohongshu, Bilibili, Kuaishou, and news sources.\n\nThe architecture follows a **transport-oriented design philosophy**, prioritizing stability, transparency, and raw data fidelity over convenience. The MCP server returns unmodified upstream API responses to ensure maximum data fidelity and long-term compatibility.\n\n## High-Level Architecture\n\n```mermaid\ngraph TD\n    subgraph \"MCP Host Environment\"\n        A[MCP Client<br/>Claude Desktop/Cursor]\n    end\n    \n    subgraph \"justoneapi-mcp Server\"\n        B[MCP SDK Server]\n        C[Tool Handlers]\n        D[Common Libraries]\n        E[HTTP Client]\n    end\n    \n    subgraph \"External Services\"\n        F[JustOneAPI<br/>api.justoneapi.com]\n        G[Chinese Social Media<br/>Platforms]\n    end\n    \n    A -->|MCP Protocol| B\n    B --> C\n    C --> D\n    D --> E\n    E -->|HTTPS| F\n    F -->|API Responses| G\n    \n    style A fill:#e1f5fe\n    style F fill:#fff3e0\n    style G fill:#f3e5f5\n```\n\n## Core Components\n\n### Component Overview\n\n| Component | File Location | Purpose |\n|-----------|---------------|---------|\n| MCP Server | `src/index.ts` | Entry point, tool registration, request routing |\n| Tool Handlers | `src/tools/*` | Individual tool implementations |\n| HTTP Client | `src/common/http.ts` | HTTP request management with retry logic |\n| Configuration | `src/common/config.ts` | Token management, URL sanitization |\n| Error Handling | `src/common/errors.ts` | Error code mapping and payload transformation |\n\n### Module Dependency Graph\n\n```mermaid\ngraph LR\n    subgraph \"Entry Point\"\n        A[src/index.ts]\n    end\n    \n    subgraph \"Tool Layer\"\n        B[unified_search_v1.ts]\n        C[kuaishou_search_video_v2.ts]\n    end\n    \n    subgraph \"Common Layer\"\n        D[config.ts]\n        E[http.ts]\n        F[errors.ts]\n    end\n    \n    subgraph \"External\"\n        G[JustOneAPI]\n    end\n    \n    A --> B\n    A --> C\n    B --> D\n    B --> E\n    B --> F\n    C --> D\n    C --> E\n    C --> F\n    E --> F\n    E --> G\n    \n    style A fill:#ffecb3\n    style D fill:#c8e6c9\n    style E fill:#c8e6c9\n    style F fill:#c8e6c9\n    style G fill:#fff3e0\n```\n\n## Tool Registration System\n\n### Request Flow\n\n```mermaid\nsequenceDiagram\n    participant Client as MCP Client\n    participant Server as MCP Server\n    participant Handler as Tool Handler\n    participant HTTP as HTTP Client\n    participant API as JustOneAPI\n    \n    Client->>Server: Tool Request (unified_search_v1)\n    Server->>Handler: Forward Input\n    Handler->>Handler: Validate with Zod Schema\n    Handler->>HTTP: GET /api/search/v1\n    HTTP->>HTTP: Token encoding\n    HTTP->>API: Request with token\n    API-->>HTTP: JSON Response\n    HTTP-->>Handler: Raw JSON\n    Handler-->>Server: JSON Response\n    Server-->>Client: MCP Response\n```\n\n### Tool Registration Pattern\n\nTools are registered in `src/index.ts` using the MCP SDK's `registerTool` method. Each tool registration includes:\n\n1. **Tool name** - Unique identifier following `{platform}_{action}_{version}` pattern\n2. **Input schema** - Zod schema for parameter validation\n3. **Handler function** - Async function that processes requests\n\n```typescript\n// Registration pattern from src/index.ts:55-72\nserver.registerTool(\n  \"unified_search_v1\",\n  {\n    description: \"Unified search across multiple platforms...\",\n    inputSchema: UnifiedSearchV1Input.shape,\n  },\n  async (input) => {\n    try {\n      const data = await unifiedSearchV1(input);\n      return {\n        content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n      };\n    } catch (e: unknown) {\n      const m = toMcpErrorPayload(e);\n      return {\n        isError: true,\n        content: [{ type: \"text\", text: `ERROR[${m.code}]: ${m.message}` }],\n      };\n    }\n  }\n);\n```\n\n## HTTP Client Architecture\n\n### Retry Strategy\n\nThe HTTP client in `src/common/http.ts` implements an intelligent retry mechanism with exponential backoff.\n\n```mermaid\ngraph TD\n    A[Request] --> B{Attempt < Max?}\n    B -->|Yes| C{Check Retryable?}\n    C -->|AbortError| D[Retry]\n    C -->|HTTP 5xx| D\n    C -->|ECONNRESET| D\n    C -->|ECONNREFUSED| D\n    C -->|ENOTFOUND| D\n    C -->|No| E[Throw Error]\n    D --> F[Wait 250ms × Attempt]\n    F --> G[Retry Request]\n    G --> B\n    B -->|No| H[Throw Last Error]\n    \n    style E fill:#ffcdd2\n    style H fill:#ffcdd2\n    style D fill:#c8e6c9\n```\n\n### Retryable Conditions\n\n| Condition | Type | Retry Behavior |\n|-----------|------|----------------|\n| `AbortError` | Timeout | ✅ Retry |\n| HTTP 5xx | Server Error | ✅ Retry |\n| `ECONNRESET` | Connection Reset | ✅ Retry |\n| `ECONNREFUSED` | Connection Refused | ✅ Retry |\n| `ENOTFOUND` | DNS Lookup Failed | ✅ Retry |\n| HTTP 4xx | Client Error | ❌ No Retry |\n| Business Errors | API Code | ❌ No Retry |\n\n资料来源：[src/common/http.ts:29-36]()\n\n## Error Handling System\n\n### Error Flow\n\n```mermaid\ngraph TD\n    A[Exception Thrown] --> B{Error Type?}\n    B -->|AbortError| C[NETWORK_TIMEOUT]\n    B -->|upstreamCode exists| D[Map Upstream Code]\n    B -->|httpStatus exists| E[UPSTREAM_ERROR]\n    B -->|cause or network code| F[NETWORK_ERROR]\n    B -->|Unknown| G[UPSTREAM_ERROR]\n    \n    D --> H[Return MCP Error Payload]\n    C --> H\n    E --> H\n    F --> H\n    G --> H\n    \n    style C fill:#fff9c4\n    style D fill:#fff9c4\n    style E fill:#fff9c4\n    style F fill:#fff9c4\n```\n\n### Error Code Mapping\n\n| MCP Error Code | Upstream Code | Description | User Action |\n|----------------|---------------|-------------|-------------|\n| `INVALID_TOKEN` | N/A | Token invalid/inactive | Update `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | N/A | Data collection failed | Retry after delay |\n| `RATE_LIMITED` | 302 | Too many requests | Slow down, retry later |\n| `DAILY_QUOTA_EXCEEDED` | N/A | Daily limit reached | Wait until tomorrow |\n| `INSUFFICIENT_BALANCE` | N/A | Low account balance | Top up account |\n| `PERMISSION_DENIED` | N/A | No access to resource | Contact support |\n| `VALIDATION_ERROR` | N/A | Invalid parameters | Check input values |\n| `INTERNAL_ERROR` | N/A | Server error | Retry later |\n| `NETWORK_TIMEOUT` | N/A | Request timed out | Check network |\n| `NETWORK_ERROR` | N/A | Connection failed | Check internet |\n| `UPSTREAM_ERROR` | N/A | Unspecified upstream | Retry or contact support |\n\n## Configuration Management\n\n### Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | ✅ Yes | - | API authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint base URL |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after first attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |\n\n### Token Management\n\nThe `requireToken()` function in `src/common/config.ts` validates and retrieves the API token:\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN?.trim();\n  if (!token) {\n    throw new Error(\"JUSTONEAPI_TOKEN environment variable is required\");\n  }\n  return token;\n}\n```\n\n### URL Sanitization for Logging\n\nThe `toSafeUrlForLog()` function masks sensitive tokens in URLs before logging:\n\n```mermaid\ngraph LR\n    A[Full URL with token] --> B[Parse URL]\n    B --> C{Token param exists?}\n    C -->|Yes| D[Mask token value]\n    C -->|No| E[Return original]\n    D --> F[Return sanitized URL]\n    E --> F\n```\n\n## Tool Specifications\n\n### Available Tools\n\n| Tool Name | Purpose | Version |\n|-----------|---------|---------|\n| `unified_search_v1` | Multi-platform social media search | v1 |\n| `kuaishou_search_video_v2` | Kuaishou-specific video search | v2 |\n\n### Platform Support\n\nThe unified search supports the following platforms:\n\n| Platform | Identifier | Type |\n|----------|------------|------|\n| All Platforms | `ALL` | Default |\n| News | `NEWS` | News content |\n| Weibo | `WEIBO` | Social posts |\n| WeChat | `WEIXIN` | Articles |\n| Zhihu | `ZHIHU` | Q&A content |\n| Douyin | `DOUYIN` | Short videos |\n| Xiaohongshu | `XIAOHONGSHU` | Lifestyle content |\n| Bilibili | `BILIBILI` | Long-form videos |\n| Kuaishou | `KUAISHOU` | Short videos |\n\n### Search Syntax Support\n\n| Operator | Syntax | Description |\n|----------|--------|-------------|\n| Single keyword | `deepseek` | Basic search |\n| AND search | `deepseek chatgpt` | Both keywords required |\n| OR search | `deepseek~chatgpt` | Either keyword matches |\n| NOT search | `deepseek -chatgpt` | Exclude keyword |\n\n## Data Flow Architecture\n\n### Unified Search Flow\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant Handler as unified_search_v1\n    participant HTTP as getJson\n    participant API as JustOneAPI\n    \n    User->>Handler: {keyword, source, start, end}\n    Handler->>Handler: Encode parameters\n    Handler->>HTTP: GET /api/search/v1?token=...&keyword=...\n    HTTP->>API: HTTPS Request\n    API-->>HTTP: {code, message, data, nextCursor}\n    HTTP-->>Handler: Raw JSON response\n    Handler-->>User: JSON with raw data\n    \n    Note over User,API: Raw upstream data returned unchanged\n```\n\n## Technology Stack\n\n### Production Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `@modelcontextprotocol/sdk` | ^1.25.1 | MCP protocol implementation |\n| `zod` | ^4.3.4 | Schema validation |\n| `dotenv` | ^17.2.3 | Environment variable loading |\n\n### Development Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `typescript` | ^5.9.3 | Type safety |\n| `eslint` | ^9.39.2 | Code linting |\n| `prettier` | ^3.7.4 | Code formatting |\n| `ts-node` | ^10.9.2 | TypeScript execution |\n\n### Node.js Requirement\n\n- **Minimum version**: Node.js 18.0.0\n- **Runtime**: ES2022+ module system\n\n## Startup and Initialization\n\n### Configuration Validation\n\nOn server startup, the main function validates that required configuration exists:\n\n```mermaid\ngraph TD\n    A[Server Start] --> B{JUSTONEAPI_TOKEN set?}\n    B -->|No| C[Exit with Error]\n    B -->|Yes| D[Start MCP Server]\n    D --> E[Register Tools]\n    E --> F[Listen for Requests]\n    \n    style C fill:#ffcdd2\n    style F fill:#c8e6c9\n```\n\nThe token validation occurs in `src/index.ts` before the MCP server begins accepting connections, ensuring early failure with clear error messages.\n\n## Design Philosophy\n\nThe architecture embodies the **\"Transport, not transformation\"** principle:\n\n1. **Maximum Data Fidelity** - Raw upstream responses are returned unmodified\n2. **No Field Parsing** - Data structures remain as received from upstream APIs\n3. **No Data Restructuring** - No normalization or transformation of response formats\n4. **Long-term Compatibility** - Stable interface despite upstream API changes\n\n---\n\n<a id='http-client'></a>\n\n## HTTP Client Implementation\n\n### 相关页面\n\n相关主题：[System Architecture](#system-architecture), [Error Handling](#error-handling), [Configuration Reference](#configuration-reference)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n</details>\n\n# HTTP Client Implementation\n\n## Overview\n\nThe HTTP Client Implementation provides a centralized, reusable HTTP communication layer for the JustOneAPI MCP server. It handles all outbound API requests with built-in retry logic, timeout management, error normalization, and secure logging. The implementation follows a \"transport, not transformation\" philosophy, returning raw upstream responses to maintain maximum data fidelity.\n\n**Key Responsibilities:**\n- Execute HTTP GET requests to the JustOneAPI backend\n- Manage request timeouts using AbortController\n- Implement automatic retry with exponential backoff for transient failures\n- Normalize errors into structured MCP error codes\n- Ensure secure logging by masking sensitive tokens\n\n资料来源：[src/common/http.ts:48-68]()\n\n## Architecture\n\n```mermaid\ngraph TD\n    A[Tool Handler] --> B[API Function<br/>e.g., unifiedSearchV1]\n    B --> C[getJson]\n    C --> D{Token Validation}\n    D -->|Invalid| E[INVALID_TOKEN Error]\n    D -->|Valid| F[Build URL]\n    F --> G[Fetch with Timeout]\n    G --> H{Response OK?}\n    H -->|No| I[Retry Logic]\n    I --> G\n    H -->|Yes| J[Parse JSON]\n    J --> K[Business Code OK?]\n    K -->|No| L[Error Mapping]\n    K -->|Yes| M[Return Response]\n    L --> N[MCP Error Payload]\n    \n    style E fill:#ff6b6b\n    style N fill:#ffa500\n    style M fill:#51cf66\n```\n\n### Request Flow\n\n1. **Token Validation** - Ensures `JUSTONEAPI_TOKEN` exists before making requests 资料来源：[src/common/http.ts:60]() [src/common/config.ts]()\n\n2. **URL Construction** - Builds full URL with base URL and query parameters 资料来源：[src/common/http.ts:62]()\n\n3. **Fetch Execution** - Makes HTTP request with AbortController timeout 资料来源：[src/common/http.ts:70-76]()\n\n4. **Response Processing** - Validates HTTP status and parses JSON 资料来源：[src/common/http.ts:78-88]()\n\n5. **Business Logic Check** - Validates upstream `code === 0` for success 资料来源：[src/common/errors.ts:1-18]()\n\n## Core Components\n\n### ApiError Type\n\nThe `ApiError` interface extends the standard `Error` type with additional properties for HTTP-level and business-level error information.\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `httpStatus` | `number \\| undefined` | HTTP status code from the fetch response |\n| `upstreamCode` | `number \\| undefined` | Business error code from upstream API response |\n| `payload` | `unknown \\| undefined` | Full response payload when available |\n| `code` | `string \\| undefined` | Node.js error code for network errors |\n| `cause` | `unknown \\| undefined` | Underlying error cause |\n\n资料来源：[src/common/http.ts:39-45]()\n\n### getJson Function\n\nThe main HTTP client function that performs GET requests with comprehensive error handling.\n\n```typescript\nexport async function getJson(pathWithQuery: string): Promise<UpstreamResponse>\n```\n\n**Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `pathWithQuery` | `string` | API endpoint path including query string |\n\n**Returns:** `Promise<UpstreamResponse>` - Parsed JSON response from the API\n\n**Behavior:**\n- Validates token presence before any network call\n- Supports configurable retry attempts (default: 1 retry after initial attempt)\n- Implements 250ms backoff between retries\n- Returns raw upstream JSON without transformation\n\n资料来源：[src/common/http.ts:48-68]()\n\n## Retry Logic\n\nThe HTTP client implements intelligent retry behavior for transient failures.\n\n### Retry Conditions\n\n| Condition | Retryable | Description |\n|-----------|-----------|-------------|\n| `AbortError` | Yes | Request timeout |\n| HTTP 5xx | Yes | Server-side errors |\n| `ECONNRESET` | Yes | Connection reset by peer |\n| `ECONNREFUSED` | Yes | Connection refused |\n| `ENOTFOUND` | Yes | DNS lookup failure |\n| HTTP 4xx | No | Client errors |\n| Business code != 0 | No | Application-level errors |\n\n```mermaid\ngraph LR\n    A[Request Attempt] --> B{Error Type?}\n    B -->|AbortError| C[Retry]\n    B -->|5xx| C\n    B -->|Network Error| C\n    B -->|4xx| D[No Retry]\n    B -->|Business Error| D\n    C --> E{Attempts<br/>Exhausted?}\n    E -->|No| A\n    E -->|Yes| F[Throw Error]\n    D --> F\n```\n\n**Retry Configuration:**\n- Maximum attempts: `1 + JUSTONEAPI_RETRY` (default: 2 total attempts)\n- Backoff delay: `250ms * attempt_number`\n\n资料来源：[src/common/http.ts:68-96]()\n\n## Timeout Management\n\nTimeouts are implemented using the AbortController API for native browser/Node.js compatibility.\n\n| Setting | Environment Variable | Default | Description |\n|---------|---------------------|---------|-------------|\n| Request Timeout | `JUSTONEAPI_TIMEOUT_MS` | `20000` | Timeout in milliseconds |\n\n**Implementation:**\n\n```typescript\nconst controller = new AbortController();\nconst timer = setTimeout(() => controller.abort(), config.timeoutMs);\n\nconst res = await fetch(url, { method: \"GET\", signal: controller.signal });\n// ... process response ...\nclearTimeout(timer); // Clean up timer\n```\n\nWhen a timeout occurs, an `AbortError` is thrown, which triggers the retry logic.\n\n资料来源：[src/common/http.ts:70-76]()\n\n## Error Handling\n\n### Error Code Mapping\n\nThe system maps upstream error codes to standardized MCP error codes.\n\n| Upstream Code | MCP Code | Description |\n|---------------|----------|-------------|\n| 301 | `INVALID_TOKEN` | Token is invalid or inactive |\n| 302 | `INVALID_TOKEN` | Token validation failed |\n| 401 | `INVALID_TOKEN` | Authentication required |\n| 402 | `INSUFFICIENT_BALANCE` | Account balance too low |\n| 403 | `PERMISSION_DENIED` | No access to resource |\n| 404 | `PERMISSION_DENIED` | Resource not found |\n| 422 | `VALIDATION_ERROR` | Invalid request parameters |\n| 429 | `RATE_LIMITED` | Too many requests |\n| 500 | `INTERNAL_ERROR` | Server error |\n| 503 | `UPSTREAM_ERROR` | Service unavailable |\n\n资料来源：[src/common/errors.ts:19-53]()\n\n### Error Payload Structure\n\nWhen an error occurs, the `toMcpErrorPayload` function converts the error to a structured format.\n\n```typescript\n{\n  code: JOAErrorCode;      // Normalized MCP error code\n  message: string;         // Human-readable message\n  upstreamCode?: number;  // Original upstream error code\n  httpStatus?: number;     // HTTP status code\n}\n```\n\n**Error Priority:**\n1. `AbortError` → `NETWORK_TIMEOUT`\n2. `upstreamCode` present → Maps to appropriate MCP code\n3. `httpStatus` present → `UPSTREAM_ERROR`\n4. `cause` or network error code → `NETWORK_ERROR`\n5. Fallback → `UPSTREAM_ERROR`\n\n资料来源：[src/common/errors.ts:55-91]()\n\n## Security Features\n\n### Token Masking\n\nAll API tokens are masked in logs to prevent credential leakage.\n\n```typescript\nexport function toSafeUrlForLog(fullUrl: string): string {\n  try {\n    const u = new URL(fullUrl);\n    if (u.searchParams.has(\"token\")) {\n      u.searchParams.set(\"token\", maskToken(u.searchParams.get(\"token\") ?? \"\"));\n    }\n    return u.toString();\n  } catch {\n    // Fallback: best-effort masking\n    return fullUrl.replace(/token=([^&]+)/g, (_m, g1) => `token=${maskToken(g1)}`);\n  }\n}\n```\n\n**Features:**\n- Primary method uses URL API for accurate parsing\n- Fallback regex for non-standard URLs\n- Two-level fallback to prevent logging failures\n\n资料来源：[src/common/config.ts:58-74]()\n\n### Debug Logging\n\nWhen `JUSTONEAPI_DEBUG=true`, requests are logged to stderr with masked tokens:\n\n```\n[justoneapi] GET https://api.justoneapi.com/api/search/v1?token=***&keyword=AI (attempt 1/2)\n```\n\n资料来源：[src/common/http.ts:72-74]()\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | - | API authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint base URL |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after initial attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging |\n\n资料来源：[README.md:103-110]()\n\n## Usage Examples\n\n### Basic Tool Implementation\n\nTools in this MCP server use the HTTP client through dedicated API functions:\n\n```typescript\n// From unified_search_v1.ts\nexport async function unifiedSearchV1(input: z.infer<typeof UnifiedSearchV1Input>) {\n  const token = encodeURIComponent(requireToken());\n  const keyword = encodeURIComponent(input.keyword);\n\n  const params = new URLSearchParams();\n  params.append(\"token\", token);\n  params.append(\"keyword\", keyword);\n\n  if (input.source) {\n    params.append(\"source\", input.source);\n  }\n\n  if (input.nextCursor) {\n    params.append(\"nextCursor\", input.nextCursor);\n  } else {\n    params.append(\"start\", input.start);\n    params.append(\"end\", input.end);\n  }\n\n  return await getJson(`/api/search/v1?${params.toString()}`);\n}\n```\n\n资料来源：[src/tools/search/unified_search_v1.ts:29-54]()\n\n### Error Response Format\n\nAll errors are returned in a consistent MCP format:\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n**Example:**\n```\nERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\n```\n\n资料来源：[README.md:86-89]()\n\n## Integration with MCP Server\n\nThe HTTP client is integrated into the MCP server's tool registration system:\n\n```typescript\nserver.registerTool(\n  \"unified_search_v1\",\n  {\n    description: \"Unified search across multiple platforms...\",\n    inputSchema: UnifiedSearchV1Input.shape,\n  },\n  async (input) => {\n    try {\n      const data = await unifiedSearchV1(input);\n      return {\n        content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n      };\n    } catch (e: unknown) {\n      const m = toMcpErrorPayload(e);\n      return {\n        isError: true,\n        content: [\n          {\n            type: \"text\",\n            text: `ERROR[${m.code}] (upstream=${m.upstreamCode ?? \"N/A\"}): ${m.message}`,\n          },\n        ],\n      };\n    }\n  }\n);\n```\n\n资料来源：[src/index.ts:50-70]()\n\n## Dependencies\n\nThe HTTP client implementation uses the following dependencies:\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `@modelcontextprotocol/sdk` | `^1.25.1` | MCP server framework |\n| `zod` | `^4.3.4` | Schema validation |\n| `dotenv` | `^17.2.3` | Environment variable loading |\n\n资料来源：[package.json:16-23]()\n\n---\n\n<a id='unified-search-tool'></a>\n\n## Unified Search Tool\n\n### 相关页面\n\n相关主题：[Kuaishou Video Search Tool](#kuaishou-video-search), [Tool Naming Conventions and Standards](#tool-conventions), [Error Handling](#error-handling)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n</details>\n\n# Unified Search Tool\n\n## Overview\n\nThe Unified Search Tool (`unified_search_v1`) is the primary MCP (Model Context Protocol) tool provided by justoneapi-mcp. It enables aggregated searching across multiple Chinese social media platforms and news sources through a single API interface.\n\n**Key Characteristics:**\n- Searches 8 platforms simultaneously in one request\n- Returns raw, unmodified JSON from upstream APIs\n- Supports advanced search syntax (AND, OR, NOT operators)\n- Implements cursor-based pagination\n- UTC+8 timezone for all date/time operations\n\n资料来源：[TOOLS.md:43-60]()\n\n## Architecture\n\n### System Context\n\n```mermaid\ngraph TD\n    subgraph \"MCP Host\"\n        A[Claude / Cursor]\n    end\n    \n    subgraph \"justoneapi-mcp\"\n        B[Server Entry<br/>src/index.ts]\n        C[Tool Handler<br/>unified_search_v1]\n        D[HTTP Client<br/>src/common/http.ts]\n        E[Error Handler<br/>src/common/errors.ts]\n    end\n    \n    subgraph \"External\"\n        F[JustOneAPI<br/>api.justoneapi.com]\n    end\n    \n    A -->|MCP Protocol| B\n    B --> C\n    C --> D\n    D -->|GET /api/search/v1| F\n    F -->|JSON Response| D\n    D --> E\n    \n    style F fill:#f9f,stroke:#333\n    style D fill:#bbf,stroke:#333\n    style E fill:#fbb,stroke:#333\n```\n\n### Request Flow\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Host\n    participant Server as justoneapi-mcp\n    participant HTTP as HTTP Client\n    participant API as JustOneAPI\n    \n    MCP->>Server: unified_search_v1(params)\n    Server->>HTTP: getJson(endpoint, params)\n    \n    loop Retry Logic (max 2 attempts)\n        HTTP->>API: GET /api/search/v1\n        API-->>HTTP: JSON Response\n        \n        alt Success (code=0)\n            HTTP-->>Server: data\n        else Retryable Error (5xx, timeout)\n            HTTP->>HTTP: Wait 250ms * attempt\n        end\n    end\n    \n    alt Non-retryable Error\n        Server->>Server: toMcpErrorPayload(e)\n        Server-->>MCP: ERROR[...]\n    else Success\n        Server-->>MCP: Raw JSON response\n    end\n```\n\n资料来源：[src/index.ts:29-47]()\n资料来源：[src/common/http.ts:1-44]()\n\n## Parameters\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `keyword` | string | Yes | Search keyword with advanced syntax support |\n| `source` | string | No | Platform filter (default: `ALL`) |\n| `start` | string | Conditional | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `end` | string | Conditional | End time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `nextCursor` | string | No | Pagination cursor from previous response |\n\n**Note:** `start` and `end` are required for the first page request. They must be omitted when using `nextCursor` for pagination.\n\n资料来源：[src/tools/search/unified_search_v1.ts:16-41]()\n\n## Supported Platforms\n\n| Platform ID | Description |\n|-------------|-------------|\n| `ALL` | Search all platforms (default) |\n| `NEWS` | News articles |\n| `WEIBO` | Sina Weibo |\n| `WEIXIN` | WeChat public accounts |\n| `ZHIHU` | Zhihu Q&A |\n| `DOUYIN` | Douyin (TikTok China) |\n| `XIAOHONGSHU` | Xiaohongshu (Little Red Book) |\n| `BILIBILI` | Bilibili video platform |\n| `KUAISHOU` | Kuaishou short video |\n\n资料来源：[src/tools/search/unified_search_v1.ts:9-16]()\n\n## Search Syntax\n\nThe unified search supports advanced query operators:\n\n| Operator | Syntax | Example | Description |\n|----------|--------|---------|-------------|\n| Single keyword | `word` | `deepseek` | Search for exact term |\n| AND (implicit) | `word1 word2` | `deepseek chatgpt` | Both terms must appear |\n| OR | `word1~word2` | `deepseek~chatgpt` | Either term may appear |\n| NOT | `word -exclude` | `deepseek -chatgpt` | Exclude term from results |\n\n**Syntax Rules:**\n- Single keyword: Plain text match\n- AND operator: Space-separated terms (implicit)\n- OR operator: Tilde (`~`) separator\n- NOT operator: Dash (`-`) prefix on exclusion term\n\n资料来源：[TOOLS.md:62-69]()\n\n## Pagination\n\n### Cursor-Based Pagination\n\n```mermaid\ngraph LR\n    A[First Request<br/>start, end] --> B[Response<br/>data + nextCursor]\n    B --> C{Next Page?}\n    C -->|Yes| D[Next Request<br/>nextCursor]\n    D --> E[Response<br/>data + nextCursor]\n    E --> C\n    C -->|No| F[Done]\n```\n\n### Pagination Rules\n\n1. **First Request:** Include `start` and `end` time parameters\n2. **Subsequent Requests:** Use `nextCursor` instead of time parameters\n3. **Final Page:** Response without `nextCursor` indicates completion\n\nWhen `nextCursor` is provided, `start`, `end`, and `source` parameters should be omitted—the cursor contains all necessary pagination context.\n\n资料来源：[TOOLS.md:32-42]()\n\n## Response Format\n\n### Success Response\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-01-02T14:55:21Z\",\n  \"data\": {\n    // Platform-specific data structure\n  }\n}\n```\n\n### Error Response\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n| Error Code | Description | Recovery Action |\n|------------|-------------|-----------------|\n| `INVALID_TOKEN` | Token invalid or inactive | Update `JUSTONEAPI_TOKEN` |\n| `RATE_LIMITED` | Too many requests | Slow down and retry |\n| `DAILY_QUOTA_EXCEEDED` | Daily limit reached | Wait or upgrade plan |\n| `INSUFFICIENT_BALANCE` | Low account balance | Top up account |\n| `VALIDATION_ERROR` | Invalid parameters | Check input values |\n| `NETWORK_TIMEOUT` | Request timed out | Check network/retry |\n| `NETWORK_ERROR` | Connection failed | Check internet |\n| `UPSTREAM_ERROR` | Server error | Retry or contact support |\n\n资料来源：[src/common/errors.ts:1-72]()\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | — | API authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout (ms) |\n| `JUSTONEAPI_RETRY` | No | `1` | Retry attempts |\n| `JUSTONEAPI_DEBUG` | No | `false` | Debug logging |\n\n### MCP Server Configuration\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\"\n      }\n    }\n  }\n}\n```\n\n## Usage Examples\n\n### Basic Multi-Platform Search\n\n```\nSearch for \"AI\" discussions on all platforms from January 1-5, 2025\n```\n\n**Generated Parameters:**\n```json\n{\n  \"keyword\": \"AI\",\n  \"source\": \"ALL\",\n  \"start\": \"2025-01-01 00:00:00\",\n  \"end\": \"2025-01-05 23:59:59\"\n}\n```\n\n### Platform-Specific Search\n\n```\nSearch for \"chatgpt\" on Weibo only, from December 1st to January 2nd\n```\n\n**Generated Parameters:**\n```json\n{\n  \"keyword\": \"chatgpt\",\n  \"source\": \"WEIBO\",\n  \"start\": \"2024-12-01 00:00:00\",\n  \"end\": \"2025-01-02 23:59:59\"\n}\n```\n\n### Complex Query with OR and NOT\n\n```\nSearch for posts containing \"deepseek\" OR \"机器学习\" but NOT \"广告\"\n```\n\n**Generated Parameters:**\n```json\n{\n  \"keyword\": \"deepseek~机器学习 -广告\",\n  \"source\": \"ZHIHU\",\n  \"start\": \"2025-01-01 00:00:00\",\n  \"end\": \"2025-01-31 23:59:59\"\n}\n```\n\n### Pagination Request\n\nWhen continuing from a previous response:\n\n```json\n{\n  \"keyword\": \"AI\",\n  \"nextCursor\": \"eyJsYXN0SWQiOiIxMjM0NTY3ODkwIn0=\"\n}\n```\n\n资料来源：[README.md:1-80]()\n\n## Design Philosophy\n\nThe Unified Search Tool follows the **\"Transport, not transformation\"** principle:\n\n- **Maximum data fidelity:** Returns unmodified upstream JSON responses\n- **No field parsing:** Raw response structure preserved\n- **No data restructuring:** Original field names and hierarchy maintained\n- **Long-term compatibility:** Interface stability prioritized over convenience\n\nThis approach ensures that clients receive complete, unmodified data for any downstream processing needs.\n\n资料来源：[README.md:95-105]()\n\n## Implementation\nError with Openai API: output new_sensitive (1027)\n\nPlease check that you have set the OPENAI_API_KEY environment variable with a valid API key.\n\n---\n\n<a id='kuaishou-video-search'></a>\n\n## Kuaishou Video Search Tool\n\n### 相关页面\n\n相关主题：[Unified Search Tool](#unified-search-tool), [Tool Naming Conventions and Standards](#tool-conventions)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n</details>\n\n# Kuaishou Video Search Tool\n\n## Overview\n\nThe **Kuaishou Video Search Tool** (`kuaishou_search_video_v2`) is a Model Context Protocol (MCP) tool that enables users to search for videos on Kuaishou, a major Chinese short-video platform. It integrates with the JustOneAPI service to provide programmatic access to Kuaishou's video search functionality.\n\n**Key Characteristics:**\n- Platform-specific search targeting Kuaishou exclusively\n- Pagination support for result browsing\n- Returns raw, untransformed JSON responses from the upstream API\n- Zod-based input validation with clear parameter descriptions\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:1-16]()\n\n## Architecture\n\n### System Context\n\nThe tool operates within the broader justoneapi-mcp server architecture, which uses the MCP SDK to expose tools to AI hosts like Claude Desktop or Cursor.\n\n```mermaid\ngraph TD\n    A[MCP Host<br/>Claude Desktop/Cursor] -->|registerTool| B[justoneapi-mcp Server]\n    B -->|registerTool| C[kuaishou_search_video_v2]\n    C -->|requireToken| D[Config Module]\n    C -->|HTTP GET| E[JustOneAPI Gateway]\n    E -->|Proxies to| F[Kuaishou API]\n    F -->|JSON Response| E\n    E -->|Raw JSON| C\n    C -->|Formatted Result| B\n    B -->|MCP Response| A\n```\n\n### Component Responsibilities\n\n| Component | File | Responsibility |\n|-----------|------|-----------------|\n| Tool Handler | `src/tools/kuaishou/search_video_v2.ts` | Input validation, API call orchestration |\n| HTTP Client | `src/common/http.ts` | Request execution with retry logic |\n| Error Handler | `src/common/errors.ts` | Error code mapping and formatting |\n| Config | `src/common/config.ts` | Token retrieval and validation |\n| Server Entry | `src/index.ts` | Tool registration with MCP SDK |\n\n资料来源：[src/index.ts:18-37]()\n\n## Input Parameters\n\nThe `KuaishouSearchVideoV2Input` schema defines the tool's input contract using Zod validation.\n\n### Parameter Specification\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `keyword` | `string` | Yes | - | Search keyword, e.g., `'dance'` |\n| `page` | `number` | No | `1` | Page number for pagination (must be ≥ 1) |\n\n### Zod Schema Definition\n\n```typescript\nexport const KuaishouSearchVideoV2Input = z.object({\n  keyword: z.string().min(1).describe(\"Search keyword, e.g. 'dance'\"),\n  page: z.number().int().min(1).default(1).describe(\"Page number, default 1\"),\n});\n```\n\n**Validation Rules:**\n- `keyword` must be a non-empty string (minimum 1 character)\n- `page` must be a positive integer; defaults to `1` if not provided\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:4-8]()\n\n## API Request Flow\n\n### Request Construction\n\nThe tool builds the API request by encoding parameters and appending them to the endpoint URL:\n\n```typescript\nexport async function kuaishouSearchVideoV2(input: z.infer<typeof KuaishouSearchVideoV2Input>) {\n  const token = encodeURIComponent(requireToken());\n  const keyword = encodeURIComponent(input.keyword);\n  const page = input.page;\n\n  return await getJson(\n    `/api/kuaishou/search-video/v2?token=${token}&keyword=${keyword}&page=${page}`\n  );\n}\n```\n\n### Request Flow Diagram\n\n```mermaid\nsequenceDiagram\n    participant Client as MCP Tool Handler\n    participant Config as Config Module\n    participant HTTP as HTTP Client\n    participant API as JustOneAPI Gateway\n\n    Client->>Config: requireToken()\n    Config-->>Client: Returns JUSTONEAPI_TOKEN\n    \n    Client->>Client: encodeURIComponent(token, keyword, page)\n    \n    Client->>HTTP: getJson(/api/kuaishou/search-video/v2?...)\n    HTTP->>API: GET Request\n    \n    alt Success (2xx)\n        API-->>HTTP: { code: 0, data: {...} }\n        HTTP-->>Client: Parsed JSON object\n    else Error (4xx/5xx)\n        API-->>HTTP: Error response\n        HTTP-->>Client: Throws ApiError\n    end\n```\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:10-16]()\n\n## Error Handling\n\nAll errors are normalized into MCP error codes with actionable messages.\n\n### Error Code Reference\n\n| Error Code | Description | User Action |\n|------------|-------------|-------------|\n| `INVALID_TOKEN` | Token is invalid or inactive | Update `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | Data collection failed | Retry after a short delay |\n| `RATE_LIMITED` | Too many requests | Slow down and retry later |\n| `DAILY_QUOTA_EXCEEDED` | Daily usage limit reached | Wait until tomorrow or upgrade plan |\n| `INSUFFICIENT_BALANCE` | Account balance too low | Top up account |\n| `VALIDATION_ERROR` | Invalid request parameters | Check input values |\n| `INTERNAL_ERROR` | Server error | Retry later |\n| `NETWORK_TIMEOUT` | Request timed out | Check network or retry |\n| `NETWORK_ERROR` | Network connection failed | Check internet connection |\n| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |\n\n### Error Response Format\n\nErrors are returned in a standardized format:\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\nExample:\n```\nERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\n```\n\n资料来源：[README.md:78-95]()\n\n### Error Processing in MCP Handler\n\n```typescript\nasync (input) => {\n  try {\n    const data = await kuaishouSearchVideoV2(input);\n    return {\n      content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n    };\n  } catch (e: unknown) {\n    const m = toMcpErrorPayload(e);\n    return {\n      isError: true,\n      content: [{\n        type: \"text\",\n        text: `ERROR[${m.code}] (upstream=${m.upstreamCode ?? \"N/A\"}): ${m.message}`,\n      }],\n    };\n  }\n}\n```\n\n资料来源：[src/index.ts:20-36]()\n\n## HTTP Retry Mechanism\n\nThe underlying HTTP client implements automatic retry logic for transient failures.\n\n### Retry Conditions\n\n| Condition | Retryable |\n|-----------|-----------|\n| Timeout (`AbortError`) | ✅ Yes |\n| HTTP 5xx status codes | ✅ Yes |\n| `ECONNRESET` | ✅ Yes |\n| `ECONNREFUSED` | ✅ Yes |\n| `ENOTFOUND` | ✅ Yes |\n| HTTP 4xx status codes | ❌ No |\n\n### Retry Strategy\n\n- **Attempts**: Configurable via `JUSTONEAPI_RETRY` (default: 1 retry after first attempt)\n- **Backoff**: 250ms × attempt number between retries\n- **Timeout**: Configurable via `JUSTONEAPI_TIMEOUT_MS` (default: 20000ms)\n\n```mermaid\ngraph TD\n    A[HTTP Request] --> B{Success?}\n    B -->|Yes| C[Return JSON]\n    B -->|No| D{Retryable Error?}\n    D -->|No| E[Throw Error]\n    D -->|Yes| F{Attempts Remaining?}\n    F -->|No| E\n    F -->|Yes| G[Wait 250ms × attempt]\n    G --> A\n```\n\n资料来源：[src/common/http.ts:32-42]()\n\n## Tool Registration\n\nThe tool is registered with the MCP server using the SDK's `registerTool` method.\n\n```typescript\nserver.registerTool(\n  \"kuaishou_search_video_v2\",\n  {\n    description:\n      \"Search Kuaishou videos by keyword. Returns the original raw JSON response from upstream without field normalization.\",\n    inputSchema: KuaishouSearchVideoV2Input.shape,\n  },\n  async (input) => {\n    // Implementation...\n  }\n);\n```\n\n**Registration Details:**\n- **Tool Name**: `kuaishou_search_video_v2`\n- **Schema**: `KuaishouSearchVideoV2Input.shape` (Zod-derived)\n- **Response Type**: Raw JSON text with indentation\n\n资料来源：[src/index.ts:18-37]()\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | - | Authentication token for JustOneAPI |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after first attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging |\n\n### Token Security\n\nThe configuration module masks tokens in log output for security:\n\n```typescript\nexport function toSafeUrlForLog(fullUrl: string): string {\n  try {\n    const u = new URL(fullUrl);\n    if (u.searchParams.has(\"token\")) {\n      u.searchParams.set(\"token\", maskToken(u.searchParams.get(\"token\") ?? \"\"));\n    }\n    return u.toString();\n  } catch {\n    return fullUrl.replace(/token=([^&]+)/g, (_m, g1) => `token=${maskToken(g1)}`);\n  }\n}\n```\n\n资料来源：[src/common/config.ts:27-41]()\n\n## Response Contract\n\n### Success Response Format\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-12-31T14:55:21Z\",\n  \"data\": {\n    // Platform-specific data structure from Kuaishou API\n  }\n}\n```\n\n### Field Descriptions\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `code` | `number` | `0` indicates success; non-zero indicates error |\n| `message` | `string \\| null` | Error description if code ≠ 0 |\n| `recordTime` | `string` | Timestamp of the response (ISO 8601) |\n| `data` | `object` | Raw response from upstream Kuaishou API |\n\n### Raw JSON Philosophy\n\nThe tool intentionally returns **unmodified upstream responses**:\n- ✅ Maximum data fidelity\n- ✅ No field parsing or normalization\n- ✅ No data restructuring\n- ✅ Long-term compatibility\n\n资料来源：[TOOLS.md:69-86]()\n\n## Usage Examples\n\n### Claude Desktop / Cursor\n\n```\nSearch for \"dance\" videos on Kuaishou, page 1\n```\n\n### MCP Host Tool Invocation\n\n```json\n{\n  \"name\": \"kuaishou_search_video_v2\",\n  \"input\": {\n    \"keyword\": \"dance\",\n    \"page\": 1\n  }\n}\n```\n\n### Expected Response Structure\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-01-15T10:30:00Z\",\n  \"data\": {\n    // Kuaishou video search results\n    // (exact structure determined by upstream API)\n  }\n}\n```\n\n## Dependencies\n\nThe tool relies on the following npm packages:\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `@modelcontextprotocol/sdk` | `^1.25.1` | MCP server and tool framework |\n| `zod` | `^4.3.4` | Schema validation and type inference |\n| `dotenv` | `^17.2.3` | Environment variable loading |\n\n资料来源：[package.json:18-26]()\n\n## Related Documentation\n\n| Document | Description |\n|----------|-------------|\n| [README.md](README.md) | Main project documentation |\n| [TOOLS.md](TOOLS.md) | Complete tools reference |\n| [unified_search_v1](./unified%20Search%20Tool.md) | Multi-platform search alternative |\n\n---\n\n<a id='tool-conventions'></a>\n\n## Tool Naming Conventions and Standards\n\n### 相关页面\n\n相关主题：[Unified Search Tool](#unified-search-tool), [Kuaishou Video Search Tool](#kuaishou-video-search)\n\n<details>\n<summary>Relevant Source Files</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n</details>\n\n# Tool Naming Conventions and Standards\n\n## Overview\n\nThe justoneapi-mcp project implements a standardized naming convention for all MCP (Model Context Protocol) tools. This convention ensures consistency, predictability, and scalability across the entire tool ecosystem. The naming standard follows a three-part pattern that clearly communicates the tool's scope, purpose, and version in a single identifier.\n\nThe primary objectives of this naming standard include:\n\n- **Discoverability**: Tools can be easily identified and located based on their naming pattern\n- **Versioning**: API evolution is managed through version suffixes\n- **Consistency**: All contributors follow the same pattern, reducing cognitive load\n- **Scalability**: New tools can be added following the established convention without ambiguity\n\n资料来源：[README.md:73]()\n\n## Naming Pattern Structure\n\nAll tools in the justoneapi-mcp server follow a unified naming pattern:\n\n```\n{platform}_{action}_{version}\n```\n\nThis three-component structure provides immediate context about each tool's purpose and scope.\n\n### Component Breakdown\n\n| Component | Purpose | Examples | Description |\n|-----------|---------|----------|-------------|\n| `platform` | Identifies the target service | `kuaishou`, `unified` | The platform or scope the tool operates on |\n| `action` | Describes the operation | `search`, `search_video` | What the tool does, can be compound with underscore |\n| `version` | Indicates API version | `v1`, `v2` | Version of the underlying API endpoint |\n\n### Syntax Rules\n\n1. **Delimiter**: Components are separated by underscores (`_`), not camelCase or hyphens\n2. **Lowercase**: All components use lowercase letters exclusively\n3. **Compound actions**: Multi-word actions use underscores (e.g., `search_video`)\n4. **Version format**: Version uses lowercase `v` followed by a number (e.g., `v1`, `v2`)\n\n资料来源：[README.md:74-76]()\n\n## Current Tool Registry\n\nThe following table lists all currently available tools in the justoneapi-mcp server:\n\n| Tool Name | Platform | Action | Version | Purpose |\n|-----------|----------|--------|---------|---------|\n| `unified_search_v1` | unified | search | v1 | Multi-platform search across Weibo, WeChat, Zhihu, Douyin, Xiaohongshu, Bilibili, Kuaishou, and News |\n| `kuaishou_search_video_v2` | kuaishou | search_video | v2 | Platform-specific video search for Kuaishou |\n\n资料来源：[src/index.ts:24-46]()\n\n## Platform Component Standards\n\n### Reserved Platform Identifiers\n\nThe platform component identifies the target service or search domain:\n\n| Platform | Description | Supported Actions |\n|----------|-------------|-------------------|\n| `unified` | Aggregated multi-platform search | `search` |\n| `kuaishou` | Kuaishou video platform | `search_video` |\n| `weibo` | Weibo social platform (planned) | `search` |\n| `zhihu` | Zhihu Q&A platform (planned) | `search` |\n| `douyin` | Douyin short video (planned) | `search_video` |\n| `bilibili` | Bilibili video platform (planned) | `search_video` |\n\n资料来源：[TOOLS.md:34-40]()\n\n### Naming Future Platforms\n\nWhen adding new platforms, follow these guidelines:\n\n1. Use the lowercase English name of the platform\n2. If the platform name contains multiple words, use the most common short form\n3. Avoid abbreviations unless they are universally recognized\n4. Ensure uniqueness across all existing platform names\n\n## Action Component Standards\n\n### Single-Word Actions\n\nSimple actions use a single lowercase word:\n\n- `search` - General search functionality\n- `analyze` - Data analysis operations\n- `fetch` - Data retrieval operations\n\n### Compound Actions\n\nActions with multiple components use underscores to separate words:\n\n| Action | Components | Meaning |\n|--------|------------|---------|\n| `search_video` | search + video | Video search functionality |\n| `search_user` | search + user | User profile search |\n| `fetch_trending` | fetch + trending | Trending content retrieval |\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:1-15]()\n\n## Version Component Standards\n\n### Versioning Strategy\n\nThe version component follows semantic versioning principles adapted for API evolution:\n\n| Version Pattern | Meaning | Upgrade Consideration |\n|----------------|---------|----------------------|\n| `v1` | Initial stable release | Breaking changes unlikely |\n| `v2` | Major version with potential breaking changes | Check changelog before upgrading |\n| `v{n}` | Future major versions | Each increment may introduce breaking changes |\n\n### Version Upgrade Triggers\n\nConsider incrementing the version when:\n\n- **Breaking API changes**: Parameter types, required fields, or return structure change\n- **Behavior changes**: Same inputs produce different outputs\n- **Deprecations**: Removing functionality from a tool\n- **Major architectural changes**: Internal refactoring affecting external behavior\n\n### Version Coexistence\n\nMultiple versions of the same tool may coexist, allowing gradual migration:\n\n- Old versions remain available for backward compatibility\n- New versions receive new features and improvements\n- Deprecation notices appear in documentation\n\n## Implementation Architecture\n\n### Tool Registration Flow\n\nThe following diagram illustrates how tools are registered and exposed through the MCP server:\n\n```mermaid\ngraph TD\n    A[Tool Definition File] --> B[Zod Input Schema]\n    A --> C[Tool Handler Function]\n    B --> D[registerTool in index.ts]\n    C --> D\n    D --> E[McpServer Instance]\n    E --> F[STDIO Transport]\n    F --> G[MCP Host Client]\n    \n    H[Tool Name: kuaishou_search_video_v2] --> D\n    I[Tool Name: unified_search_v1] --> D\n```\n\n### Tool Registration Code Structure\n\nTools are registered in `src/index.ts` using the MCP SDK's `registerTool` method:\n\n```typescript\nserver.registerTool(\n  \"kuaishou_search_video_v2\",\n  {\n    description: \"Search Kuaishou videos by keyword...\",\n    inputSchema: KuaishouSearchVideoV2Input.shape,\n  },\n  async (input) => {\n    try {\n      const data = await kuaishouSearchVideoV2(input);\n      return { content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }] };\n    } catch (e: unknown) {\n      const m = toMcpErrorPayload(e);\n      return { isError: true, content: [...] };\n    }\n  }\n);\n```\n\n资料来源：[src/index.ts:24-46]()\n\n## Input Schema Conventions\n\n### Zod-Based Validation\n\nAll tools use Zod schemas for input validation, ensuring type safety and automatic documentation:\n\n```typescript\nexport const KuaishouSearchVideoV2Input = z.object({\n  keyword: z.string().min(1).describe(\"Search keyword, e.g. 'dance'\"),\n  page: z.number().int().min(1).default(1).describe(\"Page number, default 1\"),\n});\n```\n\n### Schema Documentation Pattern\n\nEach parameter includes:\n\n| Field | Purpose | Methods |\n|-------|---------|---------|\n| `describe()` | Human-readable description | Required for all parameters |\n| `.min()` | Minimum value constraint | For strings and numbers |\n| `.default()` | Default value if omitted | Optional parameters |\n| `.optional()` | Marks non-required parameters | Optional parameters |\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:4-9]()\n\n## Unified Search Tool Specification\n\n### `unified_search_v1`\n\nThe unified search tool provides cross-platform search capabilities with advanced syntax support.\n\n#### Parameters\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `keyword` | string | Yes | Search keyword with syntax: single `word`, AND `word1 word2`, OR `word1~word2`, NOT `word -excluded` |\n| `source` | enum | No | Platform filter: `ALL`, `NEWS`, `WEIBO`, `WEIXIN`, `ZHIHU`, `DOUYIN`, `XIAOHONGSHU`, `BILIBILI`, `KUAISHOU` |\n| `start` | string | Conditional | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8). Required for first page |\n| `end` | string | Conditional | End time `yyyy-MM-dd HH:mm:ss` (UTC+8). Required for first page |\n| `nextCursor` | string | No | Pagination cursor from previous response |\n\n#### Search Syntax Examples\n\n| Syntax | Example | Meaning |\n|--------|---------|---------|\n| Single keyword | `deepseek` | Posts containing \"deepseek\" |\n| AND search | `deepseek chatgpt` | Posts containing both terms |\n| OR search | `deepseek~chatgpt` | Posts containing either term |\n| NOT search | `deepseek -chatgpt` | Posts with \"deepseek\" but not \"chatgpt\" |\n\n资料来源：[src/tools/search/unified_search_v1.ts:1-42]()\n\n## Platform-Specific Tool Specification\n\n### `kuaishou_search_video_v2`\n\nThe Kuaishou video search tool provides platform-specific video search functionality.\n\n#### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `keyword` | string | Yes | - | Search keyword, minimum 1 character |\n| `page` | number | No | 1 | Page number, must be positive integer |\n\n#### API Endpoint\n\n```\nGET /api/kuaishou/search-video/v2?token={token}&keyword={keyword}&page={page}\n```\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:1-15]()\n\n## Error Handling Integration\n\n### Standardized Error Codes\n\nAll tools return errors in a consistent format that includes the MCP error code:\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n### Error Code Mapping\n\n| MCP Code | Trigger Condition | Upstream Code | User Action |\n|----------|-------------------|---------------|-------------|\n| `INVALID_TOKEN` | Invalid or inactive token | - | Update `JUSTONEAPI_TOKEN` |\n| `RATE_LIMITED` | Too many requests | 302 | Slow down and retry |\n| `DAILY_QUOTA_EXCEEDED` | Daily limit reached | - | Wait until tomorrow |\n| `INSUFFICIENT_BALANCE` | Low account balance | - | Top up account |\n| `NETWORK_TIMEOUT` | Request timeout | - | Check network/retry |\n| `COLLECT_FAILED` | Data collection failed | - | Retry after delay |\n| `VALIDATION_ERROR` | Invalid parameters | - | Check input values |\n\n资料来源：[src/common/errors.ts:1-60]()\n\n### Error Handler Implementation\n\n```typescript\nexport function toMcpErrorPayload(e: unknown): {\n  code: JOAErrorCode;\n  message: string;\n  upstreamCode?: number;\n  httpStatus?: number;\n} {\n  const error = e as {\n    name?: string;\n    message?: string;\n    upstreamCode?: number;\n    httpStatus?: number;\n  };\n  \n  if (error.name === \"AbortError\") {\n    return { code: \"NETWORK_TIMEOUT\", message: buildUserMessage(\"NETWORK_TIMEOUT\") };\n  }\n  // ... additional error type handling\n}\n```\n\n## Best Practices\n\n### Creating New Tools\n\nFollow these steps to add a new tool:\n\n1. **Choose the name** following the `{platform}_{action}_{version}` pattern\n2. **Create the tool file** in `src/tools/{platform}/`\n3. **Define the Zod schema** with descriptive parameter documentation\n4. **Implement the handler** using `getJson` from `common/http.ts`\n5. **Register in `index.ts`** with description and input schema\n6. **Add tests** for input validation and error handling\n\n### File Naming Conventions\n\n| Tool Type | Location | File Name Pattern |\n|-----------|----------|-------------------|\n| Platform-specific | `src/tools/{platform}/` | `{action}_{version}.ts` |\n| Unified tools | `src/tools/search/` | `{action}_{version}.ts` |\n| Utility functions | `src/common/` | `{purpose}.ts` |\n\n### Documentation Requirements\n\nEach tool must document:\n\n- All parameters with types and descriptions\n- Required vs optional parameters\n- Default values where applicable\n- Error codes that may be returned\n- Example usage scenarios\n\n## Summary\n\nThe tool naming convention in justoneapi-mcp provides a clear, consistent, and scalable approach to defining MCP tools. By following the `{platform}_{action}_{version}` pattern, developers can quickly understand any tool's purpose and scope. The Zod-based schema validation ensures type safety, while standardized error handling provides consistent feedback across all operations.\n\nKey takeaways:\n\n- Use underscores to separate all components\n- Always include the version suffix (`v1`, `v2`, etc.)\n- Use compound action names with underscores when needed\n- Follow the established file structure for organization\n- Leverage Zod schemas for validation and documentation\n\n---\n\n<a id='configuration-reference'></a>\n\n## Configuration Reference\n\n### 相关页面\n\n相关主题：[Authentication](#authentication), [HTTP Client Implementation](#http-client)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n</details>\n\n# Configuration Reference\n\n## Overview\n\nThe justoneapi-mcp server provides a centralized configuration system that manages all runtime settings through environment variables. The configuration module serves as the single source of truth for API credentials, connection parameters, and debugging options.\n\nConfiguration is loaded from environment variables at startup and validated before the MCP server begins accepting requests. The system follows a \"fail-fast\" design pattern, terminating immediately if required parameters are missing.\n\n资料来源：[src/index.ts:58-64]()\n\n## Environment Variables\n\n### Required Variables\n\n| Variable | Type | Required | Description |\n|----------|------|----------|-------------|\n| `JUSTONEAPI_TOKEN` | string | **Yes** | Your JustOneAPI authentication token. Used for all API requests. |\n\nThe server validates the token presence on startup. If the token is missing or empty, the server exits with an error message directing users to set the environment variable.\n\n资料来源：[src/index.ts:58-68]()\n\n### Optional Variables\n\n| Variable | Type | Default | Description |\n|----------|------|---------|-------------|\n| `JUSTONEAPI_BASE_URL` | string | `https://api.justoneapi.com` | Base API endpoint for all requests |\n| `JUSTONEAPI_TIMEOUT_MS` | number | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | number | `1` | Number of retries after initial request failure |\n| `JUSTONEAPI_DEBUG` | boolean | `false` | Enable debug logging to stderr |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## Configuration Module Architecture\n\n### Module Structure\n\nThe configuration system consists of the following exported functions and objects:\n\n```typescript\n// Implemented in src/common/config.ts\nexport const config: Config;        // Runtime configuration object\nexport function requireToken(): string;    // Validates and returns token\nexport function toSafeUrlForLog(url: string): string;  // Sanitizes URLs for logging\n```\n\n### Configuration Object\n\nThe internal `Config` interface defines the shape of the runtime configuration:\n\n```typescript\ninterface Config {\n  token: string;\n  baseUrl: string;\n  timeoutMs: number;\n  retry: number;\n  debug: boolean;\n}\n```\n\n## Token Management\n\n### Token Validation\n\nThe `requireToken()` function performs strict validation on the token:\n\n1. Reads `JUSTONEAPI_TOKEN` from environment\n2. Trims whitespace from the value\n3. Checks if the token is empty\n4. Returns the validated token string\n\nIf validation fails, an error is thrown immediately, preventing server startup.\n\n资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n\n### Token Usage in HTTP Layer\n\nThe token is used in HTTP requests by encoding it for URL safety:\n\n```typescript\nconst token = encodeURIComponent(requireToken());\n```\n\nThis encoded token is appended to all API requests, including:\n\n- Unified search: `/api/search/v1?token=${token}&keyword=${keyword}`\n- Kuaishou video search: `/api/kuaishou/search-video/v2?token=${token}&keyword=${keyword}`\n\n资料来源：[src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n\n## HTTP Layer Integration\n\n### Request Flow\n\n```mermaid\ngraph TD\n    A[API Tool Called] --> B[getJson Function]\n    B --> C[requireToken Validation]\n    C --> D[Build URL with Config]\n    D --> E[Create AbortController]\n    E --> F[Execute Fetch Request]\n    F --> G{Success?}\n    G -->|Yes| H[Parse JSON Response]\n    G -->|No| I{Check Retryable Error}\n    I -->|Yes| J[Wait 250ms × Attempt]\n    J --> E\n    I -->|No| K[Throw Error]\n    H --> L[Return UpstreamResponse]\n    K --> M[Error Handler]\n```\n\n### Configuration Parameters Used\n\nThe HTTP module consumes configuration for request handling:\n\n| Parameter | Usage | Purpose |\n|-----------|-------|---------|\n| `config.baseUrl` | URL construction | Prepend to all API paths |\n| `config.timeoutMs` | Request timeout | Set AbortController timer |\n| `config.retry` | Retry logic | Calculate total attempt count |\n| `config.debug` | Logging | Print request details to stderr |\n\n资料来源：[src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n### Retry Mechanism\n\nThe retry logic uses the `JUSTONEAPI_RETRY` configuration value:\n\n```typescript\nconst attempts = 1 + Math.max(0, Number.isFinite(config.retry) ? config.retry : 0);\n```\n\nRetry occurs only for specific error types:\n\n| Error Type | Retryable |\n|------------|-----------|\n| `AbortError` (timeout) | ✅ Yes |\n| HTTP 5xx status | ✅ Yes |\n| `ECONNRESET` | ✅ Yes |\n| `ECONNREFUSED` | ✅ Yes |\n| `ENOTFOUND` | ✅ Yes |\n| HTTP 4xx status | ❌ No |\n| Business code ≠ 0 | ❌ No |\n\n资料来源：[src/common/http.ts:31-39]()\n\n### Timeout Configuration\n\nThe timeout is applied using AbortController:\n\n```typescript\nconst timer = setTimeout(() => controller.abort(), config.timeoutMs);\n```\n\nWith the default of 20000ms (20 seconds), requests exceeding this duration are cancelled and may be retried based on retry configuration.\n\n资料来源：[src/common/http.ts:44-45]()\n\n## Debug Logging\n\nWhen `JUSTONEAPI_DEBUG` is set to `true`, detailed request information is logged to stderr:\n\n```typescript\nif (config.debug) {\n  console.error(`[justoneapi] GET ${toSafeUrlForLog(url)} (attempt ${attempt}/${attempts})`);\n}\n```\n\n### URL Sanitization\n\nThe `toSafeUrlForLog()` function ensures tokens are never exposed in logs by sanitizing URLs before output.\n\n资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n\n## Error Handling Integration\n\nConfiguration errors are mapped to MCP error codes:\n\n| Upstream Code | MCP Error Code | User Message |\n|---------------|----------------|--------------|\n| - | `INVALID_TOKEN` | Token is invalid or inactive |\n| - | `NETWORK_TIMEOUT` | Request timed out |\n| - | `NETWORK_ERROR` | Network connection failed |\n| - | `INTERNAL_ERROR` | Server error |\n\n资料来源：[src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n## MCP Server Configuration\n\n### Claude Desktop Configuration\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\",\n        \"JUSTONEAPI_TIMEOUT_MS\": \"30000\",\n        \"JUSTONEAPI_DEBUG\": \"true\"\n      }\n    }\n  }\n}\n```\n\n### Configuration File Locations\n\n| Operating System | Config File Path |\n|-----------------|------------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## Dependencies\n\nThe configuration system depends on the following packages:\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `zod` | ^4.3.4 | Input validation schemas |\n| `dotenv` | ^17.2.3 | Environment variable loading |\n| `@modelcontextprotocol/sdk` | ^1.25.1 | MCP protocol implementation |\n\n资料来源：[package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n## Startup Validation\n\nThe server performs validation at startup in `src/index.ts`:\n\n```typescript\nasync function main() {\n  // Validate configuration on startup\n  if (!process.env.JUSTONEAPI_TOKEN?.trim()) {\n    console.error(\n      \"[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\\n\" +\n        \"Please set the JUSTONEAPI_TOKEN environment variable in your MCP host configuration\"\n    );\n    process.exit(1);\n  }\n  // ... server initialization\n}\n```\n\nThis ensures users receive immediate feedback about missing configuration before the server attempts any network operations.\n\n资料来源：[src/index.ts:58-68]()\n\n## Summary\n\nThe configuration system provides:\n\n- **Centralized management** via environment variables\n- **Fail-fast validation** on server startup\n- **Safe logging** with token sanitization\n- **Configurable timeouts** and retry behavior\n- **Debug capabilities** for troubleshooting\n\nAll configuration flows through a single module (`src/common/config.ts`) ensuring consistent behavior across the entire application.\n\n---\n\n<a id='mcp-integration'></a>\n\n## MCP Host Integration\n\n### 相关页面\n\n相关主题：[Getting Started with JustOneAPI MCP](#getting-started)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n</details>\n\n# MCP Host Integration\n\n## Overview\n\nMCP Host Integration refers to the process of connecting the **justoneapi-mcp** server to an MCP (Model Context Protocol) host application, enabling AI assistants like Claude Desktop, Cursor, or other MCP-compatible hosts to access Chinese social media search capabilities.\n\nThe integration follows the MCP specification, using JSON-RPC over stdio for communication between the host and server. This architecture allows any MCP-compatible host to discover and invoke the tools provided by justoneapi-mcp without custom integrations.\n\n资料来源：[README.md:1-50]()\n\n## Architecture\n\n### System Components\n\nThe MCP Host Integration consists of three primary layers:\n\n```mermaid\ngraph TD\n    A[\"MCP Host<br/>(Claude Desktop, Cursor)\"] --> B[\"justoneapi-mcp Server\"]\n    B --> C[\"JustOneAPI Backend\"]\n    B --> D[\"Zod Validation Layer\"]\n    \n    A --> E[\"StdioServerTransport\"]\n    E --> B\n    \n    style A fill:#e1f5fe\n    style B fill:#fff3e0\n    style C fill:#e8f5e9\n```\n\n| Component | Description | Technology |\n|-----------|-------------|------------|\n| MCP Host | Client application providing AI capabilities | Claude Desktop, Cursor, etc. |\n| Transport | Communication channel | stdio (Standard Input/Output) |\n| MCP Server | Tool registry and request handler | @modelcontextprotocol/sdk |\n| Validation | Input schema validation | Zod v4 |\n| API Client | Upstream API communication | Native fetch with retry logic |\n\n资料来源：[src/index.ts:1-20]()\n\n### Request Flow\n\n```mermaid\nsequenceDiagram\n    participant Host as MCP Host\n    participant Server as justoneapi-mcp\n    participant API as JustOneAPI\n    \n    Host->>Server: Tool invocation (JSON-RPC)\n    Server->>Server: Validate with Zod schema\n    Server->>API: HTTP request with token\n    API->>API: Process search request\n    API-->>Server: Raw JSON response\n    Server-->>Host: JSON-RPC response\n```\n\n## Supported MCP Hosts\n\nThe justoneapi-mcp server is compatible with any application implementing the MCP specification:\n\n| Host | Platform | Configuration Path |\n|------|----------|---------------------|\n| Claude Desktop | macOS, Windows, Linux | Platform-specific config |\n| Cursor | macOS, Windows, Linux | MCP settings |\n| Other MCP hosts | Any | Host-specific |\n\n资料来源：[README.md:50-80]()\n\n## Installation and Configuration\n\n### Quick Start with npx\n\nThe recommended installation method uses `npx` for zero-configuration deployment:\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md:60-75]()\n\n### Configuration Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | Yes | - | Your JustOneAPI authentication token |\n| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint |\n| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |\n| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after initial attempt |\n| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |\n\n资料来源：[README.md:130-145]()\n\n### Configuration File Locations\n\n| Operating System | Configuration Path |\n|------------------|-------------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n资料来源：[README.md:55-70]()\n\n## Tool Discovery\n\n### Discovery Mechanism\n\nWhen the MCP host starts, the justoneapi-mcp server automatically registers all available tools. The host queries the server's capabilities and receives a manifest of all callable tools with their input schemas.\n\n```mermaid\ngraph LR\n    A[Host Startup] --> B[Initialize Stdio Transport]\n    B --> C[Register Tools via SDK]\n    C --> D[Handle list_tools Request]\n    D --> E[Return Tool Manifest]\n    \n    F[User Request] --> G[Validate Input with Zod]\n    G --> H[Execute Tool Handler]\n    H --> I[Return JSON Response]\n```\n\n### Available Tools\n\n| Tool Name | Version | Description | Parameters |\n|-----------|---------|-------------|------------|\n| `unified_search_v1` | v1 | Multi-platform search | keyword, source, start, end, nextCursor |\n| `kuaishou_search_video_v2` | v2 | Kuaishou video search | keyword, nextCursor |\n\n资料来源：[TOOLS.md:15-50]()\n\n### Discovery Command\n\nTo discover available tools in Claude Desktop:\n\n```\nPlease list all available tools from justoneapi-mcp\n```\n\n资料来源：[README.md:35-45]()\n\n## Tool Input Validation\n\n### Schema Validation Flow\n\nAll tool inputs pass through Zod validation before execution:\n\n```mermaid\ngraph TD\n    A[User Input] --> B[Zod Schema Validation]\n    B -->|Valid| C[Execute Tool Handler]\n    B -->|Invalid| D[Return VALIDATION_ERROR]\n    C --> E[API Request]\n    E --> F[JSON Response]\n    \n    style D fill:#ffcdd2\n    style F fill:#c8e6c9\n```\n\n### Example: unified_search_v1 Schema\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `keyword` | string | Yes | Search keyword with syntax support |\n| `source` | enum | No | Platform filter (default: ALL) |\n| `start` | string | First page* | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `end` | string | First page* | End time `yyyy-MM-dd HH:mm:ss` (UTC+8) |\n| `nextCursor` | string | Pagination | Cursor from previous response |\n\n*Required for first page unless using `nextCursor`\n\n资料来源：[src/tools/search/unified_search_v1.ts:10-45]()\n\n### Search Syntax Support\n\n| Operator | Example | Behavior |\n|----------|---------|----------|\n| Single keyword | `deepseek` | Search for exact term |\n| AND | `deepseek chatgpt` | Both terms must appear |\n| OR | `deepseek~chatgpt` | Either term can appear |\n| NOT | `deepseek -chatgpt` | Exclude term |\n\n资料来源：[README.md:95-110]()\n\n## Error Handling Integration\n\n### Error Mapping\n\nThe server normalizes upstream errors into stable MCP error codes:\n\n| Error Code | Upstream Condition | User Action |\n|------------|-------------------|-------------|\n| `INVALID_TOKEN` | Invalid/inactive token | Update JUSTONEAPI_TOKEN |\n| `COLLECT_FAILED` | Data collection failed | Retry after delay |\n| `RATE_LIMITED` | Too many requests | Slow down and retry |\n| `DAILY_QUOTA_EXCEEDED` | Daily limit reached | Wait until tomorrow |\n| `INSUFFICIENT_BALANCE` | Low account balance | Top up account |\n| `PERMISSION_DENIED` | No access to resource | Contact support |\n| `VALIDATION_ERROR` | Invalid parameters | Check input values |\n| `INTERNAL_ERROR` | Server error | Retry later |\n| `NETWORK_TIMEOUT` | Request timed out | Check network/retry |\n| `NETWORK_ERROR` | Connection failed | Check internet |\n| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |\n\n资料来源：[src/common/errors.ts:50-80]()\n\n### Error Response Format\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\nExample:\n```\nERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\n```\n\n资料来源：[README.md:115-125]()\n\n### Retry Logic\n\nThe HTTP client implements automatic retry for transient failures:\n\n| Retry Trigger | Backoff Strategy |\n|--------------|------------------|\n| AbortError (timeout) | 250ms × attempt |\n| HTTP 5xx | 250ms × attempt |\n| ECONNRESET | 250ms × attempt |\n| ECONNREFUSED | 250ms × attempt |\n| ENOTFOUND | 250ms × attempt |\n\n资料来源：[src/common/http.ts:15-30]()\n\n## Session and Pagination\n\n### Cursor-Based Pagination\n\nSearch results use `nextCursor` for pagination to maintain state across requests:\n\n```mermaid\ngraph LR\n    A[First Request] -->|start + end| B[Page 1 Response]\n    B -->|nextCursor| C[Second Request]\n    C -->|nextCursor| D[Page 2 Response]\n    D -->|nextCursor| E[Continue...]\n    \n    style A fill:#e3f2fd\n    style D fill:#e8f5e9\n```\n\n### Continuing Results\n\nWhen results have more pages, simply ask:\n- \"Show me the next page of results\"\n- \"Get more results from the previous search\"\n- \"Continue with the next page\"\n\nThe MCP host automatically extracts `nextCursor` and fetches subsequent pages without requiring `start`, `end`, or `source` parameters again.\n\n资料来源：[README.md:78-92]()\n\n## Dependencies\n\n### Runtime Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| @modelcontextprotocol/sdk | ^1.25.1 | MCP server implementation |\n| zod | ^4.3.4 | Schema validation |\n| dotenv | ^17.2.3 | Environment configuration |\n\n### Development Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| typescript | ^5.9.3 | Type safety |\n| eslint | ^9.39.2 | Code linting |\n| prettier | ^3.7.4 | Code formatting |\n\n资料来源：[package.json:15-35]()\n\n## Design Philosophy\n\n### Transport, Not Transformation\n\nThe justoneapi-mcp server adheres to a \"Transport, not transformation\" principle:\n\n- **Maximum data fidelity** - Returns unmodified upstream responses\n- **No field parsing** - Raw JSON from APIs\n- **No data restructuring** - Preserves original schema\n- **Long-term compatibility** - Schema stability over convenience\n\nThis ensures that:\n1. No data is lost in translation\n2. Users receive complete API responses\n3. Breaking changes in upstream APIs are visible immediately\n4. Advanced users can access any field from the response\n\n资料来源：[README.md:155-165]()\n\n## Advanced Configuration Example\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\",\n        \"JUSTONEAPI_TIMEOUT_MS\": \"30000\",\n        \"JUSTONEAPI_DEBUG\": \"true\",\n        \"JUSTONEAPI_RETRY\": \"3\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md:145-155]()\n\n## Token Security\n\nThe server masks tokens in log output for security:\n\n```typescript\nfunction maskToken(token: string): string {\n  if (token.length <= 8) return \"****\";\n  return token.slice(0, 4) + \"****\" + token.slice(-4);\n}\n```\n\nSafe URL logging replaces the token parameter with masked value, ensuring credentials are never exposed in logs or error messages.\n\n资料来源：[src/common/config.ts:30-45]()\n\n---\n\n<a id='error-handling'></a>\n\n## Error Handling\n\n### 相关页面\n\n相关主题：[HTTP Client Implementation](#http-client), [Unified Search Tool](#unified-search-tool), [Configuration Reference](#configuration-reference)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n</details>\n\n# Error Handling\n\n## Overview\n\nThe justoneapi-mcp project implements a comprehensive error handling system designed to provide stability, transparency, and raw data fidelity. The error handling layer acts as a bridge between upstream API responses and MCP (Model Context Protocol) tool invocations, normalizing diverse error conditions into stable, actionable MCP error codes.\n\n**Key Design Principles:**\n\n- Transport, not transformation — the system prioritizes maximum data fidelity\n- Fail fast with clear validation (token requirement checked early)\n- Retry logic for transient failures\n- Safe logging that never exposes sensitive credentials\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n---\n\n## Error Code System\n\n### Core Error Codes\n\nThe system defines a comprehensive set of standardized error codes that map upstream errors to user-friendly MCP responses.\n\n| Error Code | Description | Recommended Action |\n|------------|-------------|-------------------|\n| `INVALID_TOKEN` | Token is invalid or inactive | Update your `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | Data collection failed | Retry after a short delay |\n| `RATE_LIMITED` | Too many requests | Slow down and retry later |\n| `DAILY_QUOTA_EXCEEDED` | Daily usage limit reached | Wait until tomorrow or upgrade plan |\n| `INSUFFICIENT_BALANCE` | Account balance too low | Top up your account |\n| `PERMISSION_DENIED` | No access to this resource | Contact support |\n| `VALIDATION_ERROR` | Invalid request parameters | Check input values |\n| `INTERNAL_ERROR` | Server error | Retry later |\n| `NETWORK_TIMEOUT` | Request timed out | Check network or retry |\n| `NETWORK_ERROR` | Network connection failed | Check internet connection |\n| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n### Upstream Code Mapping\n\nThe `mapUpstreamCode` function in `errors.ts` translates numeric upstream API codes into MCP error codes.\n\n```typescript\nfunction mapUpstreamCode(upstreamCode: number): JOAErrorCode {\n  switch (upstreamCode) {\n    case 302:\n      return \"RATE_LIMITED\";\n    case 401:\n      return \"INVALID_TOKEN\";\n    // ... other mappings\n    default:\n      return \"UPSTREAM_ERROR\";\n  }\n}\n```\n\n资料来源：[src/common/errors.ts:1-50](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n---\n\n## Architecture\n\n### Error Flow Diagram\n\n```mermaid\ngraph TD\n    A[API Request] --> B{HTTP Response OK?}\n    B -->|No| C[HTTP Level Error]\n    B -->|Yes| D{JSON Parse Success?}\n    D -->|No| E[Parse Error]\n    D -->|Yes| F{Business Code = 0?}\n    F -->|No| G[Business Level Error]\n    F -->|Yes| H[Success Response]\n    \n    C --> I[Create ApiError with httpStatus]\n    E --> J[Create ApiError with payload=text]\n    G --> K[Create ApiError with upstreamCode]\n    \n    I --> L[toMcpErrorPayload]\n    J --> L\n    K --> L\n    \n    L --> M[Return MCP Error Format]\n    \n    H --> N[Return JSON Data]\n```\n\n### Component Structure\n\n| Component | File | Responsibility |\n|-----------|------|-----------------|\n| Error Type Definitions | `src/common/errors.ts` | Error codes, mapping functions |\n| HTTP Client | `src/common/http.ts` | Request execution, retry logic |\n| Error Processing | `src/common/errors.ts` | Payload conversion, message building |\n| Tool Integration | `src/index.ts` | MCP error formatting for tool responses |\n\n资料来源：[src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts), [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n---\n\n## Error Detection and Classification\n\n### Detection Sources\n\nThe error handling system identifies errors from multiple sources:\n\n1. **Timeout Errors** — AbortError from AbortController\n2. **HTTP Status Errors** — Non-2xx responses\n3. **JSON Parse Failures** — Invalid JSON responses\n4. **Business Logic Errors** — Upstream API returns code != 0\n5. **Network Failures** — ECONNREFUSED, ENOTFOUND, ECONNRESET\n\n```typescript\n// Timeout from AbortController\nif (error.name === \"AbortError\") {\n  return { code: \"NETWORK_TIMEOUT\", message: buildUserMessage(\"NETWORK_TIMEOUT\") };\n}\n\n// Network-level failures\nif (error.cause || error.code === \"ECONNREFUSED\" || error.code === \"ENOTFOUND\") {\n  return { code: \"NETWORK_ERROR\", message: error.message ?? buildUserMessage(\"NETWORK_ERROR\") };\n}\n```\n\n资料来源：[src/common/errors.ts:52-73](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n### Error Payload Interface\n\n```typescript\ninterface ApiError extends Error {\n  httpStatus?: number;\n  upstreamCode?: number;\n  payload?: unknown;\n  code?: string;\n  cause?: unknown;\n}\n```\n\n资料来源：[src/common/http.ts:15-21](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n---\n\n## HTTP Client Error Handling\n\n### Retry Logic\n\nThe `getJson` function implements intelligent retry logic with exponential backoff.\n\n```mermaid\ngraph LR\n    A[Request] --> B{Attempt <= Max?}\n    B -->|Yes| C[Execute Fetch]\n    C --> D{Success?}\n    D -->|Yes| E[Return JSON]\n    D -->|No| F{Retryable?}\n    F -->|Yes| G[Wait 250ms * attempt]\n    F -->|No| H[Throw Error]\n    G --> B\n    H --> I[toMcpErrorPayload]\n```\n\n### Retryable Conditions\n\n| Condition | Retryable | Reason |\n|-----------|-----------|--------|\n| AbortError (timeout) | ✅ Yes | Transient timeout |\n| HTTP 5xx | ✅ Yes | Server-side issue |\n| ECONNRESET | ✅ Yes | Connection reset |\n| ECONNREFUSED | ✅ Yes | Server unavailable |\n| ENOTFOUND | ✅ Yes | DNS/network issue |\n| HTTP 4xx | ❌ No | Client error |\n| Business code != 0 | ❌ No | Data issue |\n\n```typescript\nconst retryable =\n  error.name === \"AbortError\" ||\n  (typeof httpStatus === \"number\" && httpStatus >= 500) ||\n  error.code === \"ECONNRESET\" ||\n  error.code === \"ECONNREFUSED\" ||\n  error.code === \"ENOTFOUND\";\n```\n\n资料来源：[src/common/http.ts:40-48](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n### Timeout Configuration\n\n| Configuration | Default | Description |\n|---------------|---------|-------------|\n| `JUSTONEAPI_TIMEOUT_MS` | 20000 | Request timeout in milliseconds |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n---\n\n## Error Processing Flow\n\n### The `toMcpErrorPayload` Function\n\nThis function transforms various error types into a standardized MCP error format:\n\n```typescript\nexport function toMcpErrorPayload(e: unknown): {\n  code: JOAErrorCode;\n  message: string;\n  upstreamCode?: number;\n  httpStatus?: number;\n}\n```\n\n**Processing Priority:**\n\n1. AbortError → `NETWORK_TIMEOUT`\n2. Upstream business code (if present) → Mapped MCP code\n3. HTTP status (if present) → `UPSTREAM_ERROR`\n4. Network errors (cause present or specific codes) → `NETWORK_ERROR`\n5. Default fallback → `UPSTREAM_ERROR`\n\n资料来源：[src/common/errors.ts:76-101](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n### User Message Building\n\nThe `buildUserMessage` function generates human-readable messages for each error code:\n\n```typescript\nfunction buildUserMessage(code: JOAErrorCode, base?: string | null): string {\n  switch (code) {\n    case \"NETWORK_TIMEOUT\":\n      return base ?? \"Request timed out. Check network or increase timeout.\";\n    case \"INVALID_TOKEN\":\n      return base ?? \"Invalid or inactive token. Check JUSTONEAPI_TOKEN.\";\n    // ... additional cases\n    default:\n      return base ?? \"Upstream error. Please retry later.\";\n  }\n}\n```\n\n资料来源：[src/common/errors.ts:25-74](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n---\n\n## Tool-Level Error Handling\n\n### MCP Tool Integration\n\nAll tools registered with the MCP server wrap their execution in try-catch blocks to ensure consistent error formatting.\n\n```typescript\nserver.registerTool(\n  \"unified_search_v1\",\n  {\n    description: \"Unified search across multiple platforms...\",\n    inputSchema: UnifiedSearchV1Input.shape,\n  },\n  async (input) => {\n    try {\n      const data = await unifiedSearchV1(input);\n      return {\n        content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n      };\n    } catch (e: unknown) {\n      const m = toMcpErrorPayload(e);\n      return {\n        isError: true,\n        content: [\n          {\n            type: \"text\",\n            text: `ERROR[${m.code}] (upstream=${m.upstreamCode ?? \"N/A\"}): ${m.message}`,\n          },\n        ],\n      };\n    }\n  }\n);\n```\n\n资料来源：[src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n### Error Response Format\n\nMCP tool errors are formatted as:\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n**Example Responses:**\n\n| Scenario | Response Format |\n|----------|-----------------|\n| Rate Limited | `ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.` |\n| Invalid Token | `ERROR[INVALID_TOKEN] (upstream=401): Invalid or inactive token. Check JUSTONEAPI_TOKEN.` |\n| Network Timeout | `ERROR[NETWORK_TIMEOUT] (upstream=N/A): Request timed out. Check network or increase timeout.` |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n---\n\n## Validation Errors\n\n### Early Validation\n\nThe system performs early validation to fail fast with clear error messages:\n\n**Token Validation:**\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN?.trim();\n  if (!token) {\n    const err = new Error(\"JUSTONEAPI_TOKEN is required\") as ApiError;\n    err.upstreamCode = 401;\n    throw err;\n  }\n  return token;\n}\n```\n\n资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n\n**Search Parameter Validation:**\n\n```typescript\n// First page: require start and end times\nif (!input.start || !input.end) {\n  throw new Error(\n    \"start and end times are required for the first page (unless using nextCursor for pagination)\"\n  );\n}\n```\n\n资料来源：[src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n\n---\n\n## Debugging Error Handling\n\n### Debug Mode\n\nEnable debug logging to trace error handling flow:\n\n```json\n{\n  \"mcpServers\": {\n    \"justoneapi\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"justoneapi-mcp\"],\n      \"env\": {\n        \"JUSTONEAPI_TOKEN\": \"your_token_here\",\n        \"JUSTONEAPI_DEBUG\": \"true\"\n      }\n    }\n  }\n}\n```\n\n### Safe URL Logging\n\nThe system includes `toSafeUrlForLog` to prevent token leakage in logs:\n\n```typescript\nexport function toSafeUrlForLog(fullUrl: string): string {\n  if (u.searchParams.has(\"token\")) {\n    u.searchParams.set(\"token\", maskToken(u.searchParams.get(\"token\") ?? \"\"));\n  }\n  return u.toString();\n}\n```\n\n资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n\n---\n\n## Configuration Options\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `JUSTONEAPI_TOKEN` | *(required)* | Your JustOneAPI token |\n| `JUSTONEAPI_BASE_URL` | `https://api.justoneapi.com` | API endpoint |\n| `JUSTONEAPI_TIMEOUT_MS` | `20000` | Request timeout (milliseconds) |\n| `JUSTONEAPI_RETRY` | `1` | Number of retries after first attempt |\n| `JUSTONEAPI_DEBUG` | `false` | Enable debug logging to stderr |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n---\n\n## Best Practices\n\n1. **Handle Rate Limits** — Implement exponential backoff when receiving `RATE_LIMITED`\n2. **Check Token Validity** — Ensure `JUSTONEAPI_TOKEN` is active before heavy usage\n3. **Monitor Quotas** — Track `DAILY_QUOTA_EXCEEDED` errors to avoid service interruption\n4. **Enable Debug Mode** — Use `JUSTONEAPI_DEBUG=true` when troubleshooting\n5. **Use Pagination** — Leverage `nextCursor` for large result sets to avoid timeout issues\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：justoneapi/justoneapi-mcp\n\n摘要：发现 7 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | README/documentation is current enough for a first validation pass.\n\n## 2. 运行坑 · 来源证据：Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of…\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个运行相关的待验证问题：Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of 2-39)\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3b8110f2a2a84250a1da5b96b5573463 | https://github.com/justoneapi/justoneapi-mcp/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。\n\n## 3. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | last_activity_observed missing\n\n## 4. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium\n\n## 5. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium\n\n## 6. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | issue_or_pr_quality=unknown\n\n## 7. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | release_recency=unknown\n\n<!-- canonical_name: justoneapi/justoneapi-mcp; human_manual_source: deepwiki_human_wiki -->\n",
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "Human Manual / 人类版说明书"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log / 踩坑日志\n\n项目：justoneapi/justoneapi-mcp\n\n摘要：发现 7 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | README/documentation is current enough for a first validation pass.\n\n## 2. 运行坑 · 来源证据：Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of…\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个运行相关的待验证问题：Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of 2-39)\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3b8110f2a2a84250a1da5b96b5573463 | https://github.com/justoneapi/justoneapi-mcp/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。\n\n## 3. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | last_activity_observed missing\n\n## 4. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium\n\n## 5. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium\n\n## 6. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | issue_or_pr_quality=unknown\n\n## 7. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | release_recency=unknown\n",
      "summary": "用户实践前最可能遇到的身份、安装、配置、运行和安全坑。",
      "title": "Pitfall Log / 踩坑日志"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# justoneapi-mcp - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 justoneapi-mcp 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的工具连接与集成任务。\n我常用的宿主 AI：MCP Client\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: Production-ready MCP server exposing JustOneAPI endpoints to AI agents with raw JSON responses. 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. getting-started：Getting Started with JustOneAPI MCP。围绕“Getting Started with JustOneAPI MCP”模拟一次用户任务，不展示安装或运行结果。\n2. authentication：Authentication。围绕“Authentication”模拟一次用户任务，不展示安装或运行结果。\n3. system-architecture：System Architecture。围绕“System Architecture”模拟一次用户任务，不展示安装或运行结果。\n4. unified-search-tool：Unified Search Tool。围绕“Unified Search Tool”模拟一次用户任务，不展示安装或运行结果。\n5. configuration-reference：Configuration Reference。围绕“Configuration Reference”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. getting-started\n输入：用户提供的“Getting Started with JustOneAPI MCP”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. authentication\n输入：用户提供的“Authentication”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. system-architecture\n输入：用户提供的“System Architecture”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. unified-search-tool\n输入：用户提供的“Unified Search Tool”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. configuration-reference\n输入：用户提供的“Configuration Reference”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / getting-started：Step 1 必须围绕“Getting Started with JustOneAPI MCP”形成一个小中间产物，并等待用户确认。\n- Step 2 / authentication：Step 2 必须围绕“Authentication”形成一个小中间产物，并等待用户确认。\n- Step 3 / system-architecture：Step 3 必须围绕“System Architecture”形成一个小中间产物，并等待用户确认。\n- Step 4 / unified-search-tool：Step 4 必须围绕“Unified Search Tool”形成一个小中间产物，并等待用户确认。\n- Step 5 / configuration-reference：Step 5 必须围绕“Configuration Reference”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/justoneapi/justoneapi-mcp\n- https://github.com/justoneapi/justoneapi-mcp#readme\n- README.md\n- package.json\n- src/common/config.ts\n- src/common/http.ts\n- src/index.ts\n- src/tools/search/unified_search_v1.ts\n- TOOLS.md\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 justoneapi-mcp 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start / 官方入口\n\n项目：justoneapi/justoneapi-mcp\n\n## 官方安装入口\n\n### Node.js / npm · 官方安装入口\n\n```bash\nnpm install -g justoneapi-mcp\n```\n\n来源：https://github.com/justoneapi/justoneapi-mcp#readme\n\n## 来源\n\n- repo: https://github.com/justoneapi/justoneapi-mcp\n- docs: https://github.com/justoneapi/justoneapi-mcp#readme\n",
      "summary": "从项目官方 README 或安装文档提取的开工入口。",
      "title": "Quick Start / 官方入口"
    }
  },
  "validation_id": "dval_21f5de23e008417cbe3efcca12f1f7ba"
}
