{
  "canonical_name": "justoneapi/justoneapi-mcp",
  "compilation_id": "pack_fd0d747c449e403cb5b04b2bf8e4046a",
  "created_at": "2026-05-15T03:17:06.133819+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": "MCP Tools",
        "label_zh": "MCP 工具",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-mcp-tools",
        "type": "product_domain"
      },
      {
        "label_en": "Visual Workflow Orchestration",
        "label_zh": "视觉工作流编排",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-visual-workflow-orchestration",
        "type": "user_job"
      },
      {
        "label_en": "Retrieval Augmentation",
        "label_zh": "检索增强",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-retrieval-augmentation",
        "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": "Local-first",
        "label_zh": "本地优先",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-local-first",
        "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": [
        "MCP 工具",
        "视觉工作流编排",
        "检索增强",
        "节点式流程编排",
        "本地优先"
      ],
      "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. project-overview：项目概述。围绕“项目概述”模拟一次用户任务，不展示安装或运行结果。\n2. configuration：配置管理。围绕“配置管理”模拟一次用户任务，不展示安装或运行结果。\n3. tools-overview：工具概览。围绕“工具概览”模拟一次用户任务，不展示安装或运行结果。\n4. unified-search：统一搜索工具。围绕“统一搜索工具”模拟一次用户任务，不展示安装或运行结果。\n5. error-handling：错误处理。围绕“错误处理”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. project-overview\n输入：用户提供的“项目概述”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. configuration\n输入：用户提供的“配置管理”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. tools-overview\n输入：用户提供的“工具概览”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. unified-search\n输入：用户提供的“统一搜索工具”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. error-handling\n输入：用户提供的“错误处理”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / project-overview：Step 1 必须围绕“项目概述”形成一个小中间产物，并等待用户确认。\n- Step 2 / configuration：Step 2 必须围绕“配置管理”形成一个小中间产物，并等待用户确认。\n- Step 3 / tools-overview：Step 3 必须围绕“工具概览”形成一个小中间产物，并等待用户确认。\n- Step 4 / unified-search：Step 4 必须围绕“统一搜索工具”形成一个小中间产物，并等待用户确认。\n- Step 5 / error-handling：Step 5 必须围绕“错误处理”形成一个小中间产物，并等待用户确认。\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- README.zh-CN.md\n- src/common/config.ts\n- src/version.ts\n- TOOLS.md\n- src/index.ts\n- src/tools/search/unified_search_v1.ts\n- src/common/errors.ts\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": [
        "MCP 工具",
        "视觉工作流编排",
        "检索增强",
        "节点式流程编排",
        "本地优先"
      ],
      "thumb": "gray",
      "type": "MCP 配置"
    },
    "manual": {
      "markdown": "# https://github.com/justoneapi/justoneapi-mcp 项目说明书\n\n生成时间：2026-05-15 01:49:03 UTC\n\n## 目录\n\n- [项目概述](#project-overview)\n- [安装部署](#installation)\n- [配置管理](#configuration)\n- [工具概览](#tools-overview)\n- [统一搜索工具](#unified-search)\n- [平台专用工具](#platform-tools)\n- [错误处理](#error-handling)\n- [认证授权](#authentication)\n- [系统架构](#system-architecture)\n- [开发指南](#development-guide)\n\n<a id='project-overview'></a>\n\n## 项目概述\n\n### 相关页面\n\n相关主题：[系统架构](#system-architecture), [安装部署](#installation)\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/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/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- [src/version.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/version.ts)\n</details>\n\n# 项目概述\n\n## 项目简介\n\njustoneapi-mcp 是一个基于 Model Context Protocol (MCP) 协议构建的服务器应用程序，专门用于在中国社交媒体平台和新闻网站上进行统一搜索和数据采集。该项目作为 MCP 主机（如 Claude Desktop、Cursor 等）与 JustOneAPI 之间的桥梁，使 AI 助手能够直接访问和分析中国主流社交媒体的内容。资料来源：[README.md:1]()\n\n该项目的核心设计理念是\"传输而非转换\"（Transport, not transformation），强调数据的稳定性和原始保真度，返回未经修改的上游 API 响应。资料来源：[README.md:180]()\n\n## 技术架构\n\n### 系统架构图\n\n```mermaid\ngraph TD\n    subgraph MCP主机 [\"MCP 主机\"]\n        A[Claude Desktop / Cursor]\n    end\n    \n    subgraph justoneapi-mcp [\"justoneapi-mcp 服务器\"]\n        B[入口模块 src/index.ts]\n        C[工具注册模块]\n        D[HTTP 请求模块]\n        E[错误处理模块]\n        F[配置管理模块]\n        G[统一搜索工具]\n        H[快手搜索工具]\n    end\n    \n    subgraph JustOneAPI [\"JustOneAPI 服务\"]\n        I[API 网关]\n        J[上游数据源]\n    end\n    \n    A -->|MCP 协议| B\n    B --> C\n    C --> G\n    C --> H\n    G --> D\n    H --> D\n    D --> F\n    D -->|HTTP 请求| I\n    I --> J\n    \n    J -->|微博| K[WEIBO]\n    J -->|微信| L[WEIXIN]\n    J -->|知乎| M[ZHIHU]\n    J -->|抖音| N[DOUYIN]\n    J -->|小红书| O[XIAOHONGSHU]\n    J -->|哔哩哔哩| P[BILIBILI]\n    J -->|快手| Q[KUAISHOU]\n    J -->|新闻| R[NEWS]\n```\n\n### 技术栈\n\n| 技术组件 | 版本要求 | 用途说明 |\n|---------|---------|---------|\n| Node.js | >=18.0.0 | 运行时环境 |\n| TypeScript | ^5.9.3 | 开发语言 |\n| @modelcontextprotocol/sdk | ^1.25.1 | MCP 协议实现 |\n| Zod | ^4.3.4 | 参数验证与 schema 定义 |\n| dotenv | ^17.2.3 | 环境变量管理 |\n\n资料来源：[package.json:7-18]()\n\n## 核心模块设计\n\n### 模块职责说明\n\n```mermaid\ngraph LR\n    subgraph 核心模块\n        A[config.ts]\n        B[http.ts]\n        C[errors.ts]\n    end\n    \n    subgraph 工具模块\n        D[unified_search_v1.ts]\n        E[search_video_v2.ts]\n    end\n    \n    subgraph 入口模块\n        F[index.ts]\n    end\n    \n    F --> A\n    F --> D\n    F --> E\n    D --> B\n    E --> B\n    B --> C\n```\n\n### 配置管理模块\n\n`src/common/config.ts` 负责管理和验证环境变量配置。资料来源：[src/common/config.ts:1]()\n\n| 配置项 | 默认值 | 必填 | 说明 |\n|-------|-------|------|------|\n| `JUSTONEAPI_TOKEN` | - | 是 | JustOneAPI 访问令牌 |\n| `JUSTONEAPI_BASE_URL` | `https://api.justoneapi.com` | 否 | API 端点地址 |\n| `JUSTONEAPI_TIMEOUT_MS` | `20000` | 否 | 请求超时时间（毫秒） |\n| `JUSTONEAPI_RETRY` | `1` | 否 | 失败后重试次数 |\n| `JUSTONEAPI_DEBUG` | `false` | 否 | 启用调试日志 |\n\n资料来源：[README.md:195-202]()\n\n配置模块还提供令牌掩码功能，用于日志输出时保护敏感信息：\n\n```typescript\nexport function toSafeUrlForLog(fullUrl: string): string {\n  // 移除或掩码 token 查询参数\n}\n```\n\n资料来源：[src/common/config.ts:27-39]()\n\n### HTTP 请求模块\n\n`src/common/http.ts` 实现统一的 HTTP 请求处理机制，具备以下特性：资料来源：[src/common/http.ts:1]()\n\n**重试机制**：\n\n- 仅对以下情况触发重试：\n  - 请求超时（AbortError）\n  - HTTP 5xx 状态码\n  - 网络连接重置（ECONNRESET）\n  - 连接被拒绝（ECONNREFUSED）\n  - DNS 解析失败（ENOTFOUND）\n\n**退避策略**：每次重试间隔为 `250 * attempt` 毫秒。资料来源：[src/common/http.ts:28-29]()\n\n```mermaid\ngraph TD\n    A[发起请求] --> B{请求成功?}\n    B -->|是| C[返回 JSON 响应]\n    B -->|否| D{可重试错误?}\n    D -->|超时/5xx/网络错误| E[等待退避时间]\n    D -->|其他错误| F[抛出异常]\n    E --> G[重试]\n    G --> A\n    D -->|达到最大重试次数| F\n```\n\n### 错误处理模块\n\n`src/common/errors.ts` 实现标准化的 MCP 错误码映射系统。资料来源：[src/common/errors.ts:1]()\n\n**错误码映射表**：\n\n| 上游错误码 | MCP 错误码 | 描述 | 用户操作 |\n|-----------|-----------|------|---------|\n| 302 | `RATE_LIMITED` | 请求频率超限 | 降低请求频率后重试 |\n| - | `INVALID_TOKEN` | 令牌无效或未激活 | 更新 `JUSTONEAPI_TOKEN` |\n| - | `COLLECT_FAILED` | 数据采集失败 | 短暂延迟后重试 |\n| - | `DAILY_QUOTA_EXCEEDED` | 日用量超限 | 等待明天或升级套餐 |\n| - | `INSUFFICIENT_BALANCE` | 账户余额不足 | 充值账户 |\n| - | `PERMISSION_DENIED` | 无权访问资源 | 联系客服 |\n| - | `VALIDATION_ERROR` | 请求参数无效 | 检查输入值 |\n| - | `INTERNAL_ERROR` | 服务器内部错误 | 稍后重试 |\n| - | `NETWORK_TIMEOUT` | 请求超时 | 检查网络或重试 |\n| - | `NETWORK_ERROR` | 网络连接失败 | 检查网络连接 |\n| - | `UPSTREAM_ERROR` | 上游未指明错误 | 重试或联系客服 |\n\n资料来源：[README.md:152-169]()\n\n**错误输出格式**：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n示例：`ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.` 资料来源：[README.md:170-174]()\n\n## 可用工具\n\n### 工具清单\n\n| 工具名称 | 版本 | 功能描述 |\n|---------|------|---------|\n| `unified_search_v1` | v1 | 跨平台统一搜索 |\n| `kuaishou_search_video_v2` | v2 | 快手视频搜索 |\n\n资料来源：[TOOLS.md:15-19]()\n\n### 统一搜索工具 (unified_search_v1)\n\n统一搜索工具支持在多个中国社交媒体和新闻平台上一站式搜索。资料来源：[src/tools/search/unified_search_v1.ts:1]()\n\n**支持的平台**：\n\n- `ALL` - 全部平台（默认）\n- `NEWS` - 新闻\n- `WEIBO` - 微博\n- `WEIXIN` - 微信\n- `ZHIHU` - 知乎\n- `DOUYIN` - 抖音\n- `XIAOHONGSHU` - 小红书\n- `BILIBILI` - 哔哩哔哩\n- `KUAISHOU` - 快手\n\n资料来源：[README.md:30-38]()\n\n**参数定义**：\n\n| 参数 | 类型 | 必填 | 说明 |\n|-----|------|------|------|\n| `keyword` | string | 是 | 搜索关键词，支持高级语法 |\n| `source` | string | 否 | 平台过滤器，默认 `ALL` |\n| `start` | string | 首次请求必填 | 开始时间 `yyyy-MM-dd HH:mm:ss` (UTC+8)，范围不超过 84 天 |\n| `end` | string | 首次请求必填 | 结束时间 `yyyy-MM-dd HH:mm:ss` (UTC+8)，必须晚于开始时间 |\n| `nextCursor` | string | 分页时使用 | 来自上一页响应的游标 |\n\n资料来源：[src/tools/search/unified_search_v1.ts:14-35]()\n\n**搜索语法**：\n\n| 语法类型 | 格式 | 示例 | 说明 |\n|---------|------|------|------|\n| 单关键词 | `word` | `deepseek` | 搜索单个关键词 |\n| AND 搜索 | `word1 word2` | `deepseek chatgpt` | 两个关键词必须同时出现 |\n| OR 搜索 | `word1~word2` | `deepseek~chatgpt` | 任一关键词出现即可 |\n| NOT 搜索 | `word -excluded` | `deepseek -chatgpt` | 排除指定关键词 |\n\n资料来源：[README.md:122-127]()\n\n**API 调用示例**：\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### 快手视频搜索工具 (kuaishou_search_video_v2)\n\n快手视频搜索是平台特定的工具，专注于快手平台的视频内容搜索。资料来源：[src/tools/kuaishou/search_video_v2.ts:1]()\n\n**参数定义**：\n\n| 参数 | 类型 | 必填 | 默认值 | 说明 |\n|-----|------|------|--------|------|\n| `keyword` | string | 是 | - | 搜索关键词，如 `dance` |\n| `page` | number | 否 | 1 | 页码，从 1 开始 |\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:5-8]()\n\n## 输出契约\n\n### 成功响应格式\n\n所有工具返回原始 JSON 响应，设计原则是\"最大数据保真度、无字段解析、无数据重组\"。资料来源：[README.md:149-152]()\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-12-31T14:55:21Z\",\n  \"data\": {\n    // 平台特定数据结构\n  }\n}\n```\n\n| 字段 | 类型 | 说明 |\n|-----|------|------|\n| `code` | integer | 0 表示成功，非 0 表示错误 |\n| `message` | string/null | 错误信息，成功时为 null |\n| `recordTime` | string | 响应记录时间（ISO 8601 格式） |\n| `data` | object | 平台特定数据内容 |\n\n### 分页机制\n\n当搜索结果存在更多页面时，响应会包含 `nextCursor` 字段。用户可以通过以下方式继续获取下一页：\n\n- \"显示更多结果\"\n- \"继续获取上一页的更多结果\"\n- \"继续下一页\"\n\n系统会自动从上一条响应中提取 `nextCursor` 并用于后续请求。资料来源：[README.md:128-141]()\n\n```mermaid\ngraph LR\n    A[首次请求] -->|无 nextCursor| B[返回第一页 + nextCursor]\n    B --> C[请求第二页]\n    C -->|携带 nextCursor| D[返回第二页 + nextCursor]\n    D --> E[继续...直到无 nextCursor]\n```\n\n## 安装与配置\n\n### 安装方式\n\n**推荐方式：npx（无需安装）**\n\n直接使用 npx 运行，无需本地安装：\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:70-80]()\n\n### Claude Desktop 配置\n\n配置文件位置：\n\n| 操作系统 | 配置文件路径 |\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### 自定义配置示例\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## 版本管理\n\n项目使用动态版本管理机制，从 `package.json` 读取版本号：资料来源：[src/version.ts:1]()\n\n```typescript\nconst packageJsonPath = join(__dirname, \"../package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\nversion = packageJson.version || \"0.0.0\";\n```\n\n## 项目结构\n\n```\njustoneapi-mcp/\n├── src/\n│   ├── index.ts                 # 入口模块\n│   ├── version.ts               # 版本管理\n│   ├── common/\n│   │   ├── config.ts            # 配置管理\n│   │   ├── http.ts              # HTTP 请求处理\n│   │   └── errors.ts            # 错误处理\n│   └── tools/\n│       ├── search/\n│       │   └── unified_search_v1.ts    # 统一搜索工具\n│       └── kuaishou/\n│           └── search_video_v2.ts      # 快手搜索工具\n├── package.json\n├── eslint.config.js\n├── README.md\n├── TOOLS.md\n└── LICENSE\n```\n\n## 设计哲学\n\n**传输，而非转换**\n\n该 MCP 服务器的设计优先级为：资料来源：[README.md:179-182]()\n\n1. **稳定性**：确保服务可靠运行\n2. **透明度**：返回原始数据，不隐藏上游信息\n3. **数据保真度**：返回未修改的上游 API 响应\n\n这一设计理念确保了长期兼容性和最大化的数据完整性，用户可以直接访问底层数据并进行自定义分析。\n\n## 许可证\n\n本项目采用 MIT 许可证开源授权。资料来源：[README.md:206]()\n\n---\n\n<a id='installation'></a>\n\n## 安装部署\n\n### 相关页面\n\n相关主题：[配置管理](#configuration), [认证授权](#authentication)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\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- [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/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [tsconfig.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/tsconfig.json)\n</details>\n\n# 安装部署\n\n本文档详细说明 justoneapi-mcp 的安装、配置和部署流程。justoneapi-mcp 是一个基于 Model Context Protocol (MCP) 的服务器，用于连接 JustOneAPI 社交媒体数据搜索服务。\n\n## 系统要求\n\n### 运行环境\n\n| 组件 | 最低版本要求 |\n|------|-------------|\n| Node.js | >= 18.0.0 |\n\n资料来源：[package.json:28]()\n\n### 依赖包\n\n| 依赖包 | 版本 | 用途 |\n|--------|------|------|\n| @modelcontextprotocol/sdk | ^1.25.1 | MCP 协议实现 |\n| zod | ^4.3.4 | 参数验证与 Schema 定义 |\n| dotenv | ^17.2.3 | 环境变量管理 |\n\n资料来源：[package.json:33-36]()\n\n## 安装方式\n\n### 方式一：npx 方式（推荐）\n\n使用 npx 可以直接运行，无需预先安装：\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这种方式的优势在于：\n- 无需手动安装\n- 始终使用最新版本\n- 配置简单快捷\n\n资料来源：[README.md:71-79]()\n\n### 方式二：本地安装\n\n如果需要特定版本或离线部署：\n\n```bash\nnpm install -g justoneapi-mcp\n```\n\n或项目依赖方式：\n\n```bash\nnpm install justoneapi-mcp\n```\n\n## MCP 主机配置\n\n### Claude Desktop 配置\n\n#### macOS\n\n配置文件路径：`~/Library/Application Support/Claude/claude_desktop_config.json`\n\n#### Windows\n\n配置文件路径：`%APPDATA%\\Claude\\claude_desktop_config.json`\n\n#### Linux\n\n配置文件路径：`~/.config/Claude/claude_desktop_config.json`\n\n### 完整配置示例\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        \"JUSTJUSTONEAPI_TIMEOUT_MS\": \"30000\",\n        \"JUSTONEAPI_DEBUG\": \"true\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md:64-89]()\n\n## 环境变量配置\n\n### 必需配置\n\n| 变量名 | 说明 | 默认值 |\n|--------|------|--------|\n| JUSTONEAPI_TOKEN | JustOneAPI 访问令牌 | **必需** |\n\n### 可选配置\n\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| JUSTONEAPI_BASE_URL | `https://api.justoneapi.com` | API 端点地址 |\n| JUSTONEAPI_TIMEOUT_MS | `20000` | 请求超时时间（毫秒） |\n| JUSTONEAPI_RETRY | `1` | 首次请求失败后的重试次数 |\n| JUSTONEAPI_DEBUG | `false` | 是否启用调试日志 |\n\n资料来源：[README.md:91-100]()\n\n### 令牌获取\n\n访问 [JustOneAPI Dashboard](https://dashboard.justoneapi.com/en/login) 注册并获取 API 令牌。\n\n## 配置模块详解\n\n### 配置加载流程\n\n```mermaid\ngraph TD\n    A[启动 MCP Server] --> B[检查 JUSTONEAPI_TOKEN]\n    B --> C{Token 是否存在且非空?}\n    C -->|是| D[加载可选配置]\n    C -->|否| E[输出错误信息并退出]\n    D --> F[配置加载完成]\n    F --> G[注册工具并启动服务]\n    E --> H[进程终止]\n```\n\n配置模块负责在服务启动时验证必要参数，核心逻辑位于 `src/common/config.ts`。\n\n资料来源：[src/common/config.ts]()\n\n### 令牌验证\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN;\n  if (!token?.trim()) {\n    throw new Error(\"JUSTONEAPI_TOKEN is required\");\n  }\n  return token;\n}\n```\n\n该函数在所有 API 请求前被调用，确保令牌有效。\n\n资料来源：[src/common/config.ts]()\n\n### 安全日志处理\n\n配置模块提供令牌脱敏功能，避免在日志中泄露敏感信息：\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]()\n\n## HTTP 请求机制\n\n### 请求流程\n\n```mermaid\ngraph TD\n    A[发起请求] --> B{重试次数 < maxRetries?}\n    B -->|是| C[创建 AbortController]\n    C --> D[设置超时定时器]\n    D --> E[发送 GET 请求]\n    E --> F{响应状态码 < 500?}\n    F -->|是| G[解析 JSON 响应]\n    G --> H{业务代码 == 0?}\n    H -->|是| I[返回响应数据]\n    H -->|否| J[抛出业务错误]\n    F -->|否| K{可重试错误?}\n    K -->|是| L[等待后重试]\n    K -->|否| M[抛出错误]\n    J --> N[返回错误响应]\n    B -->|否| M\n    L --> B\n```\n\n### 重试策略\n\n请求失败时，HTTP 模块会自动重试以下情况：\n\n| 错误类型 | 是否重试 |\n|----------|----------|\n| AbortError（超时） | ✅ 重试 |\n| HTTP 5xx 错误 | ✅ 重试 |\n| ECONNRESET | ✅ 重试 |\n| ECONNREFUSED | ✅ 重试 |\n| ENOTFOUND | ✅ 重试 |\n| HTTP 4xx 错误 | ❌ 不重试 |\n| 业务代码 != 0 | ❌ 不重试 |\n\n重试间隔采用简单退避策略：`250ms * attempt`。\n\n资料来源：[src/common/http.ts:24-36]()\n\n### 超时配置\n\n默认超时时间为 20 秒，可通过 `JUSTONEAPI_TIMEOUT_MS` 环境变量自定义：\n\n```typescript\nconst timer = setTimeout(() => controller.abort(), config.timeoutMs);\n```\n\n资料来源：[src/common/http.ts:41]()\n\n## 服务启动流程\n\n### 启动时验证\n\n```mermaid\ngraph TD\n    A[main 函数入口] --> B[检查环境变量]\n    B --> C{JUSTONEAPI_TOKEN 是否设置?}\n    C -->|否| D[输出错误信息]\n    D --> E[进程终止]\n    C -->|是| F[创建 MCP Server]\n    F --> G[注册 unified_search_v1 工具]\n    G --> H[注册 kuaishou_search_video_v2 工具]\n    H --> I[连接 stdio 传输]\n    I --> J[服务就绪]\n```\n\n### 主入口代码\n\n```typescript\nasync function main() {\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...\"\n    );\n    process.exit(1);\n  }\n  // ... 启动服务\n}\n```\n\n资料来源：[src/index.ts:58-65]()\n\n## TypeScript 编译配置\n\n### 项目配置\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"lib\": [\"ES2022\"],\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"resolveJsonModule\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"sourceMap\": true\n  },\n  \"include\": [\"src/**/*\"],\n exclude\": [\"node_modules\", \"dist\"]\n}\n```\n\n编译产物输出至 `dist` 目录，包含以下文件：\n\n| 目录 | 内容 |\n|------|------|\n| dist/common/ | 通用模块（config、http、errors） |\n| dist/tools/ | 工具模块 |\n| dist/index.js | 主入口 |\n| dist/*.d.ts | 类型声明文件 |\n\n资料来源：[tsconfig.json]()\n\n## 开发环境搭建\n\n### 克隆项目\n\n```bash\ngit clone https://github.com/justoneapi/justoneapi-mcp.git\ncd justoneapi-mcp\n```\n\n### 安装依赖\n\n```bash\nnpm install\n```\n\n### TypeScript 类型检查\n\n```bash\nnpm run typecheck\n```\n\n### 代码格式化\n\n```bash\nnpm run format\n```\n\n### ESLint 检查\n\n```bash\nnpm run lint\n```\n\n### 构建项目\n\n```bash\nnpm run build\n```\n\n### 启动服务（开发模式）\n\n```bash\nnpm run start\n```\n\n## 项目文件结构\n\n```\njustoneapi-mcp/\n├── src/\n│   ├── index.ts                    # 主入口文件\n│   ├── version.ts                  # 版本信息\n│   ├── common/\n│   │   ├── config.ts               # 配置管理\n│   │   ├── http.ts                 # HTTP 请求封装\n│   │   └── errors.ts               # 错误处理\n│   └── tools/\n│       └── search/\n│           └── unified_search_v1.ts # 统一搜索工具\n├── dist/                           # 编译输出\n├── package.json                    # 项目配置\n├── tsconfig.json                   # TypeScript 配置\n└── eslint.config.js                # ESLint 配置\n```\n\n## 故障排查\n\n### 常见问题\n\n#### 1. Token 未设置错误\n\n```\n[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\n```\n\n**解决方案**：确保在 MCP 主机配置中正确设置 `JUSTONEAPI_TOKEN` 环境变量。\n\n#### 2. 请求超时\n\n```\nERROR[NETWORK_TIMEOUT]: Request timed out\n```\n\n**解决方案**：增加 `JUSTONEAPI_TIMEOUT_MS` 配置值（默认 20000ms）。\n\n#### 3. 速率限制\n\n```\nERROR[RATE_LIMITED]: Rate limit exceeded\n```\n\n**解决方案**：降低请求频率，等待一段时间后重试。\n\n### 调试模式\n\n启用调试日志以排查问题：\n\n```json\n{\n  \"env\": {\n    \"JUSTONEAPI_DEBUG\": \"true\"\n  }\n}\n```\n\n调试模式下会输出所有 HTTP 请求详情（令牌已脱敏）。\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- JustOneAPI 官网：https://justoneapi.com\n\n---\n\n<a id='configuration'></a>\n\n## 配置管理\n\n### 相关页面\n\n相关主题：[安装部署](#installation), [认证授权](#authentication)\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/version.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/version.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- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n</details>\n\n# 配置管理\n\n## 概述\n\njustoneapi-mcp 采用简洁而健壮的环境变量配置方案。配置管理系统负责验证必需参数、管理可选行为、确保敏感信息安全性，并在服务启动时进行完整性检查。资料来源：[README.md:108-120]()\n\n## 核心配置架构\n\n配置系统围绕环境变量构建，遵循\"约定优于配置\"的设计原则。所有配置项通过 `process.env` 访问，核心 token 验证在服务初始化阶段强制执行。\n\n```mermaid\ngraph TD\n    A[服务启动] --> B[检查 JUSTONEAPI_TOKEN]\n    B --> C{Token 是否存在且非空?}\n    C -->|是| D[配置验证通过]\n    C -->|否| E[输出错误信息并退出]\n    D --> F[初始化 MCP Server]\n    F --> G[注册工具集]\n    E --> H[进程终止]\n    \n    I[运行时配置] --> J[HTTP 请求]\n    J --> K[Token 注入]\n    K --> L[URL 安全日志]\n    \n    D --> I\n```\n\n资料来源：[src/index.ts:55-68]()\n\n## 环境变量配置项\n\n### 必需配置\n\n| 配置变量 | 类型 | 说明 |\n|---------|------|------|\n| `JUSTONEAPI_TOKEN` | string | API 访问令牌，用于认证上游 JustOneAPI 服务 |\n\n服务启动时，若 `JUSTONEAPI_TOKEN` 未设置或为空字符串，将输出错误信息并终止进程。资料来源：[src/index.ts:55-68]()\n\n```typescript\n// 启动验证逻辑\nif (!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```\n\n### 可选配置\n\n| 配置变量 | 默认值 | 类型 | 说明 |\n|---------|--------|------|------|\n| `JUSTONEAPI_BASE_URL` | `https://api.justoneapi.com` | string | API 端点地址 |\n| `JUSTONEAPI_TIMEOUT_MS` | `20000` | number | 请求超时时间（毫秒） |\n| `JUSTONEAPI_RETRY` | `1` | number | 首次请求失败后的重试次数 |\n| `JUSTONEAPI_DEBUG` | `false` | boolean | 启用调试日志输出到 stderr |\n\n资料来源：[README.md:114-119]()\n\n## Token 管理机制\n\n### Token 验证函数\n\n`requireToken()` 函数封装了 token 的获取与验证逻辑，确保在所有需要认证的 API 调用前进行校验。资料来源：[src/common/config.ts:1-20]()\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN;\n  if (!token?.trim()) {\n    throw new Error(\"JUSTONEAPI_TOKEN environment variable is not set or is empty\");\n  }\n  return token;\n}\n```\n\n### Token 掩码处理\n\n为防止敏感信息在日志中泄露，系统提供了 Token 掩码功能。对于长度为 12 位以内的 Token，保留首尾各 2 位字符，中间用 `*` 替换；超过 12 位的 Token 保留前 6 位和后 4 位。资料来源：[src/common/config.ts:26-35]()\n\n```typescript\nfunction maskToken(token: string): string {\n  if (token.length <= 12) {\n    return token.slice(0, 2) + \"*\".repeat(token.length - 4) + token.slice(-2);\n  }\n  return token.slice(0, 6) + \"*\".repeat(8) + token.slice(-4);\n}\n```\n\n## URL 安全日志\n\n在 HTTP 请求处理过程中，敏感 Token 参数会被自动掩码处理后再输出日志，确保生产环境中不会泄露认证凭据。资料来源：[src/common/config.ts:40-55]()\n\n```mermaid\nsequenceDiagram\n    participant Client as 调用方\n    participant HTTP as HTTP 模块\n    participant Config as 配置模块\n    participant Log as 日志输出\n    \n    Client->>HTTP: 发起 API 请求\n    HTTP->>Config: 调用 toSafeUrlForLog()\n    Config->>Config: 检测 URL 中的 token 参数\n    Config->>Config: 执行 maskToken() 掩码\n    Config-->>Log: 返回安全 URL\n    HTTP-->>Client: 返回响应\n```\n\n## HTTP 请求与配置联动\n\n### 超时控制\n\n超时时间通过 `JUSTONEAPI_TIMEOUT_MS` 配置控制，内部使用 `AbortController` 实现。超时错误会被映射为 `NETWORK_TIMEOUT` 错误码。资料来源：[src/common/http.ts:35-45]()\n\n### 重试机制\n\n`JUSTONEAPI_RETRY` 配置指定初始请求失败后的重试次数。重试策略包含 250 毫秒的指数退避延迟。资料来源：[src/common/http.ts:50-60]()\n\n```mermaid\ngraph TD\n    A[发送请求] --> B{成功?}\n    B -->|是| C[返回结果]\n    B -->|否| D{可重试错误?}\n    D -->|AbortError| E[重试]\n    D -->|5xx 错误| E\n    D -->|ECONNRESET| E\n    D -->|ECONNREFUSED| E\n    D -->|ENOTFOUND| E\n    D -->|否| F[抛出异常]\n    E -->|attempt < retry| A\n    E -->|attempt >= retry| F\n```\n\n重试条件判断逻辑：资料来源：[src/common/http.ts:20-35]()\n\n## 版本配置\n\n版本信息从项目根目录的 `package.json` 动态读取，确保版本号与发布的包保持同步。若读取失败，默认回退至 `0.0.0`。资料来源：[src/version.ts:1-22]()\n\n## 错误处理与配置\n\n配置相关的错误会被规范化为 MCP 错误码，提供可操作的错误信息和明确的错误来源。\n\n| 错误码 | 触发条件 | 建议操作 |\n|--------|----------|---------|\n| `INVALID_TOKEN` | Token 无效或未激活 | 更新 `JUSTONEAPI_TOKEN` |\n| `RATE_LIMITED` | 请求频率超限 | 减慢请求速度 |\n| `DAILY_QUOTA_EXCEEDED` | 日配额用尽 | 等待次日或升级套餐 |\n| `INSUFFICIENT_BALANCE` | 账户余额不足 | 充值账户 |\n| `NETWORK_TIMEOUT` | 请求超时 | 检查网络或重试 |\n| `NETWORK_ERROR` | 网络连接失败 | 检查网络连接 |\n\n资料来源：[src/common/errors.ts:25-65]()\n\n## 配置验证流程\n\n```mermaid\nflowchart TD\n    A[进程启动] --> B[加载环境变量]\n    B --> C[验证 JUSTONEAPI_TOKEN]\n    C --> D{验证结果}\n    D -->|通过| E[初始化 Zod Schema]\n    D -->|失败| K[输出错误并退出]\n    E --> F[注册 MCP 工具]\n    F --> G[启动服务监听]\n    G --> H[等待请求]\n    H --> I{收到请求}\n    I -->|unified_search_v1| J1[执行统一搜索]\n    I -->|kuaishou_search_video_v2| J2[执行快手搜索]\n    J1 --> L[注入 token 并调用 API]\n    J2 --> L\n    L --> M[返回原始 JSON]\n```\n\n## 配置文件示例\n\n### Claude Desktop 配置\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\n资料来源：[README.md:80-96]()\n\n## 最佳实践\n\n1. **Token 安全**：始终通过环境变量传递 Token，避免硬编码在配置文件中\n2. **超时设置**：根据网络环境调整 `JUSTONEAPI_TIMEOUT_MS`，默认 20 秒适合大多数场景\n3. **重试策略**：在不稳定网络环境下可适当增加 `JUSTONEAPI_RETRY` 值\n4. **调试模式**：生产环境应保持 `JUSTONEAPI_DEBUG` 为 `false`，仅在排查问题时启用\n\n---\n\n<a id='tools-overview'></a>\n\n## 工具概览\n\n### 相关页面\n\n相关主题：[统一搜索工具](#unified-search), [平台专用工具](#platform-tools)\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</details>\n\n# 工具概览\n\n## 1. 概述\n\nJustOneAPI MCP（Model Context Protocol）是一个 MCP 服务器项目，旨在为 Claude Desktop、Cursor 等 MCP 主机提供对中国社交媒体和新闻平台的数据搜索能力。该项目采用\"传输而非转换\"（Transport, not transformation）的设计理念，优先保证数据的稳定性和原始性 资料来源：[README.md:1]()。\n\n工具（Tools）是 MCP 协议中的核心概念，每个工具代表一个可调用的功能单元。在 justoneapi-mcp 中，工具通过 `@modelcontextprotocol/sdk` 框架注册到 MCP 主机，用户可以通过自然语言或结构化参数调用这些工具 资料来源：[src/index.ts:1-30]()。\n\n## 2. 架构设计\n\n### 2.1 整体架构\n\n```mermaid\ngraph TD\n    subgraph MCP主机\n        A[Claude Desktop / Cursor]\n    end\n    \n    subgraph justoneapi-mcp\n        B[工具注册层<br/>src/index.ts]\n        C[工具实现层<br/>src/tools/]\n        D[公共组件层<br/>src/common/]\n    end\n    \n    subgraph 外部依赖\n        E[JustOneAPI 服务端]\n    end\n    \n    A -->|MCP 协议调用| B\n    B --> C\n    C --> D\n    D -->|HTTP 请求| E\n    \n    style A fill:#e1f5fe\n    style E fill:#fff3e0\n```\n\n### 2.2 请求处理流程\n\n```mermaid\nsequenceDiagram\n    participant U as 用户\n    participant M as MCP主机\n    participant S as justoneapi-mcp\n    participant A as JustOneAPI\n    \n    U->>M: 自然语言请求\n    M->>S: 调用工具\n    S->>S: 参数验证<br/>Zod Schema\n    S->>A: HTTP GET请求\n    A->>S: JSON响应\n    S->>S: 错误映射\n    S->>M: 结构化结果\n    M->>U: 返回结果\n```\n\n## 3. 可用工具列表\n\n### 3.1 当前版本工具\n\n| 工具名称 | 版本 | 功能描述 | 平台支持 |\n|---------|------|----------|----------|\n| `unified_search_v1` | v1 | 统一多平台搜索 | Weibo、WeChat、Zhihu、Douyin、Xiaohongshu、Bilibili、Kuaishou、News |\n| `kuaishou_search_video_v2` | v2 | 快手视频搜索 | 快手平台专用 |\n\n资料来源：[TOOLS.md:1-25]()\n\n### 3.2 工具命名规范\n\n所有工具遵循统一的命名约定：`{platform}_{action}_{version}` 资料来源：[README.md:45-46]()\n\n- **平台前缀**（platform）：指定目标平台，如 `kuaishou`、`unified`\n- **动作名称**（action）：表示操作类型，如 `search_video`、`search`\n- **版本号**（version）：使用语义化版本，如 `v1`、`v2`\n\n## 4. 统一搜索工具（unified_search_v1）\n\n### 4.1 工具描述\n\n`unified_search_v1` 是该 MCP 服务器的核心工具，支持跨多个中国社交媒体和新闻平台进行联合搜索。用户可以通过单一请求同时查询微博、微信、知乎、抖音、小红书、B站、快手和新闻平台的数据 资料来源：[src/index.ts:31-40]()。\n\n### 4.2 参数说明\n\n| 参数名 | 类型 | 必填 | 默认值 | 描述 |\n|-------|------|------|--------|------|\n| `keyword` | string | **是** | - | 搜索关键词，支持高级语法 |\n| `source` | string | 否 | `ALL` | 平台筛选器 |\n| `start` | string | 条件必填 | - | 开始时间（UTC+8），格式：yyyy-MM-dd HH:mm:ss |\n| `end` | string | 条件必填 | - | 结束时间（UTC+8），格式：yyyy-MM-dd HH:mm:ss |\n| `nextCursor` | string | 否 | - | 分页游标，用于获取后续页面 |\n\n资料来源：[src/tools/search/unified_search_v1.ts:15-42]()\n\n### 4.3 平台选项\n\n| 平台标识 | 描述 |\n|---------|------|\n| `ALL` | 全部平台（默认） |\n| `NEWS` | 新闻 |\n| `WEIBO` | 微博 |\n| `WEIXIN` | 微信 |\n| `ZHIHU` | 知乎 |\n| `DOUYIN` | 抖音 |\n| `XIAOHONGSHU` | 小红书 |\n| `BILIBILI` | B站（哔哩哔哩） |\n| `KUAISHOU` | 快手 |\n\n资料来源：[src/tools/search/unified_search_v1.ts:10-13]()\n\n### 4.4 搜索语法\n\n| 语法类型 | 语法格式 | 示例 | 说明 |\n|---------|---------|------|------|\n| 单关键词 | `keyword` | `deepseek` | 搜索包含指定关键词的内容 |\n| AND 搜索 | `word1 word2` | `deepseek chatgpt` | 同时包含两个关键词 |\n| OR 搜索 | `word1~word2` | `deepseek~chatgpt` | 包含任一关键词 |\n| NOT 搜索 | `word1 -word2` | `deepseek -chatgpt` | 包含前者，排除后者 |\n\n资料来源：[TOOLS.md:43-51]()\n\n### 4.5 参数验证逻辑\n\n```mermaid\ngraph TD\n    A[输入参数] --> B{keyword 是否为空?}\n    B -->|是| C[抛出错误]\n    B -->|否| D{是否使用分页?}\n    D -->|是 nextCursor| E[使用 nextCursor]\n    D -->|否 首頁| F{start 和 end 都存在?}\n    F -->|是| G[构建查询参数]\n    F -->|否| H[抛出错误：需要 start 和 end]\n    C --> I[返回 INVALID 请求]\n    H --> I\n    E --> J[构建查询参数<br/>含 nextCursor]\n    G --> K[调用 getJson]\n    J --> K\n```\n\n首次请求时，`start` 和 `end` 参数必须提供，且时间范围不能超过 84 天。使用分页时，只需提供 `nextCursor` 即可 资料来源：[src/tools/search/unified_search_v1.ts:30-37]()。\n\n## 5. 错误处理机制\n\n### 5.1 错误码映射表\n\n| 错误码 | 描述 | 用户操作建议 |\n|-------|------|-------------|\n| `INVALID_TOKEN` | Token 无效或未激活 | 更新 `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | 数据采集失败 | 稍后重试 |\n| `RATE_LIMITED` | 请求过于频繁 | 降低请求频率，稍后重试 |\n| `DAILY_QUOTA_EXCEEDED` | 达到每日使用限额 | 等待明天或升级套餐 |\n| `INSUFFICIENT_BALANCE` | 账户余额不足 | 充值账户 |\n| `PERMISSION_DENIED` | 无权访问该资源 | 联系技术支持 |\n| `VALIDATION_ERROR` | 请求参数无效 | 检查输入值 |\n| `INTERNAL_ERROR` | 服务器内部错误 | 稍后重试 |\n| `NETWORK_TIMEOUT` | 请求超时 | 检查网络或重试 |\n| `NETWORK_ERROR` | 网络连接失败 | 检查网络连接 |\n| `UPSTREAM_ERROR` | 上游服务未指明错误 | 重试或联系支持 |\n\n资料来源：[README.md:88-108]()\n\n### 5.2 错误格式\n\n所有错误均以统一格式返回：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n示例：\n\n```\nERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\n```\n\n资料来源：[src/common/errors.ts:1-30]()\n\n### 5.3 错误处理流程\n\n```mermaid\ngraph TD\n    A[HTTP 响应] --> B{HTTP 状态码}\n    B -->|200| C{业务 code}\n    B -->|非 200| D[抛出 NETWORK_ERROR]\n    C -->|0| E[返回成功响应]\n    C -->|非 0| F[映射错误码]\n    F --> G[构建 MCP 错误格式]\n    D --> G\n    E --> H[返回 JSON 数据]\n    G --> I[返回错误信息]\n```\n\n错误映射逻辑会自动识别超时、HTTP 状态码、网络错误等不同类型的故障，并将其转换为用户友好的错误信息 资料来源：[src/common/errors.ts:35-70]()。\n\n## 6. HTTP 请求机制\n\n### 6.1 重试策略\n\n```mermaid\ngraph TD\n    A[请求发起] --> B{尝试次数 <= 最大重试次数?}\n    B -->|是| C[发起 HTTP 请求]\n    C --> D{请求成功?}\n    D -->|是| E[返回响应]\n    D -->|否| F{可重试错误?}\n    F -->|是| G[等待 250ms * 尝试次数]\n    F -->|否| H[抛出错误]\n    G --> B\n    B -->|否| H\n```\n\n可重试的错误类型包括：\n\n- 超时错误（`AbortError`）\n- HTTP 5xx 错误\n- 网络连接重置（`ECONNRESET`）\n- 连接被拒绝（`ECONNREFUSED`）\n- DNS 解析失败（`ENOTFOUND`）\n\n资料来源：[src/common/http.ts:1-45]()\n\n### 6.2 超时配置\n\n| 配置项 | 默认值 | 说明 |\n|-------|-------|------|\n| `JUSTONEAPI_TIMEOUT_MS` | 20000ms | 单次请求超时时间 |\n\n## 7. 认证与配置\n\n### 7.1 环境变量配置\n\n| 变量名 | 必填 | 默认值 | 描述 |\n|-------|------|--------|------|\n| `JUSTONEAPI_TOKEN` | **是** | - | JustOneAPI 访问令牌 |\n| `JUSTONEAPI_BASE_URL` | 否 | `https://api.justoneapi.com` | API 端点 |\n| `JUSTONEAPI_TIMEOUT_MS` | 否 | `20000` | 请求超时（毫秒） |\n| `JUSTONEAPI_RETRY` | 否 | `1` | 首次失败后的重试次数 |\n| `JUSTONEAPI_DEBUG` | 否 | `false` | 启用调试日志输出到 stderr |\n\n资料来源：[README.md:119-130]()\n\n### 7.2 Token 安全处理\n\n系统内置 Token 脱敏功能，在日志输出时会自动将 Token 替换为掩码格式（显示前 4 位和后 4 位） 资料来源：[src/common/config.ts:1-20]()。\n\n示例：\n\n```\n原始 Token: sk-abc123def456ghi789\n日志显示:   sk-abc***ghi789\n```\n\n## 8. 分页机制\n\n### 8.1 分页流程\n\n当搜索结果存在多页时，响应中会包含 `nextCursor` 字段。用户可以通过以下方式继续获取更多结果：\n\n- \"Show me the next page of results\"\n- \"Get more results from the previous search\"\n- \"Continue with the next page\"\n\n```mermaid\ngraph LR\n    A[首页请求<br/>start + end] --> B[返回结果<br/>+ nextCursor]\n    B --> C{需要更多结果?}\n    C -->|是| D[下一页请求<br/>nextCursor]\n    C -->|否| E[结束]\n    D --> B\n```\n\n使用 `nextCursor` 分页时，无需再次提供 `start`、`end` 或 `source` 参数，因为游标中已包含这些信息 资料来源：[README.md:64-70]()。\n\n### 8.2 分页参数限制\n\n- 时间范围：首屏请求的时间跨度不能超过 84 天\n- 分页响应：每次返回 10-20 条结果\n\n## 9. 快速入门\n\n### 9.1 Claude Desktop 配置示例\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### 9.2 常用调用示例\n\n**跨平台搜索：**\n```\n使用 unified_search_v1 工具搜索\"AI\"，覆盖所有平台，时间范围为最近一个月。\n```\n\n**单平台搜索：**\n```\n搜索\"chatgpt\"相关内容，仅限微博平台，时间范围为2024年12月1日至2025年1月2日。\n```\n\n**分页获取：**\n```\nShow me more results\n```\n\n## 10. 输出格式\n\n### 10.1 成功响应\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-12-31T14:55:21Z\",\n  \"data\": {\n    // 平台特定数据结构\n  }\n}\n```\n\n### 10.2 错误响应\n\n```json\n{\n  \"isError\": true,\n  \"content\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"ERROR[ERROR_CODE] (upstream=XXX): Human-readable message\"\n    }\n  ]\n}\n```\n\n## 11. 项目依赖\n\n| 依赖包 | 版本 | 用途 |\n|-------|------|------|\n| `@modelcontextprotocol/sdk` | ^1.25.1 | MCP 协议 SDK |\n| `zod` | ^4.3.4 | 参数验证与 Schema 定义 |\n| `dotenv` | ^17.2.3 | 环境变量管理 |\n\n资料来源：[package.json:1-50]()\n\n---\n\n<a id='unified-search'></a>\n\n## 统一搜索工具\n\n### 相关页面\n\n相关主题：[工具概览](#tools-overview), [平台专用工具](#platform-tools)\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- [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# 统一搜索工具\n\n## 概述\n\n统一搜索工具（`unified_search_v1`）是 justoneapi-mcp 项目提供的核心功能，旨在为用户提供跨多个中国社交媒体和新闻平台的统一搜索能力。通过单一接口，用户可以同时检索微博、微信、知乎、抖音、小红书、B站、快手和新闻等多个平台的内容，无需逐个平台调用不同的 API。\n\n该工具遵循项目的核心设计理念——**传输而非转换**，即保持原始数据的完整性和保真度，不对上游响应进行字段解析或数据重组。资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 架构设计\n\n### 技术栈\n\n统一搜索工具基于以下技术组件构建：\n\n| 组件 | 技术选型 | 作用 |\n|------|----------|------|\n| MCP SDK | @modelcontextprotocol/sdk ^1.25.1 | 提供 MCP 服务器基础设施 |\n| 参数验证 | Zod ^4.3.4 | Schema 定义与输入验证 |\n| HTTP 客户端 | Node.js 内置 fetch | API 请求处理 |\n| 配置管理 | dotenv ^17.2.3 | 环境变量加载 |\n\n资料来源：[package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n### 模块依赖关系\n\n```mermaid\ngraph TD\n    A[unified_search_v1] --> B[requireToken]\n    A --> C[getJson]\n    A --> D[UnifiedSearchV1Input]\n    B --> E[config.ts - token验证]\n    C --> F[http.ts - HTTP请求]\n    F --> G[API Endpoint]\n    D --> H[Zod Schema验证]\n```\n\n## 工具注册与入口\n\n统一搜索工具通过 MCP SDK 的 `server.registerTool()` 方法注册到 MCP 服务器。工具注册时需要提供工具名称、描述和输入模式。资料来源：[src/index.ts:22-42](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n```typescript\nserver.registerTool(\n  \"unified_search_v1\",\n  {\n    description:\n      \"Unified search across multiple platforms (Weibo, WeChat, Zhihu, Douyin, Xiaohongshu, Bilibili, Kuaishou, News). Search by keyword with time range. Supports AND/OR/NOT operators and pagination. Returns raw JSON response.\",\n    inputSchema: UnifiedSearchV1Input.shape,\n  },\n  async (input) => {\n    // 处理逻辑\n  }\n);\n```\n\n### 错误处理机制\n\n工具执行过程中捕获所有异常，并通过 `toMcpErrorPayload()` 函数将错误转换为标准化的 MCP 错误格式返回。错误消息格式为：`ERROR[ERROR_CODE] (upstream=XXX): Human-readable message`。资料来源：[src/index.ts:31-39](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n## 输入参数定义\n\n`UnifiedSearchV1Input` 是统一搜索工具的 Zod Schema，定义了所有合法的输入参数及其验证规则。资料来源：[src/tools/search/unified_search_v1.ts:10-32](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n\n### 参数一览\n\n| 参数名 | 类型 | 必填 | 默认值 | 说明 |\n|--------|------|------|--------|------|\n| keyword | string | 是 | - | 搜索关键词，支持高级语法 |\n| source | PlatformType | 否 | ALL | 平台筛选器 |\n| start | string | 条件必填 | - | 开始时间（UTC+8），首页必需 |\n| end | string | 条件必填 | - | 结束时间（UTC+8），首页必需 |\n| nextCursor | string | 否 | - | 分页游标，用于后续页面 |\n\n### 平台类型枚举\n\n统一搜索支持以下平台类型：\n\n```typescript\nexport const PlatformType = z.enum([\n  \"ALL\",\n  \"NEWS\",\n  \"WEIBO\",\n  \"WEIXIN\",\n  \"ZHIHU\",\n  \"DOUYIN\",\n  \"XIAOHONGSHU\",\n  \"BILIBILI\",\n  \"KUAISHOU\",\n]);\n```\n\n资料来源：[src/tools/search/unified_search_v1.ts:7-18](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n\n| 枚举值 | 平台名称 |\n|--------|----------|\n| ALL | 所有平台（默认） |\n| NEWS | 新闻 |\n| WEIBO | 微博 |\n| WEIXIN | 微信 |\n| ZHIHU | 知乎 |\n| DOUYIN | 抖音 |\n| XIAOHONGSHU | 小红书 |\n| BILIBILI | B站 |\n| KUAISHOU | 快手 |\n\n### 参数验证规则\n\n1. **keyword**：最短长度 1 个字符，不允许空字符串\n2. **start/end**：首次请求时必须提供，且结束时间必须晚于开始时间\n3. **时间范围**：查询时间跨度必须在 84 天以内\n4. **nextCursor**：用于分页时，必须替代 start/end 参数使用\n\n## 搜索语法\n\n统一搜索工具支持丰富的高级搜索语法，允许用户精确表达搜索意图。资料来源：[TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n\n### 语法类型\n\n| 语法类型 | 示例 | 说明 |\n|----------|------|------|\n| 单关键词 | `deepseek` | 搜索包含该关键词的所有内容 |\n| AND 搜索 | `deepseek chatgpt` | 两个关键词必须同时出现 |\n| OR 搜索 | `deepseek~chatgpt` | 两个关键词任一出现即可 |\n| NOT 搜索 | `deepseek -chatgpt` | 包含第一个词但排除第二个词 |\n\n### 使用示例\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## 请求处理流程\n\n```mermaid\nsequenceDiagram\n    participant User as 用户\n    participant MCP as MCP服务器\n    participant Handler as unifiedSearchV1\n    participant HTTP as getJson\n    participant API as JustOneAPI\n\n    User->>MCP: unified_search_v1 调用\n    MCP->>Handler: 传入输入参数\n    Handler->>Handler: Zod Schema 验证\n    Handler->>Handler: 构建 URL 参数\n    Handler->>HTTP: 发起 GET 请求\n    HTTP->>API: GET /api/search/v1\n    API-->>HTTP: JSON 响应\n    HTTP-->>Handler: 解析后的 JSON\n    Handler-->>MCP: 返回内容数组\n    MCP-->>User: 格式化输出\n```\n\n## 分页机制\n\n统一搜索工具采用游标式分页机制，与传统的页码分页方式不同。当搜索结果存在后续页面时，响应中会包含 `nextCursor` 字段。资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n### 分页流程\n\n```mermaid\ngraph TD\n    A[首次搜索请求] --> B{提供 start/end?}\n    B -->|是| C[发起首页请求]\n    B -->|否| D[使用 nextCursor]\n    C --> E[获取响应]\n    D --> E\n    E --> F{存在 nextCursor?}\n    F -->|是| G[返回 nextCursor 给用户]\n    F -->|否| H[搜索完成]\n    G --> I[用户请求下一页]\n    I --> D\n```\n\n### 分页使用方式\n\n用户获取下一页结果时，无需再次提供 `start`、`end` 或 `source` 参数，因为游标中已包含这些信息：\n\n```\nShow me the next page of results\nGet more results from the previous search\nContinue with the next page\n```\n\n## HTTP 请求处理\n\n### getJson 函数\n\n统一搜索工具内部使用 `getJson()` 函数处理所有 HTTP 请求，该函数位于 `src/common/http.ts`。资料来源：[src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n### 重试策略\n\n`getJson()` 实现了智能重试机制，仅在以下情况下进行重试：\n\n| 重试条件 | 触发场景 |\n|----------|----------|\n| 请求超时 | AbortError 异常 |\n| HTTP 5xx 错误 | 服务器内部错误 |\n| 网络连接重置 | ECONNRESET |\n| 连接被拒绝 | ECONNREFUSED |\n| DNS 解析失败 | ENOTFOUND |\n\n重试逻辑采用指数退避策略，每次重试间隔为 `250 * attempt` 毫秒。\n\n### 请求超时\n\n默认请求超时时间为 20000 毫秒（20秒），可通过 `JUSTONEAPI_TIMEOUT_MS` 环境变量配置。资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 错误处理\n\n### 错误码映射\n\n项目维护了一套标准化的错误码体系，所有错误最终都会映射到这些代码。资料来源：[src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n| 错误码 | 含义 | 建议操作 |\n|--------|------|----------|\n| INVALID_TOKEN | Token 无效或已失效 | 更新 JUSTONEAPI_TOKEN |\n| COLLECT_FAILED | 数据采集失败 | 稍后重试 |\n| RATE_LIMITED | 请求过于频繁 | 降低请求频率 |\n| DAILY_QUOTA_EXCEEDED | 达到日使用限额 | 等待次日或升级套餐 |\n| INSUFFICIENT_BALANCE | 账户余额不足 | 充值账户 |\n| PERMISSION_DENIED | 无权访问该资源 | 联系客服 |\n| VALIDATION_ERROR | 请求参数无效 | 检查输入值 |\n| INTERNAL_ERROR | 服务器内部错误 | 稍后重试 |\n| NETWORK_TIMEOUT | 请求超时 | 检查网络或重试 |\n| NETWORK_ERROR | 网络连接失败 | 检查网络连接 |\n| UPSTREAM_ERROR | 上游未指明错误 | 重试或联系客服 |\n\n### 错误响应格式\n\n所有错误均以统一格式返回：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n其中 `upstream` 字段表示上游 API 返回的原始错误码。\n\n## 配置管理\n\n### 环境变量\n\n统一搜索工具使用以下环境变量进行配置：资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n| 变量名 | 必填 | 默认值 | 说明 |\n|--------|------|--------|------|\n| JUSTONEAPI_TOKEN | 是 | - | 您的 JustOneAPI 令牌 |\n| JUSTONEAPI_BASE_URL | 否 | https://api.justoneapi.com | API 端点 |\n| JUSTONEAPI_TIMEOUT_MS | 否 | 20000 | 请求超时（毫秒） |\n| JUSTONEAPI_RETRY | 否 | 1 | 首次失败后的重试次数 |\n| JUSTONEAPI_DEBUG | 否 | false | 启用调试日志输出 |\n\n### Token 安全\n\n配置模块实现了 Token 脱敏功能，在日志记录时会自动将 Token 遮蔽，防止敏感信息泄露。资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n\n## 输出格式\n\n统一搜索工具返回原始 JSON 响应，不进行任何字段标准化或数据结构重组。这是项目\"传输而非转换\"设计理念的体现。资料来源：[TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n\n### 成功响应结构\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-12-31T14:55:00\",\n  \"data\": {\n    // 平台特定的数据结构\n  }\n}\n```\n\n- `code: 0` 表示成功\n- `code != 0` 表示错误（参见错误处理章节）\n\n## 使用示例\n\n### 基础搜索\n\n使用自然语言请求统一搜索：\n\n```\nSearch for AI discussions on Chinese social media from last week\n```\n\nClaude 会自动转换为正确的 API 格式，处理日期格式化（UTC+8 时区），并返回聚合结果。\n\n### 高级搜索\n\n**平台特定搜索：**\n```\nSearch for \"chatgpt\" on Weibo only, from December 1st to January 2nd\n```\n\n**复杂查询：**\n```\nSearch for posts containing \"AI\" OR \"机器学习\" but NOT \"广告\" on Zhihu,\nfrom the last 30 days\n```\n\n### 配置示例\n\n在 Claude Desktop 的 `mcpServers` 配置中添加：\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## 与其他工具的关系\n\njustoneapi-mcp 项目中，除了统一搜索工具外，还提供了平台特定搜索工具，如 `kuaishou_search_video_v2`。两者都基于相同的底层 HTTP 和错误处理机制，但面向不同的使用场景。资料来源：[src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)\n\n| 工具名称 | 搜索范围 | 适用场景 |\n|----------|----------|----------|\n| unified_search_v1 | 多平台聚合搜索 | 跨平台舆情分析、品牌监控 |\n| kuaishou_search_video_v2 | 快手平台 | 快手视频专项研究 |\n\n---\n\n<a id='platform-tools'></a>\n\n## 平台专用工具\n\n### 相关页面\n\n相关主题：[工具概览](#tools-overview), [统一搜索工具](#unified-search)\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/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.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</details>\n\n# 平台专用工具\n\n## 概述\n\n平台专用工具（Platform-Specific Tools）是 justoneapi-mcp 项目中针对特定社交媒体平台提供深度搜索能力的功能模块。与统一搜索工具 `unified_search_v1` 不同，平台专用工具针对单个平台进行优化，提供更精细的参数控制和平台特定的功能实现。\n\n当前已实现的平台专用工具包括：\n\n| 工具名称 | 平台 | 版本 | 功能描述 |\n|---------|------|------|---------|\n| `kuaishou_search_video_v2` | 快手 | v2 | 快手视频关键词搜索 |\n\n资料来源：[src/index.ts:9]()\n\n## 架构设计\n\n### 工具注册机制\n\n平台专用工具通过 MCP SDK 的 `registerTool` 方法注册到服务器中。每个工具包含三个核心组成部分：工具名称、描述信息（含 Zod 输入验证 schema）和异步处理函数。\n\n```mermaid\ngraph TD\n    A[MCP 主机发送请求] --> B[服务器接收工具调用]\n    B --> C[匹配工具名称]\n    C --> D{找到对应工具?}\n    D -->|是| E[执行异步处理函数]\n    D -->|否| F[返回错误]\n    E --> G[调用平台 API]\n    G --> H{请求成功?}\n    H -->|是| I[返回原始 JSON]\n    H -->|否| J[错误处理]\n    J --> K[转换为 MCP 错误格式]\n```\n\n资料来源：[src/index.ts:18-40]()\n\n### 目录结构\n\n平台专用工具遵循统一的目录组织规范：\n\n```\nsrc/tools/\n├── kuaishou/\n│   └── search_video_v2.ts    # 快手视频搜索 v2\n└── search/\n    └── unified_search_v1.ts  # 统一搜索 v1\n```\n\n这种结构确保了代码的模块化组织和可维护性，每个平台拥有独立的子目录，便于后续扩展更多平台工具。\n\n## 快手视频搜索工具\n\n### 功能介绍\n\n`kuaishou_search_video_v2` 是专门用于在快手平台搜索视频内容的工具。该工具通过快手开放 API 获取视频搜索结果，返回未经处理的原始 JSON 数据，确保数据完整性。\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:1-4]()\n\n### 输入参数\n\n| 参数名 | 类型 | 必填 | 默认值 | 说明 |\n|-------|------|------|--------|------|\n| `keyword` | string | 是 | - | 搜索关键词，如 \"dance\" |\n| `page` | number | 否 | 1 | 页码，必须为正整数 |\n\n输入验证由 Zod 库提供支持，确保参数类型的正确性：\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资料来源：[src/tools/kuaishou/search_video_v2.ts:6-9]()\n\n### API 请求构建\n\n工具将输入参数转换为 URL 查询参数并调用内部 HTTP 模块：\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请求流程：\n\n1. 从环境配置获取 API Token 并进行 URL 编码\n2. 对搜索关键词进行 URL 编码处理\n3. 构建完整的 API 端点 URL\n4. 调用 `getJson` 函数发起 HTTP GET 请求\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:11-18]()\n\n## 工具注册流程\n\n### 注册代码示例\n\n在主入口文件中，工具通过标准化的注册流程添加到 MCP 服务器：\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    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          {\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:18-40]()\n\n### 注册参数说明\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| 工具名称 | string | MCP 协议中调用该工具的标识符，遵循 `{platform}_{action}_{version}` 命名规范 |\n| description | string | 工具功能描述，供 MCP 主机（如 Claude Desktop）展示给用户 |\n| inputSchema | ZodObject | 使用 Zod 库定义的输入验证模式，包含参数类型、默认值和描述 |\n| 处理函数 | async function | 接收验证后的输入参数，执行工具逻辑并返回结果 |\n\n## 错误处理机制\n\n### 错误转换流程\n\n平台专用工具使用统一的错误处理机制 `toMcpErrorPayload` 将各类错误转换为标准化的 MCP 错误格式：\n\n```mermaid\ngraph TD\n    A[异常发生] --> B{错误类型判断}\n    B -->|AbortError| C[NETWORK_TIMEOUT]\n    B -->|upstreamCode| D[业务错误码映射]\n    B -->|httpStatus| E[UPSTREAM_ERROR]\n    B -->|cause/code| F[NETWORK_ERROR]\n    B -->|其他| G[UPSTREAM_ERROR]\n    \n    D --> H[返回 MCP 错误对象]\n    C --> H\n    E --> H\n    F --> H\n    G --> H\n    \n    H --> I[格式化错误消息]\n    I --> J[ERROR[CODE] (upstream=X): message]\n```\n\n资料来源：[src/common/errors.ts:30-60]()\n\n### 错误码映射表\n\n| 上游错误码 | MCP 错误码 | 说明 |\n|-----------|-----------|------|\n| 100 | INVALID_TOKEN | Token 无效或已失效 |\n| 301 | COLLECT_FAILED | 数据采集失败 |\n| 302 | RATE_LIMITED | 请求频率超限 |\n| 303 | DAILY_QUOTA_EXCEEDED | 每日配额已用尽 |\n| 400 | VALIDATION_ERROR | 参数验证错误 |\n| 500 | INTERNAL_ERROR | 服务器内部错误 |\n| 600 | PERMISSION_DENIED | 无权限访问 |\n| 601 | INSUFFICIENT_BALANCE | 账户余额不足 |\n\n资料来源：[src/common/errors.ts:68-85]()\n\n## 底层支持模块\n\n### HTTP 请求模块\n\n平台专用工具通过 `getJson` 函数发起 API 请求，该函数具备以下特性：\n\n- **自动重试机制**：对超时、5xx 错误和网络连接错误进行自动重试\n- **可配置超时**：支持通过 `JUSTONEAPI_TIMEOUT_MS` 环境变量配置请求超时时间，默认 20000ms\n- **请求重试次数**：可通过 `JUSTONEAPI_RETRY` 环境变量配置，默认 1 次重试\n- **Token 注入**：自动将认证 Token 添加到请求头\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:20-30]()\n\n### 配置管理模块\n\n工具通过 `requireToken` 函数获取环境变量中配置的 API Token：\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN;\n  if (!token?.trim()) {\n    throw new Error(\"JUSTONEAPI_TOKEN is required\");\n  }\n  return token;\n}\n```\n\n资料来源：[src/common/config.ts]()\n\n## 工具命名规范\n\n平台专用工具遵循统一的命名约定：\n\n```\n{platform}_{action}_{version}\n```\n\n| 组成部分 | 说明 | 示例 |\n|---------|------|------|\n| platform | 目标平台标识（小写） | kuaishou、douyin、weibo |\n| action | 操作类型 | search_video、get_user |\n| version | API 版本号 | v1、v2 |\n\n当前已实现的工具：\n\n| 工具名称 | 平台 | 版本 | 状态 |\n|---------|------|------|------|\n| kuaishou_search_video_v2 | 快手 | v2 | ✅ 已实现 |\n| unified_search_v1 | 统一搜索 | v1 | ✅ 已实现 |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 扩展指南\n\n### 添加新平台工具的步骤\n\n1. **创建工具目录**：在 `src/tools/` 下创建平台专属目录\n2. **定义输入模式**：使用 Zod 定义输入参数验证 schema\n3. **实现工具函数**：调用 `getJson` 发起 API 请求\n4. **注册工具**：在 `src/index.ts` 中使用 `server.registerTool` 注册\n5. **更新文档**：在 README.md 和 TOOLS.md 中添加工具说明\n\n### 依赖要求\n\n项目使用以下核心依赖实现平台专用工具功能：\n\n| 依赖包 | 版本 | 用途 |\n|-------|------|------|\n| @modelcontextprotocol/sdk | ^1.25.1 | MCP 服务器 SDK |\n| zod | ^4.3.4 | 输入参数验证 |\n| dotenv | ^17.2.3 | 环境变量管理 |\n\n资料来源：[package.json:18-30]()\n\n## 与统一搜索工具的对比\n\n| 特性 | 平台专用工具 | 统一搜索工具 |\n|------|-------------|-------------|\n| 覆盖范围 | 单平台 | 多平台聚合 |\n| 参数设计 | 平台特定参数 | 通用参数 |\n| 使用场景 | 深度平台分析 | 跨平台概览 |\n| 实现复杂度 | 较高 | 较低 |\n| 扩展方式 | 按平台添加 | 通用扩展 |\n\n资料来源：[src/tools/search/unified_search_v1.ts]()\n\n## 未来规划\n\n根据项目规划，以下平台专用工具即将推出：\n\n- 抖音视频搜索\n- 微博帖子搜索\n- Bilibili 视频搜索\n- 微信内容搜索\n- 知乎内容搜索\n- 小红书内容搜索\n- 新闻聚合搜索\n\n资料来源：[TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n\n---\n\n<a id='error-handling'></a>\n\n## 错误处理\n\n### 相关页面\n\n相关主题：[配置管理](#configuration), [认证授权](#authentication)\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- [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</details>\n\n# 错误处理\n\n## 概述\n\njustoneapi-mcp 采用统一的错误处理机制，将上游 API 的原始响应转换为标准化的 MCP 错误格式。该项目遵循\"传输而非转换\"（Transport, not transformation）的设计理念，在保持数据完整性的同时，为用户提供清晰、可操作的错误信息。 资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n错误处理模块位于 `src/common/errors.ts`，负责以下核心功能：\n\n- 定义标准化错误码体系（`JOAErrorCode`）\n- 映射上游 API 错误码到 MCP 错误码\n- 构建用户友好的错误消息\n- 将各类异常转换为统一的 MCP 错误负载\n\n## 错误码体系\n\n### JOAErrorCode 类型定义\n\n项目定义了 11 种标准化错误码，涵盖认证失败、网络问题、配额限制等各种场景。 资料来源：[src/common/errors.ts:58-69]()\n\n```typescript\nexport type JOAErrorCode =\n  | \"INVALID_TOKEN\"\n  | \"COLLECT_FAILED\"\n  | \"RATE_LIMITED\"\n  | \"DAILY_QUOTA_EXCEEDED\"\n  | \"VALIDATION_ERROR\"\n  | \"INTERNAL_ERROR\"\n  | \"PERMISSION_DENIED\"\n  | \"INSUFFICIENT_BALANCE\"\n  | \"NETWORK_TIMEOUT\"\n  | \"NETWORK_ERROR\"\n  | \"UPSTREAM_ERROR\";\n```\n\n### 错误码对照表\n\n| 错误码 | 说明 | 用户操作 |\n|--------|------|----------|\n| `INVALID_TOKEN` | Token 无效或未激活 | 更新 `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | 数据采集失败 | 稍后重试 |\n| `RATE_LIMITED` | 请求频率超限 | 降低请求频率后重试 |\n| `DAILY_QUOTA_EXCEEDED` | 达到每日用量限制 | 明天重试或升级套餐 |\n| `VALIDATION_ERROR` | 请求参数无效 | 检查输入值 |\n| `INTERNAL_ERROR` | 服务器内部错误 | 稍后重试 |\n| `PERMISSION_DENIED` | 无权访问该资源 | 联系客服 |\n| `INSUFFICIENT_BALANCE` | 账户余额不足 | 充值账户 |\n| `NETWORK_TIMEOUT` | 请求超时 | 检查网络或重试 |\n| `NETWORK_ERROR` | 网络连接失败 | 检查网络连接 |\n| `UPSTREAM_ERROR` | 上游未指定错误 | 重试或联系客服 |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 错误映射机制\n\n### 上游错误码到 MCP 错误码的转换\n\n`mapUpstreamCode()` 函数将上游 API 返回的数字错误码映射为标准化的 JOA 错误码。 资料来源：[src/common/errors.ts:77-94]()\n\n```typescript\nexport function mapUpstreamCode(code: number | undefined): JOAErrorCode {\n  switch (code) {\n    case 100:\n      return \"INVALID_TOKEN\";\n    case 301:\n      return \"COLLECT_FAILED\";\n    case 302:\n      return \"RATE_LIMITED\";\n    case 303:\n      return \"DAILY_QUOTA_EXCEEDED\";\n    case 400:\n      return \"VALIDATION_ERROR\";\n    case 500:\n      return \"INTERNAL_ERROR\";\n    case 600:\n      return \"PERMISSION_DENIED\";\n    case 601:\n      return \"INSUFFICIENT_BALANCE\";\n    default:\n      return \"UPSTREAM_ERROR\";\n  }\n}\n```\n\n### 映射关系图\n\n```mermaid\ngraph LR\n    A[\"上游错误码\"] --> B{\"code 值\"}\n    B -->|100| C[\"INVALID_TOKEN\"]\n    B -->|301| D[\"COLLECT_FAILED\"]\n    B -->|302| E[\"RATE_LIMITED\"]\n    B -->|303| F[\"DAILY_QUOTA_EXCEEDED\"]\n    B -->|400| G[\"VALIDATION_ERROR\"]\n    B -->|500| H[\"INTERNAL_ERROR\"]\n    B -->|600| I[\"PERMISSION_DENIED\"]\n    B -->|601| J[\"INSUFFICIENT_BALANCE\"]\n    B -->|其他| K[\"UPSTREAM_ERROR\"]\n```\n\n## 用户消息构建\n\n### buildUserMessage 函数\n\n`buildUserMessage()` 函数为每种错误码生成用户友好的错误消息。当上游返回消息时，优先使用上游消息；否则使用默认消息。 资料来源：[src/common/errors.ts:96-128]()\n\n```typescript\nexport function buildUserMessage(mcpCode: JOAErrorCode, upstreamMessage?: string | null): string {\n  const base = upstreamMessage && upstreamMessage.trim() ? upstreamMessage.trim() : undefined;\n\n  switch (mcpCode) {\n    case \"INVALID_TOKEN\":\n      return base ?? \"Invalid or inactive token. Please update JUSTONEAPI_TOKEN.\";\n    case \"COLLECT_FAILED\":\n      return base ?? \"Collection failed. Please retry after a short delay.\";\n    case \"RATE_LIMITED\":\n      return base ?? \"Rate limit exceeded. Please slow down and retry later.\";\n    case \"DAILY_QUOTA_EXCEEDED\":\n      return base ?? \"Daily quota exceeded. Please try again tomorrow or upgrade your plan.\";\n    case \"VALIDATION_ERROR\":\n      return base ?? \"Invalid parameters. Please check the input values.\";\n    case \"PERMISSION_DENIED\":\n      return base ?? \"Permission denied. Please verify your account permissions.\";\n    case \"INSUFFICIENT_BALANCE\":\n      return base ?? \"Insufficient balance. Please top up your account.\";\n    case \"INTERNAL_ERROR\":\n      return base ?? \"Internal server error. Please retry later.\";\n    case \"NETWORK_TIMEOUT\":\n      return base ?? \"Network timeout. Please retry later.\";\n    case \"NETWORK_ERROR\":\n      return base ?? \"Network error. Please retry later.\";\n    default:\n      return base ?? \"Upstream error. Please retry later.\";\n  }\n}\n```\n\n## 错误转换\n\n### toMcpErrorPayload 函数\n\n`toMcpErrorPayload()` 是核心错误转换函数，将各种类型的异常统一转换为 MCP 错误负载格式。 资料来源：[src/common/errors.ts:130-173]()\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    code?: string;\n    cause?: unknown;\n  };\n\n  // AbortController 超时\n  if (error.name === \"AbortError\") {\n    return { code: \"NETWORK_TIMEOUT\", message: buildUserMessage(\"NETWORK_TIMEOUT\") };\n  }\n\n  // 业务错误码\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  // HTTP 级别错误\n  if (typeof error.httpStatus === \"number\") {\n    return {\n      code: \"UPSTREAM_ERROR\",\n      message: error.message ?? `HTTP error ${error.httpStatus}`,\n      httpStatus: error.httpStatus,\n    };\n  }\n\n  // 网络连接错误\n  if (error.cause || error.code === \"ECONNREFUSED\" || error.code === \"ENOTFOUND\") {\n    return {\n      code: \"NETWORK_ERROR\",\n      message: error.message ?? buildUserMessage(\"NETWORK_ERROR\"),\n    };\n  }\n\n  return { code: \"UPSTREAM_ERROR\", message: error.message ?? \"Unknown error\" };\n}\n```\n\n### 错误转换流程图\n\n```mermaid\ngraph TD\n    A[\"捕获异常 e\"] --> B{\"error.name === 'AbortError'?\"}\n    B -->|是| C[\"返回 NETWORK_TIMEOUT\"]\n    B -->|否| D{\"error.upstreamCode !== undefined?\"}\n    D -->|是| E[\"mapUpstreamCode + buildUserMessage\"]\n    D -->|否| F{\"typeof error.httpStatus === 'number'?\"}\n    F -->|是| G[\"返回 UPSTREAM_ERROR\"]\n    F -->|否| H{\"error.cause || ECONNREFUSED || ENOTFOUND?\"}\n    H -->|是| I[\"返回 NETWORK_ERROR\"]\n    H -->|否| J[\"返回 UPSTREAM_ERROR + Unknown error\"]\n```\n\n## 上游响应验证\n\n### isUpstreamOk 函数\n\n用于判断上游 API 响应是否成功。 资料来源：[src/common/errors.ts:71-75]()\n\n```typescript\nexport type UpstreamResponse = {\n  code?: number;\n  message?: string | null;\n  recordTime?: string;\n  data?: unknown;\n};\n\nexport function isUpstreamOk(resp: UpstreamResponse): boolean {\n  return Number(resp?.code) === 0;\n}\n```\n\n### UpstreamResponse 类型定义\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `code` | number | 响应状态码，`0` 表示成功 |\n| `message` | string \\| null | 响应消息 |\n| `recordTime` | string | 记录时间 |\n| `data` | unknown | 响应数据 |\n\n资料来源：[src/common/errors.ts:54-56]()\n\n## HTTP 请求重试机制\n\n### getJson 函数中的重试逻辑\n\n`src/common/http.ts` 中的 `getJson()` 函数实现了智能重试机制，针对特定错误进行自动重试。 资料来源：[src/common/http.ts]()\n\n重试条件：\n\n- `AbortError`（超时）\n- HTTP 5xx 错误\n- `ECONNRESET`\n- `ECONNREFUSED`\n- `ENOTFOUND`\n\n```mermaid\ngraph TD\n    A[\"发起 HTTP 请求\"] --> B{\"请求成功?\"}\n    B -->|是| C[\"返回响应 JSON\"]\n    B -->|否| D{\"可重试错误?\"}\n    D -->|否| E[\"抛出异常\"]\n    D -->|是| F{\"尝试次数 < 最大次数?\"}\n    F -->|是| G[\"等待 250ms * attempt\"]\n    G --> H[\"重新发起请求\"]\n    H --> B\n    F -->|否| E\n```\n\n## MCP 工具中的错误处理\n\n### 统一搜索工具示例\n\n在 `src/index.ts` 中，所有工具都使用统一的错误处理模式： 资料来源：[src/index.ts]()\n\n```typescript\nasync (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\n### 错误格式规范\n\n所有错误按照统一格式返回：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n### 示例\n\n| 场景 | 错误输出 |\n|------|----------|\n| Token 无效 | `ERROR[INVALID_TOKEN] (upstream=100): Invalid or inactive token. Please update JUSTONEAPI_TOKEN.` |\n| 频率限制 | `ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.` |\n| 网络超时 | `ERROR[NETWORK_TIMEOUT] (upstream=N/A): Network timeout. Please retry later.` |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n### MCP 工具返回格式\n\n当工具调用出错时，返回包含 `isError: true` 的响应：\n\n```json\n{\n  \"isError\": true,\n  \"content\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\"\n    }\n  ]\n}\n```\n\n## 配置与环境变量\n\n### 错误处理相关配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `JUSTONEAPI_TOKEN` | *(必填)* | API 认证令牌 |\n| `JUSTONEAPI_BASE_URL` | `https://api.justoneapi.com` | API 端点 |\n| `JUSTONEAPI_TIMEOUT_MS` | `20000` | 请求超时（毫秒） |\n| `JUSTONEAPI_RETRY` | `1` | 首次失败后的重试次数 |\n| `JUSTONEAPI_DEBUG` | `false` | 启用调试日志输出到 stderr |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 设计理念\n\n### Transport, not transformation\n\n该项目坚持\"传输而非转换\"的设计哲学：\n\n- 返回上游 API 的原始 JSON 响应\n- 不进行字段解析或数据规范化\n- 不重构数据结构\n- 确保长期兼容性\n\n错误处理模块在保持数据完整性的同时，提供了必要的错误信息翻译层，使用户能够快速定位和解决问题。 资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 相关文件\n\n| 文件路径 | 说明 |\n|----------|------|\n| `src/common/errors.ts` | 核心错误处理模块 |\n| `src/common/http.ts` | HTTP 请求与重试机制 |\n| `src/common/config.ts` | 配置管理（含 URL 安全日志） |\n| `src/index.ts` | MCP 工具注册与错误处理集成 |\n| `README.md` | 错误处理文档 |\n| `TOOLS.md` | 工具文档中的错误处理说明 |\n\n---\n\n<a id='authentication'></a>\n\n## 认证授权\n\n### 相关页面\n\n相关主题：[安装部署](#installation), [配置管理](#configuration)\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- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n</details>\n\n# 认证授权\n\n## 概述\n\njustoneapi-mcp 采用基于令牌（Token）的简洁认证机制。所有 API 请求必须携带有效的 JustOneAPI 令牌才能访问上游服务。该设计遵循 \"Transport, not transformation\" 原则，在令牌验证通过后直接透传请求，不进行额外的数据转换或协议转换。\n\n认证流程的核心组件位于 `src/common/config.ts` 模块中，负责令牌的读取、验证和安全传输。\n\n## 核心配置\n\n### 环境变量配置\n\n| 变量名 | 必填 | 默认值 | 说明 |\n|--------|------|--------|------|\n| `JUSTONEAPI_TOKEN` | 是 | 无 | 用户的 JustOneAPI 访问令牌 |\n| `JUSTONEAPI_BASE_URL` | 否 | `https://api.justoneapi.com` | API 端点地址 |\n| `JUSTONEAPI_TIMEOUT_MS` | 否 | `20000` | 请求超时时间（毫秒） |\n| `JUSTONEAPI_RETRY` | 否 | `1` | 首次失败后的重试次数 |\n| `JUSTONEAPI_DEBUG` | 否 | `false` | 是否启用调试日志输出 |\n\n### 令牌获取\n\n用户需访问 [justoneapi.com](https://dashboard.justoneapi.com/en/login) 注册账号并获取 API 令牌。令牌将作为查询参数附加到每个 API 请求中。\n\n## 认证流程\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Server\n    participant Config as config.ts\n    participant HTTP as http.ts\n    participant API as JustOneAPI\n    \n    Note over MCP: 服务启动\n    MCP->>Config: 读取 JUSTONEAPI_TOKEN\n    alt Token 为空或空白\n        Config-->>MCP: 抛出配置错误\n        MCP->>MCP: 终止启动并输出错误信息\n    end\n    \n    Note over MCP: 用户发起工具调用\n    MCP->>Config: requireToken()\n    Config->>Config: 验证令牌存在\n    MCP->>HTTP: 构建请求（含令牌）\n    HTTP->>API: GET /api/xxx?token=xxx\n    API-->>HTTP: 响应 (code=0 或 code!=0)\n    \n    alt 认证失败\n        API-->>HTTP: code != 0\n        HTTP-->>MCP: 抛出 UpstreamError\n        MCP-->>用户: ERROR[INVALID_TOKEN]\n    end\n```\n\n## 令牌验证实现\n\n### requireToken 函数\n\n`src/common/config.ts` 中实现了令牌验证函数：\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN?.trim();\n  if (!token) {\n    throw new 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  }\n  return token;\n}\n```\n\n资料来源：[src/common/config.ts:1-50]()\n\n### 启动时验证\n\n服务启动时会在 `src/index.ts` 中进行强制验证：\n\n```typescript\nasync function main() {\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  // ... 继续初始化\n}\n```\n\n资料来源：[src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n## 令牌在请求中的传递\n\n所有工具实现都遵循统一的令牌传递模式。以统一搜索为例：\n\n```typescript\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  \n  return await getJson(`/api/search/v1?${params.toString()}`);\n}\n```\n\n资料来源：[src/tools/search/unified_search_v1.ts:30-50]()\n\n## 令牌安全处理\n\n### URL 安全日志\n\n为防止令牌在日志中泄露，系统提供了安全 URL 构建函数：\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该函数会在调试模式下将日志输出中的令牌进行脱敏处理，仅保留首尾字符。\n\n资料来源：[src/common/config.ts:60-80]()\n\n## 认证错误处理\n\n### 错误码映射\n\n`src/common/errors.ts` 负责将上游错误码映射为统一的 MCP 错误码：\n\n| 上游错误码 | MCP 错误码 | 说明 | 用户操作 |\n|-----------|-----------|------|----------|\n| - | `INVALID_TOKEN` | 令牌无效或未激活 | 更新 `JUSTONEAPI_TOKEN` |\n| 302 | `RATE_LIMITED` | 请求过于频繁 | 减缓请求频率 |\n| - | `INSUFFICIENT_BALANCE` | 账户余额不足 | 充值账户 |\n| - | `PERMISSION_DENIED` | 无权访问该资源 | 联系客服支持 |\n\n资料来源：[src/common/errors.ts:1-60]()\n\n### 错误响应格式\n\n认证错误以统一格式返回：\n\n```\nERROR[INVALID_TOKEN] (upstream=N/A): Token is invalid or inactive. Please update your JUSTONEAPI_TOKEN environment variable.\n```\n\n## 请求重试与超时\n\n### 重试机制\n\nHTTP 客户端在以下情况会进行重试：\n\n- `AbortError`（请求超时）\n- HTTP 5xx 状态码\n- 网络错误（`ECONNRESET`、`ECONNREFUSED`、`ENOTFOUND`）\n\n重试间隔采用指数退避策略：\n\n```typescript\n// small backoff\nawait new Promise((r) => setTimeout(r, 250 * attempt));\n```\n\n资料来源：[src/common/http.ts:40-80]()\n\n### 超时配置\n\n默认超时时间为 20 秒（20000 毫秒），可通过 `JUSTONEAPI_TIMEOUT_MS` 环境变量自定义。\n\n## MCP Host 配置示例\n\n### Claude Desktop 配置\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### 自定义配置\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## 最佳实践\n\n1. **令牌安全**：不要将令牌硬编码在代码中，使用环境变量传递\n2. **调试模式**：生产环境建议关闭 `JUSTONEAPI_DEBUG`\n3. **超时设置**：根据网络环境调整 `JUSTONEAPI_TIMEOUT_MS`\n4. **错误处理**：捕获 `INVALID_TOKEN` 错误并提示用户更新令牌\n\n---\n\n<a id='system-architecture'></a>\n\n## 系统架构\n\n### 相关页面\n\n相关主题：[项目概述](#project-overview), [开发指南](#development-guide)\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# 系统架构\n\n## 概述\n\njustoneapi-mcp 是一个基于 Model Context Protocol (MCP) 的服务器实现，旨在为 AI 助手（如 Claude Desktop、Cursor 等）提供统一的中国社交媒体和新闻平台搜索能力。该项目采用\"传输而非转换\"（Transport, not transformation）的设计理念，直接返回上游 API 的原始 JSON 数据，确保最大程度的数据保真度。资料来源：[README.md]()\n\n## 架构分层\n\n系统采用模块化分层架构，主要分为以下四层：\n\n```mermaid\ngraph TD\n    A[MCP Host<br/>Claude Desktop/Cursor] --> B[工具注册层<br/>src/index.ts]\n    B --> C[业务逻辑层<br/>src/tools/]\n    C --> D[公共基础设施层<br/>src/common/]\n    D --> E[外部服务<br/>JustOneAPI]\n    \n    C --> C1[unified_search_v1]\n    C --> C2[kuaishou_search_video_v2]\n    \n    D --> D1[config.ts<br/>配置管理]\n    D --> D2[http.ts<br/>HTTP客户端]\n    D --> D3[errors.ts<br/>错误处理]\n```\n\n| 层级 | 文件路径 | 职责 |\n|------|----------|------|\n| 工具注册层 | `src/index.ts` | MCP 工具注册、请求路由、错误格式化 |\n| 业务逻辑层 | `src/tools/**` | 各个工具的具体实现（搜索、视频等） |\n| 公共基础设施层 | `src/common/**` | 配置管理、HTTP 请求、错误处理 |\n| 外部服务层 | JustOneAPI | 第三方数据源 API |\n\n资料来源：[src/index.ts:1-80]()\n\n## 核心组件\n\n### 1. 工具注册层 (src/index.ts)\n\n作为 MCP 服务器的入口点，负责：\n\n- 初始化 MCP SDK 服务器实例\n- 注册所有可用工具及其输入 schema\n- 统一处理工具执行中的异常\n- 格式化错误响应为 MCP 错误格式\n\n```mermaid\nsequenceDiagram\n    participant Host as MCP Host\n    participant Server as MCP Server\n    participant Tool as Tool Handler\n    participant API as JustOneAPI\n    \n    Host->>Server: 工具调用请求\n    Server->>Tool: 传递输入参数\n    Tool->>API: HTTP 请求\n    API-->>Tool: JSON 响应\n    Tool-->>Server: 返回数据\n    Server-->>Host: MCP 响应格式\n    \n    Note over Tool,API: 异常时返回错误格式\n    Tool-->>Server: ERROR[CODE]: message\n    Server-->>Host: isError: true\n```\n\n关键代码结构：\n\n```typescript\n// 工具注册示例\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          type: \"text\",\n          text: `ERROR[${m.code}] (upstream=${m.upstreamCode ?? \"N/A\"}): ${m.message}`,\n        }],\n      };\n    }\n  }\n);\n```\n\n资料来源：[src/index.ts:40-65]()\n\n### 2. 配置管理 (src/common/config.ts)\n\n负责管理和验证环境变量配置：\n\n| 配置项 | 必填 | 默认值 | 说明 |\n|--------|------|--------|------|\n| `JUSTONEAPI_TOKEN` | 是 | - | API 访问令牌 |\n| `JUSTONEAPI_BASE_URL` | 否 | `https://api.justoneapi.com` | API 端点 |\n| `JUSTONEAPI_TIMEOUT_MS` | 否 | `20000` | 请求超时（毫秒） |\n| `JUSTONEAPI_RETRY` | 否 | `1` | 首次尝试后的重试次数 |\n| `JUSTONEAPI_DEBUG` | 否 | `false` | 启用调试日志 |\n\n配置验证在服务器启动时执行：\n\n```typescript\nasync function main() {\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...\"\n    );\n    process.exit(1);\n  }\n  // ...\n}\n```\n\n资料来源：[src/common/config.ts:1-30]() 和 [src/index.ts:75-85]()\n\n### 3. HTTP 客户端 (src/common/http.ts)\n\n封装 HTTP 请求逻辑，提供重试机制：\n\n```mermaid\ngraph TD\n    A[发起请求] --> B{attempt < attempts?}\n    B -->|是| C[发送 HTTP 请求]\n    C --> D{响应状态?}\n    D -->|成功 2xx| E[返回 JSON]\n    D -->|超时/5xx/网络错误| F[等待 backoff]\n    F --> G[attempt++]\n    G --> B\n    D -->|其他错误| H[立即抛出异常]\n    B -->|否| I[抛出最后一次错误]\n```\n\n**可重试的错误类型**：\n\n| 错误类型 | 条件 |\n|----------|------|\n| 超时 | `error.name === \"AbortError\"` |\n| HTTP 5xx | `httpStatus >= 500` |\n| 连接重置 | `error.code === \"ECONNRESET\"` |\n| 连接被拒绝 | `error.code === \"ECONNREFUSED\"` |\n| 主机未找到 | `error.code === \"ENOTFOUND\"` |\n\n**重试策略**：指数退避，每次重试间隔 `250 * attempt` 毫秒。\n\n资料来源：[src/common/http.ts:1-60]()\n\n### 4. 错误处理 (src/common/errors.ts)\n\n统一错误码映射和用户友好消息生成：\n\n```mermaid\ngraph TD\n    A[原始错误] --> B{错误类型判断}\n    B -->|AbortError| C[NETWORK_TIMEOUT]\n    B -->|upstreamCode| D[mapUpstreamCode]\n    B -->|httpStatus| E[UPSTREAM_ERROR]\n    B -->|cause/code| F[NETWORK_ERROR]\n    B -->|其他| G[UPSTREAM_ERROR]\n    \n    D --> H[错误码映射表]\n    H --> H1[INVALID_TOKEN<br/>302]\n    H --> H2[COLLECT_FAILED<br/>500]\n    H --> H3[RATE_LIMITED<br/>429]\n    H --> H4[DAILY_QUOTA_EXCEEDED<br/>403]\n    H --> H5[INSUFFICIENT_BALANCE<br/>402]\n    H --> H6[PERMISSION_DENIED<br/>401]\n    H --> H7[VALIDATION_ERROR<br/>400]\n```\n\n**MCP 错误码对照表**：\n\n| MCP 错误码 | 说明 | 上游响应码 | 用户操作建议 |\n|------------|------|------------|--------------|\n| `INVALID_TOKEN` | Token 无效或未激活 | 302 | 更新 `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | 数据采集失败 | 500 | 稍后重试 |\n| `RATE_LIMITED` | 请求过于频繁 | 429 | 降低请求频率 |\n| `DAILY_QUOTA_EXCEEDED` | 达到日用量限额 | 403 | 等待明天或升级套餐 |\n| `INSUFFICIENT_BALANCE` | 账户余额不足 | 402 | 充值账户 |\n| `PERMISSION_DENIED` | 无权访问该资源 | 401 | 联系客服 |\n| `VALIDATION_ERROR` | 请求参数无效 | 400 | 检查输入值 |\n| `INTERNAL_ERROR` | 服务器内部错误 | 其他 5xx | 稍后重试 |\n| `NETWORK_TIMEOUT` | 请求超时 | - | 检查网络或重试 |\n| `NETWORK_ERROR` | 网络连接失败 | - | 检查网络连接 |\n| `UPSTREAM_ERROR` | 未指定的上游错误 | - | 重试或联系客服 |\n\n**错误输出格式**：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n资料来源：[src/common/errors.ts:1-80]()\n\n## 工具实现\n\n### 统一搜索 (unified_search_v1)\n\n支持跨多个平台进行搜索，返回统一的 JSON 响应：\n\n```mermaid\ngraph LR\n    A[keyword] --> B[参数构建]\n    B --> C{分页?}\n    C -->|首页| D[start, end]\n    C -->|后续页| E[nextCursor]\n    D --> F[URLSearchParams]\n    E --> F\n    F --> G[/api/search/v1]\n    G --> H[getJson]\n```\n\n**输入参数 Schema**：\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `keyword` | string | 是 | 搜索关键词，支持 AND/OR/NOT 语法 |\n| `source` | enum | 否 | 平台筛选：`ALL`（默认）、`NEWS`、`WEIBO`、`WEIXIN`、`ZHIHU`、`DOUYIN`、`XIAOHONGSHU`、`BILIBILI`、`KUAISHOU` |\n| `start` | string | 首页必填 | 开始时间 `yyyy-MM-dd HH:mm:ss`（UTC+8），需在 84 天内 |\n| `end` | string | 首页必填 | 结束时间，需晚于开始时间 |\n| `nextCursor` | string | 分页用 | 上一页返回的游标 |\n\n**搜索语法**：\n\n- 单关键词：`deepseek`\n- AND 搜索（同时包含）：`deepseek chatgpt`\n- OR 搜索（任一包含）：`deepseek~chatgpt`\n- NOT 搜索（排除）：`deepseek -chatgpt`\n\n资料来源：[src/tools/search/unified_search_v1.ts:1-60]()\n\n### 快手视频搜索 (kuaishou_search_video_v2)\n\n针对快手平台的专用视频搜索工具：\n\n| 参数 | 类型 | 必填 | 默认值 | 说明 |\n|------|------|------|--------|------|\n| `keyword` | string | 是 | - | 搜索关键词，如 `'dance'` |\n| `page` | number | 否 | `1` | 页码，从 1 开始 |\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:1-25]()\n\n## 数据流\n\n```mermaid\nsequenceDiagram\n    participant User as 用户\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    User->>MCP: 自然语言搜索请求\n    MCP->>Server: unified_search_v1(keyword, source, start, end)\n    \n    Server->>HTTP: getJson(url)\n    HTTP->>HTTP: Token 编码\n    HTTP->>HTTP: 参数序列化\n    \n    HTTP->>API: GET /api/search/v1?...\n    API-->>HTTP: JSON 响应\n    \n    HTTP-->>Server: 原始 JSON 数据\n    Server-->>MCP: { content: [{type:\"text\", text: JSON}] }\n    MCP-->>User: 搜索结果摘要\n    \n    Note over API: code=0 表示成功<br/>code≠0 表示错误\n```\n\n## 依赖关系\n\n项目依赖项及其版本：\n\n| 依赖类型 | 包名 | 版本要求 | 用途 |\n|----------|------|----------|------|\n| 生产依赖 | `@modelcontextprotocol/sdk` | `^1.25.1` | MCP 协议实现 |\n| 生产依赖 | `zod` | `^4.3.4` | 输入验证和 Schema 定义 |\n| 生产依赖 | `dotenv` | `^17.2.3` | 环境变量管理 |\n| 开发依赖 | `typescript` | `^5.9.3` | TypeScript 编译 |\n| 开发依赖 | `eslint` | `^9.39.2` | 代码检查 |\n| 开发依赖 | `prettier` | `^3.7.4` | 代码格式化 |\n\n**运行环境要求**：Node.js >= 18.0.0\n\n资料来源：[package.json:1-50]()\n\n## 启动验证流程\n\n```mermaid\ngraph TD\n    A[服务器启动] --> B{检查 JUSTONEAPI_TOKEN}\n    B -->|未设置| C[输出错误信息]\n    C --> D[进程退出]\n    B -->|已设置| E[服务器就绪]\n    E --> F[注册所有工具]\n    F --> G[等待 MCP Host 调用]\n    G --> H{收到工具调用}\n    H -->|unified_search_v1| I[执行统一搜索]\n    H -->|kuaishou_search_video_v2| J[执行快手搜索]\n    I --> K[返回结果或错误]\n    J --> K\n```\n\n## 设计原则\n\n1. **传输而非转换**：直接返回上游 API 的原始响应，不进行字段解析或数据重组，确保长期兼容性。\n2. **透明性**：错误信息包含上游错误码，便于调试和问题定位。\n3. **稳定性**：通过 HTTP 重试机制和超时控制提高系统可靠性。\n4. **模块化**：各功能模块职责清晰，便于维护和扩展。\n\n## 扩展性\n\n项目采用插件化架构添加新工具：\n\n1. 在 `src/tools/` 下创建新的工具目录\n2. 定义 Zod 输入 Schema\n3. 实现工具逻辑函数\n4. 在 `src/index.ts` 中注册工具\n\n即将支持的工具：\n\n- Douyin 视频搜索\n- Weibo 帖子搜索\n- Bilibili 视频搜索\n\n---\n\n<a id='development-guide'></a>\n\n## 开发指南\n\n### 相关页面\n\n相关主题：[系统架构](#system-architecture), [平台专用工具](#platform-tools)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n- [eslint.config.js](https://github.com/justoneapi/justoneapi-mcp/blob/main/eslint.config.js)\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- [src/version.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/version.ts)\n</details>\n\n# 开发指南\n\n本开发指南旨在帮助开发者快速上手 justoneapi-mcp 项目的开发工作，涵盖项目结构、环境配置、代码规范、工具开发以及构建发布等核心内容。\n\n## 项目概述\n\njustoneapi-mcp 是一个基于 Model Context Protocol (MCP) 的服务器实现，用于连接 Claude 等 AI 助手与中国主流社交媒体平台的数据搜索接口。该项目支持统一搜索、快手视频搜索等多个工具，为用户提供跨平台社交媒体数据分析能力。\n\n核心设计理念：**Transport, not transformation** — 即优先保证数据传输的稳定性、透明性和原始数据完整性，而非对数据进行转换或处理。\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 项目结构\n\n```\njustoneapi-mcp/\n├── src/\n│   ├── index.ts              # MCP 服务器主入口\n│   ├── version.ts            # 版本管理模块\n│   ├── common/\n│   │   ├── config.ts         # 配置管理\n│   │   ├── errors.ts         # 错误处理\n│   │   └── http.ts           # HTTP 请求封装\n│   └── tools/\n│       ├── search/\n│       │   └── unified_search_v1.ts  # 统一搜索工具\n│       └── kuaishou/\n│           └── search_video_v2.ts     # 快手视频搜索工具\n├── eslint.config.js          # ESLint 配置\n├── tsconfig.json             # TypeScript 配置\n├── package.json              # 项目依赖配置\n└── README.md                 # 项目文档\n```\n\n### 目录职责说明\n\n| 目录/文件 | 职责 | 关键依赖 |\n|-----------|------|---------|\n| `src/index.ts` | MCP 服务器启动、工具注册、错误处理 | @modelcontextprotocol/sdk |\n| `src/common/` | 公共基础设施模块 | zod, dotenv |\n| `src/tools/` | 具体业务工具实现 | 继承 common 模块 |\n\n资料来源：[src/index.ts:1-50](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n## 环境配置\n\n### 运行时要求\n\n项目要求 Node.js 版本不低于 18.0.0。\n\n资料来源：[package.json:22](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n### 必需环境变量\n\n| 变量名 | 必填 | 默认值 | 说明 |\n|--------|------|--------|------|\n| `JUSTONEAPI_TOKEN` | **是** | 无 | JustOneAPI 访问令牌 |\n| `JUSTONEAPI_BASE_URL` | 否 | `https://api.justoneapi.com` | API 端点地址 |\n| `JUSTONEAPI_TIMEOUT_MS` | 否 | `20000` | 请求超时时间（毫秒） |\n| `JUSTONEAPI_RETRY` | 否 | `1` | 首次请求后的重试次数 |\n| `JUSTONEAPI_DEBUG` | 否 | `false` | 是否启用调试日志 |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n### 配置验证机制\n\n项目在启动时（`src/index.ts` 的 `main()` 函数）会验证 `JUSTONEAPI_TOKEN` 是否已设置。若未设置，服务器将输出错误信息并终止运行：\n\n```typescript\nif (!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...\"\n  );\n  process.exit(1);\n}\n```\n\n资料来源：[src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n## 开发工具配置\n\n### TypeScript 配置\n\n项目使用 TypeScript 5.9.3，编译配置位于 `tsconfig.json`。关键配置项包括：\n\n- **target**: ES2022\n- **module**: ESNext (ES 模块系统)\n- **moduleResolution**: bundler\n- **strict mode**: 启用严格类型检查\n\n资料来源：[package.json:29-31](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n### ESLint 配置\n\nESLint 配置集成了 TypeScript ESLint 插件和 Prettier 配置：\n\n```javascript\nrules: {\n  ...tseslint.configs.recommended.rules,\n  \"@typescript-eslint/no-explicit-any\": \"warn\",\n  \"@typescript-eslint/no-unused-vars\": [\"error\", { argsIgnorePattern: \"^_\" }],\n  \"no-console\": [\"warn\", { allow: [\"error\", \"warn\"] }],\n}\n```\n\n**规则说明：**\n\n| 规则 | 级别 | 说明 |\n|------|------|------|\n| `no-explicit-any` | warn | 允许使用 any 类型但会警告 |\n| `no-unused-vars` | error | 未使用的变量报错，下划线开头的参数除外 |\n| `no-console` | warn | 禁止使用 console.log，允许 error 和 warn |\n\n资料来源：[eslint.config.js](https://github.com/justoneapi/justoneapi-mcp/blob/main/eslint.config.js)\n\n### 项目依赖\n\n**生产依赖：**\n\n| 依赖包 | 版本 | 用途 |\n|--------|------|------|\n| @modelcontextprotocol/sdk | ^1.25.1 | MCP 协议实现 |\n| dotenv | ^17.2.3 | 环境变量加载 |\n| zod | ^4.3.4 | 输入验证与 Schema 定义 |\n\n**开发依赖：**\n\n| 依赖包 | 版本 | 用途 |\n|--------|------|------|\n| typescript | ^5.9.3 | TypeScript 编译器 |\n| eslint | ^9.39.2 | 代码检查 |\n| prettier | ^3.7.4 | 代码格式化 |\n| ts-node | ^10.9.2 | TypeScript 执行环境 |\n\n资料来源：[package.json:24-45](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n## 工具开发\n\n### 工具注册流程\n\nMCP 服务器通过 `server.registerTool()` 方法注册工具。注册时需提供工具名称、描述和输入 Schema：\n\n```typescript\nserver.registerTool(\n  \"tool_name_v1\",\n  {\n    description: \"工具描述字符串\",\n    inputSchema: ToolInputSchema.shape,\n  },\n  async (input) => {\n    // 工具实现逻辑\n    return {\n      content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n    };\n  }\n);\n```\n\n资料来源：[src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n### 工具命名规范\n\n项目采用统一的工具命名规范：`{platform}_{action}_{version}`\n\n| 示例 | 含义 |\n|------|------|\n| `unified_search_v1` | 统一搜索工具，第一版本 |\n| `kuaishou_search_video_v2` | 快手平台视频搜索，第二版本 |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n### 输入验证\n\n项目使用 Zod v4 进行输入验证。每个工具需要定义 `InputSchema`：\n\n```typescript\nimport { z } from \"zod\";\n\nexport const UnifiedSearchV1Input = z.object({\n  keyword: z.string().min(1).describe(\"搜索关键词\"),\n  source: PlatformType.optional().describe(\"平台来源\"),\n  start: z.string().optional().describe(\"开始时间\"),\n  end: z.string().optional().describe(\"结束时间\"),\n  nextCursor: z.string().optional().describe(\"分页游标\"),\n});\n```\n\n**Zod Schema 特性说明：**\n\n| 方法 | 用途 |\n|------|------|\n| `z.string().min(1)` | 非空字符串验证 |\n| `.optional()` | 可选字段 |\n| `.default(value)` | 默认值 |\n| `.describe(\"...\")` | 字段描述（用于 MCP 文档生成） |\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```typescript\nimport { z } from \"zod\";\nimport { requireToken } from \"../../common/config.js\";\nimport { getJson } from \"../../common/http.js\";\n\n// 1. 定义输入 Schema\nexport const ToolInput = z.object({\n  param1: z.string().min(1).describe(\"参数描述\"),\n  param2: z.number().int().min(1).default(1).describe(\"可选参数\"),\n});\n\n// 2. 实现工具函数\nexport async function toolFunction(input: z.infer<typeof ToolInput>) {\n  const token = encodeURIComponent(requireToken());\n  const param = encodeURIComponent(input.param1);\n  const page = input.param2;\n\n  return await getJson(\n    `/api/path?token=${token}&param=${param}&page=${page}`\n  );\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\n## HTTP 请求封装\n\n### 请求重试机制\n\n`getJson()` 函数封装了带重试逻辑的 HTTP 请求：\n\n```mermaid\ngraph TD\n    A[发起请求] --> B{成功?}\n    B -->|是| C[返回响应]\n    B -->|否| D{可重试?}\n    D -->|超时/5xx/网络错误| E[等待 250ms × attempt]\n    E --> F[重试]\n    F --> A\n    D -->|不可重试| G[抛出异常]\n    G --> H[错误处理]\n    C --> H\n```\n\n**可重试条件：**\n\n| 条件 | 说明 |\n|------|------|\n| `AbortError` | 请求超时 |\n| HTTP 5xx | 服务器内部错误 |\n| `ECONNRESET` | 连接被重置 |\n| `ECONNREFUSED` | 连接被拒绝 |\n| `ENOTFOUND` | DNS 解析失败 |\n\n资料来源：[src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n## 错误处理机制\n\n### 错误代码映射\n\n项目定义了一套标准化的 MCP 错误代码：\n\n| 错误代码 | 上游代码 | 说明 | 处理建议 |\n|----------|----------|------|----------|\n| `INVALID_TOKEN` | - | Token 无效或未激活 | 更新 JUSTONEAPI_TOKEN |\n| `COLLECT_FAILED` | - | 数据采集失败 | 稍后重试 |\n| `RATE_LIMITED` | 302 | 请求过于频繁 | 降低请求频率 |\n| `DAILY_QUOTA_EXCEEDED` | - | 达到日配额限制 | 等待明天或升级套餐 |\n| `INSUFFICIENT_BALANCE` | - | 账户余额不足 | 充值账户 |\n| `PERMISSION_DENIED` | - | 无权访问该资源 | 联系支持 |\n| `VALIDATION_ERROR` | - | 请求参数无效 | 检查输入值 |\n| `INTERNAL_ERROR` | - | 服务器内部错误 | 稍后重试 |\n| `NETWORK_TIMEOUT` | - | 请求超时 | 检查网络或重试 |\n| `NETWORK_ERROR` | - | 网络连接失败 | 检查网络连接 |\n| `UPSTREAM_ERROR` | - | 未指定的上游错误 | 重试或联系支持 |\n\n### 错误格式\n\n错误以以下格式返回：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n### 错误处理流程\n\n```mermaid\ngraph TD\n    A[捕获异常] --> B{AbortError?}\n    B -->|是| C[返回 NETWORK_TIMEOUT]\n    B -->|否| D{upstreamCode 存在?}\n    D -->|是| E[映射上游错误码]\n    E --> F[返回业务错误]\n    D -->|否| G{httpStatus 存在?}\n    G -->|是| H[返回 UPSTREAM_ERROR]\n    G -->|否| I{网络错误?}\n    I -->|是| J[返回 NETWORK_ERROR]\n    I -->|否| K[返回 UPSTREAM_ERROR]\n```\n\n资料来源：[src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n## 版本管理\n\n项目使用动态版本读取机制，从 `package.json` 中提取版本号：\n\n```typescript\nconst packageJsonPath = join(__dirname, \"../package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\nversion = packageJson.version || \"0.0.0\";\n```\n\n此设计确保构建产物中的版本号与 `package.json` 保持同步。\n\n资料来源：[src/version.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/version.ts)\n\n## 构建和发布\n\n### 安装依赖\n\n```bash\nnpm install\n```\n\n### 代码检查\n\n```bash\nnpm run lint      # ESLint 检查\nnpm run format    # Prettier 格式化\n```\n\n### 构建\n\n```bash\nnpm run build     # TypeScript 编译到 dist/\n```\n\n### 发布配置\n\n`package.json` 中的发布文件配置：\n\n```json\n{\n  \"files\": [\"dist\", \"README.md\", \"LICENSE\"]\n}\n```\n\n仅 `dist` 目录（编译产物）、`README.md` 和 `LICENSE` 会被发布到 npm。\n\n资料来源：[package.json:19-22](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n## Claude Desktop 集成\n\n### 配置示例\n\n在 Claude Desktop 配置文件中添加以下内容：\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### 配置文件位置\n\n| 操作系统 | 路径 |\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## 开发工作流程\n\n```mermaid\ngraph LR\n    A[创建工具文件] --> B[定义 Zod Schema]\n    B --> C[实现工具函数]\n    C --> D[注册工具到服务器]\n    D --> E[配置环境变量]\n    E --> F[本地测试]\n    F --> G[代码检查]\n    G --> H{通过?}\n    H -->|否| I[修复问题]\n    I --> G\n    H -->|是| J[构建发布]\n    J --> K[end]\n```\n\n## 常见问题\n\n### Token 配置问题\n\n**问题**: 服务器启动时报错 `JUSTONEAPI_TOKEN is required but not set`\n\n**解决**: 确保在 MCP host 配置中正确设置了 `JUSTONEAPI_TOKEN` 环境变量\n\n### 请求超时\n\n**问题**: 请求返回 `NETWORK_TIMEOUT`\n\n**解决**: 增加 `JUSTONEAPI_TIMEOUT_MS` 配置值（默认 20000ms）\n\n### 调试模式\n\n启用调试模式可查看详细的请求日志：\n\n```json\n{\n  \"env\": {\n    \"JUSTONEAPI_DEBUG\": \"true\"\n  }\n}\n```\n\n资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\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 项目说明书",
        "目录",
        "项目概述",
        "项目简介",
        "技术架构",
        "核心模块设计",
        "可用工具",
        "输出契约",
        "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": "07914348d554afd9e71baebe28b41438bde66491",
    "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- **项目概述**：importance `high`\n  - source_paths: README.md, README.zh-CN.md\n- **安装部署**：importance `high`\n  - source_paths: package.json, tsconfig.json\n- **配置管理**：importance `high`\n  - source_paths: src/common/config.ts, src/version.ts\n- **工具概览**：importance `high`\n  - source_paths: TOOLS.md, src/index.ts\n- **统一搜索工具**：importance `high`\n  - source_paths: src/tools/search/unified_search_v1.ts\n- **平台专用工具**：importance `medium`\n  - source_paths: src/tools/kuaishou/search_video_v2.ts\n- **错误处理**：importance `high`\n  - source_paths: src/common/errors.ts\n- **认证授权**：importance `high`\n  - source_paths: src/common/http.ts, src/common/config.ts\n\n## Repo Inspection Evidence / 源码检查证据\n\n- repo_clone_verified: true\n- repo_inspection_verified: true\n- repo_commit: `07914348d554afd9e71baebe28b41438bde66491`\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 01:49:03 UTC\n\n## 目录\n\n- [项目概述](#project-overview)\n- [安装部署](#installation)\n- [配置管理](#configuration)\n- [工具概览](#tools-overview)\n- [统一搜索工具](#unified-search)\n- [平台专用工具](#platform-tools)\n- [错误处理](#error-handling)\n- [认证授权](#authentication)\n- [系统架构](#system-architecture)\n- [开发指南](#development-guide)\n\n<a id='project-overview'></a>\n\n## 项目概述\n\n### 相关页面\n\n相关主题：[系统架构](#system-architecture), [安装部署](#installation)\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/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/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- [src/version.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/version.ts)\n</details>\n\n# 项目概述\n\n## 项目简介\n\njustoneapi-mcp 是一个基于 Model Context Protocol (MCP) 协议构建的服务器应用程序，专门用于在中国社交媒体平台和新闻网站上进行统一搜索和数据采集。该项目作为 MCP 主机（如 Claude Desktop、Cursor 等）与 JustOneAPI 之间的桥梁，使 AI 助手能够直接访问和分析中国主流社交媒体的内容。资料来源：[README.md:1]()\n\n该项目的核心设计理念是\"传输而非转换\"（Transport, not transformation），强调数据的稳定性和原始保真度，返回未经修改的上游 API 响应。资料来源：[README.md:180]()\n\n## 技术架构\n\n### 系统架构图\n\n```mermaid\ngraph TD\n    subgraph MCP主机 [\"MCP 主机\"]\n        A[Claude Desktop / Cursor]\n    end\n    \n    subgraph justoneapi-mcp [\"justoneapi-mcp 服务器\"]\n        B[入口模块 src/index.ts]\n        C[工具注册模块]\n        D[HTTP 请求模块]\n        E[错误处理模块]\n        F[配置管理模块]\n        G[统一搜索工具]\n        H[快手搜索工具]\n    end\n    \n    subgraph JustOneAPI [\"JustOneAPI 服务\"]\n        I[API 网关]\n        J[上游数据源]\n    end\n    \n    A -->|MCP 协议| B\n    B --> C\n    C --> G\n    C --> H\n    G --> D\n    H --> D\n    D --> F\n    D -->|HTTP 请求| I\n    I --> J\n    \n    J -->|微博| K[WEIBO]\n    J -->|微信| L[WEIXIN]\n    J -->|知乎| M[ZHIHU]\n    J -->|抖音| N[DOUYIN]\n    J -->|小红书| O[XIAOHONGSHU]\n    J -->|哔哩哔哩| P[BILIBILI]\n    J -->|快手| Q[KUAISHOU]\n    J -->|新闻| R[NEWS]\n```\n\n### 技术栈\n\n| 技术组件 | 版本要求 | 用途说明 |\n|---------|---------|---------|\n| Node.js | >=18.0.0 | 运行时环境 |\n| TypeScript | ^5.9.3 | 开发语言 |\n| @modelcontextprotocol/sdk | ^1.25.1 | MCP 协议实现 |\n| Zod | ^4.3.4 | 参数验证与 schema 定义 |\n| dotenv | ^17.2.3 | 环境变量管理 |\n\n资料来源：[package.json:7-18]()\n\n## 核心模块设计\n\n### 模块职责说明\n\n```mermaid\ngraph LR\n    subgraph 核心模块\n        A[config.ts]\n        B[http.ts]\n        C[errors.ts]\n    end\n    \n    subgraph 工具模块\n        D[unified_search_v1.ts]\n        E[search_video_v2.ts]\n    end\n    \n    subgraph 入口模块\n        F[index.ts]\n    end\n    \n    F --> A\n    F --> D\n    F --> E\n    D --> B\n    E --> B\n    B --> C\n```\n\n### 配置管理模块\n\n`src/common/config.ts` 负责管理和验证环境变量配置。资料来源：[src/common/config.ts:1]()\n\n| 配置项 | 默认值 | 必填 | 说明 |\n|-------|-------|------|------|\n| `JUSTONEAPI_TOKEN` | - | 是 | JustOneAPI 访问令牌 |\n| `JUSTONEAPI_BASE_URL` | `https://api.justoneapi.com` | 否 | API 端点地址 |\n| `JUSTONEAPI_TIMEOUT_MS` | `20000` | 否 | 请求超时时间（毫秒） |\n| `JUSTONEAPI_RETRY` | `1` | 否 | 失败后重试次数 |\n| `JUSTONEAPI_DEBUG` | `false` | 否 | 启用调试日志 |\n\n资料来源：[README.md:195-202]()\n\n配置模块还提供令牌掩码功能，用于日志输出时保护敏感信息：\n\n```typescript\nexport function toSafeUrlForLog(fullUrl: string): string {\n  // 移除或掩码 token 查询参数\n}\n```\n\n资料来源：[src/common/config.ts:27-39]()\n\n### HTTP 请求模块\n\n`src/common/http.ts` 实现统一的 HTTP 请求处理机制，具备以下特性：资料来源：[src/common/http.ts:1]()\n\n**重试机制**：\n\n- 仅对以下情况触发重试：\n  - 请求超时（AbortError）\n  - HTTP 5xx 状态码\n  - 网络连接重置（ECONNRESET）\n  - 连接被拒绝（ECONNREFUSED）\n  - DNS 解析失败（ENOTFOUND）\n\n**退避策略**：每次重试间隔为 `250 * attempt` 毫秒。资料来源：[src/common/http.ts:28-29]()\n\n```mermaid\ngraph TD\n    A[发起请求] --> B{请求成功?}\n    B -->|是| C[返回 JSON 响应]\n    B -->|否| D{可重试错误?}\n    D -->|超时/5xx/网络错误| E[等待退避时间]\n    D -->|其他错误| F[抛出异常]\n    E --> G[重试]\n    G --> A\n    D -->|达到最大重试次数| F\n```\n\n### 错误处理模块\n\n`src/common/errors.ts` 实现标准化的 MCP 错误码映射系统。资料来源：[src/common/errors.ts:1]()\n\n**错误码映射表**：\n\n| 上游错误码 | MCP 错误码 | 描述 | 用户操作 |\n|-----------|-----------|------|---------|\n| 302 | `RATE_LIMITED` | 请求频率超限 | 降低请求频率后重试 |\n| - | `INVALID_TOKEN` | 令牌无效或未激活 | 更新 `JUSTONEAPI_TOKEN` |\n| - | `COLLECT_FAILED` | 数据采集失败 | 短暂延迟后重试 |\n| - | `DAILY_QUOTA_EXCEEDED` | 日用量超限 | 等待明天或升级套餐 |\n| - | `INSUFFICIENT_BALANCE` | 账户余额不足 | 充值账户 |\n| - | `PERMISSION_DENIED` | 无权访问资源 | 联系客服 |\n| - | `VALIDATION_ERROR` | 请求参数无效 | 检查输入值 |\n| - | `INTERNAL_ERROR` | 服务器内部错误 | 稍后重试 |\n| - | `NETWORK_TIMEOUT` | 请求超时 | 检查网络或重试 |\n| - | `NETWORK_ERROR` | 网络连接失败 | 检查网络连接 |\n| - | `UPSTREAM_ERROR` | 上游未指明错误 | 重试或联系客服 |\n\n资料来源：[README.md:152-169]()\n\n**错误输出格式**：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n示例：`ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.` 资料来源：[README.md:170-174]()\n\n## 可用工具\n\n### 工具清单\n\n| 工具名称 | 版本 | 功能描述 |\n|---------|------|---------|\n| `unified_search_v1` | v1 | 跨平台统一搜索 |\n| `kuaishou_search_video_v2` | v2 | 快手视频搜索 |\n\n资料来源：[TOOLS.md:15-19]()\n\n### 统一搜索工具 (unified_search_v1)\n\n统一搜索工具支持在多个中国社交媒体和新闻平台上一站式搜索。资料来源：[src/tools/search/unified_search_v1.ts:1]()\n\n**支持的平台**：\n\n- `ALL` - 全部平台（默认）\n- `NEWS` - 新闻\n- `WEIBO` - 微博\n- `WEIXIN` - 微信\n- `ZHIHU` - 知乎\n- `DOUYIN` - 抖音\n- `XIAOHONGSHU` - 小红书\n- `BILIBILI` - 哔哩哔哩\n- `KUAISHOU` - 快手\n\n资料来源：[README.md:30-38]()\n\n**参数定义**：\n\n| 参数 | 类型 | 必填 | 说明 |\n|-----|------|------|------|\n| `keyword` | string | 是 | 搜索关键词，支持高级语法 |\n| `source` | string | 否 | 平台过滤器，默认 `ALL` |\n| `start` | string | 首次请求必填 | 开始时间 `yyyy-MM-dd HH:mm:ss` (UTC+8)，范围不超过 84 天 |\n| `end` | string | 首次请求必填 | 结束时间 `yyyy-MM-dd HH:mm:ss` (UTC+8)，必须晚于开始时间 |\n| `nextCursor` | string | 分页时使用 | 来自上一页响应的游标 |\n\n资料来源：[src/tools/search/unified_search_v1.ts:14-35]()\n\n**搜索语法**：\n\n| 语法类型 | 格式 | 示例 | 说明 |\n|---------|------|------|------|\n| 单关键词 | `word` | `deepseek` | 搜索单个关键词 |\n| AND 搜索 | `word1 word2` | `deepseek chatgpt` | 两个关键词必须同时出现 |\n| OR 搜索 | `word1~word2` | `deepseek~chatgpt` | 任一关键词出现即可 |\n| NOT 搜索 | `word -excluded` | `deepseek -chatgpt` | 排除指定关键词 |\n\n资料来源：[README.md:122-127]()\n\n**API 调用示例**：\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### 快手视频搜索工具 (kuaishou_search_video_v2)\n\n快手视频搜索是平台特定的工具，专注于快手平台的视频内容搜索。资料来源：[src/tools/kuaishou/search_video_v2.ts:1]()\n\n**参数定义**：\n\n| 参数 | 类型 | 必填 | 默认值 | 说明 |\n|-----|------|------|--------|------|\n| `keyword` | string | 是 | - | 搜索关键词，如 `dance` |\n| `page` | number | 否 | 1 | 页码，从 1 开始 |\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:5-8]()\n\n## 输出契约\n\n### 成功响应格式\n\n所有工具返回原始 JSON 响应，设计原则是\"最大数据保真度、无字段解析、无数据重组\"。资料来源：[README.md:149-152]()\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-12-31T14:55:21Z\",\n  \"data\": {\n    // 平台特定数据结构\n  }\n}\n```\n\n| 字段 | 类型 | 说明 |\n|-----|------|------|\n| `code` | integer | 0 表示成功，非 0 表示错误 |\n| `message` | string/null | 错误信息，成功时为 null |\n| `recordTime` | string | 响应记录时间（ISO 8601 格式） |\n| `data` | object | 平台特定数据内容 |\n\n### 分页机制\n\n当搜索结果存在更多页面时，响应会包含 `nextCursor` 字段。用户可以通过以下方式继续获取下一页：\n\n- \"显示更多结果\"\n- \"继续获取上一页的更多结果\"\n- \"继续下一页\"\n\n系统会自动从上一条响应中提取 `nextCursor` 并用于后续请求。资料来源：[README.md:128-141]()\n\n```mermaid\ngraph LR\n    A[首次请求] -->|无 nextCursor| B[返回第一页 + nextCursor]\n    B --> C[请求第二页]\n    C -->|携带 nextCursor| D[返回第二页 + nextCursor]\n    D --> E[继续...直到无 nextCursor]\n```\n\n## 安装与配置\n\n### 安装方式\n\n**推荐方式：npx（无需安装）**\n\n直接使用 npx 运行，无需本地安装：\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:70-80]()\n\n### Claude Desktop 配置\n\n配置文件位置：\n\n| 操作系统 | 配置文件路径 |\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### 自定义配置示例\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## 版本管理\n\n项目使用动态版本管理机制，从 `package.json` 读取版本号：资料来源：[src/version.ts:1]()\n\n```typescript\nconst packageJsonPath = join(__dirname, \"../package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\nversion = packageJson.version || \"0.0.0\";\n```\n\n## 项目结构\n\n```\njustoneapi-mcp/\n├── src/\n│   ├── index.ts                 # 入口模块\n│   ├── version.ts               # 版本管理\n│   ├── common/\n│   │   ├── config.ts            # 配置管理\n│   │   ├── http.ts              # HTTP 请求处理\n│   │   └── errors.ts            # 错误处理\n│   └── tools/\n│       ├── search/\n│       │   └── unified_search_v1.ts    # 统一搜索工具\n│       └── kuaishou/\n│           └── search_video_v2.ts      # 快手搜索工具\n├── package.json\n├── eslint.config.js\n├── README.md\n├── TOOLS.md\n└── LICENSE\n```\n\n## 设计哲学\n\n**传输，而非转换**\n\n该 MCP 服务器的设计优先级为：资料来源：[README.md:179-182]()\n\n1. **稳定性**：确保服务可靠运行\n2. **透明度**：返回原始数据，不隐藏上游信息\n3. **数据保真度**：返回未修改的上游 API 响应\n\n这一设计理念确保了长期兼容性和最大化的数据完整性，用户可以直接访问底层数据并进行自定义分析。\n\n## 许可证\n\n本项目采用 MIT 许可证开源授权。资料来源：[README.md:206]()\n\n---\n\n<a id='installation'></a>\n\n## 安装部署\n\n### 相关页面\n\n相关主题：[配置管理](#configuration), [认证授权](#authentication)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\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- [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/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n- [tsconfig.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/tsconfig.json)\n</details>\n\n# 安装部署\n\n本文档详细说明 justoneapi-mcp 的安装、配置和部署流程。justoneapi-mcp 是一个基于 Model Context Protocol (MCP) 的服务器，用于连接 JustOneAPI 社交媒体数据搜索服务。\n\n## 系统要求\n\n### 运行环境\n\n| 组件 | 最低版本要求 |\n|------|-------------|\n| Node.js | >= 18.0.0 |\n\n资料来源：[package.json:28]()\n\n### 依赖包\n\n| 依赖包 | 版本 | 用途 |\n|--------|------|------|\n| @modelcontextprotocol/sdk | ^1.25.1 | MCP 协议实现 |\n| zod | ^4.3.4 | 参数验证与 Schema 定义 |\n| dotenv | ^17.2.3 | 环境变量管理 |\n\n资料来源：[package.json:33-36]()\n\n## 安装方式\n\n### 方式一：npx 方式（推荐）\n\n使用 npx 可以直接运行，无需预先安装：\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这种方式的优势在于：\n- 无需手动安装\n- 始终使用最新版本\n- 配置简单快捷\n\n资料来源：[README.md:71-79]()\n\n### 方式二：本地安装\n\n如果需要特定版本或离线部署：\n\n```bash\nnpm install -g justoneapi-mcp\n```\n\n或项目依赖方式：\n\n```bash\nnpm install justoneapi-mcp\n```\n\n## MCP 主机配置\n\n### Claude Desktop 配置\n\n#### macOS\n\n配置文件路径：`~/Library/Application Support/Claude/claude_desktop_config.json`\n\n#### Windows\n\n配置文件路径：`%APPDATA%\\Claude\\claude_desktop_config.json`\n\n#### Linux\n\n配置文件路径：`~/.config/Claude/claude_desktop_config.json`\n\n### 完整配置示例\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        \"JUSTJUSTONEAPI_TIMEOUT_MS\": \"30000\",\n        \"JUSTONEAPI_DEBUG\": \"true\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md:64-89]()\n\n## 环境变量配置\n\n### 必需配置\n\n| 变量名 | 说明 | 默认值 |\n|--------|------|--------|\n| JUSTONEAPI_TOKEN | JustOneAPI 访问令牌 | **必需** |\n\n### 可选配置\n\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| JUSTONEAPI_BASE_URL | `https://api.justoneapi.com` | API 端点地址 |\n| JUSTONEAPI_TIMEOUT_MS | `20000` | 请求超时时间（毫秒） |\n| JUSTONEAPI_RETRY | `1` | 首次请求失败后的重试次数 |\n| JUSTONEAPI_DEBUG | `false` | 是否启用调试日志 |\n\n资料来源：[README.md:91-100]()\n\n### 令牌获取\n\n访问 [JustOneAPI Dashboard](https://dashboard.justoneapi.com/en/login) 注册并获取 API 令牌。\n\n## 配置模块详解\n\n### 配置加载流程\n\n```mermaid\ngraph TD\n    A[启动 MCP Server] --> B[检查 JUSTONEAPI_TOKEN]\n    B --> C{Token 是否存在且非空?}\n    C -->|是| D[加载可选配置]\n    C -->|否| E[输出错误信息并退出]\n    D --> F[配置加载完成]\n    F --> G[注册工具并启动服务]\n    E --> H[进程终止]\n```\n\n配置模块负责在服务启动时验证必要参数，核心逻辑位于 `src/common/config.ts`。\n\n资料来源：[src/common/config.ts]()\n\n### 令牌验证\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN;\n  if (!token?.trim()) {\n    throw new Error(\"JUSTONEAPI_TOKEN is required\");\n  }\n  return token;\n}\n```\n\n该函数在所有 API 请求前被调用，确保令牌有效。\n\n资料来源：[src/common/config.ts]()\n\n### 安全日志处理\n\n配置模块提供令牌脱敏功能，避免在日志中泄露敏感信息：\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]()\n\n## HTTP 请求机制\n\n### 请求流程\n\n```mermaid\ngraph TD\n    A[发起请求] --> B{重试次数 < maxRetries?}\n    B -->|是| C[创建 AbortController]\n    C --> D[设置超时定时器]\n    D --> E[发送 GET 请求]\n    E --> F{响应状态码 < 500?}\n    F -->|是| G[解析 JSON 响应]\n    G --> H{业务代码 == 0?}\n    H -->|是| I[返回响应数据]\n    H -->|否| J[抛出业务错误]\n    F -->|否| K{可重试错误?}\n    K -->|是| L[等待后重试]\n    K -->|否| M[抛出错误]\n    J --> N[返回错误响应]\n    B -->|否| M\n    L --> B\n```\n\n### 重试策略\n\n请求失败时，HTTP 模块会自动重试以下情况：\n\n| 错误类型 | 是否重试 |\n|----------|----------|\n| AbortError（超时） | ✅ 重试 |\n| HTTP 5xx 错误 | ✅ 重试 |\n| ECONNRESET | ✅ 重试 |\n| ECONNREFUSED | ✅ 重试 |\n| ENOTFOUND | ✅ 重试 |\n| HTTP 4xx 错误 | ❌ 不重试 |\n| 业务代码 != 0 | ❌ 不重试 |\n\n重试间隔采用简单退避策略：`250ms * attempt`。\n\n资料来源：[src/common/http.ts:24-36]()\n\n### 超时配置\n\n默认超时时间为 20 秒，可通过 `JUSTONEAPI_TIMEOUT_MS` 环境变量自定义：\n\n```typescript\nconst timer = setTimeout(() => controller.abort(), config.timeoutMs);\n```\n\n资料来源：[src/common/http.ts:41]()\n\n## 服务启动流程\n\n### 启动时验证\n\n```mermaid\ngraph TD\n    A[main 函数入口] --> B[检查环境变量]\n    B --> C{JUSTONEAPI_TOKEN 是否设置?}\n    C -->|否| D[输出错误信息]\n    D --> E[进程终止]\n    C -->|是| F[创建 MCP Server]\n    F --> G[注册 unified_search_v1 工具]\n    G --> H[注册 kuaishou_search_video_v2 工具]\n    H --> I[连接 stdio 传输]\n    I --> J[服务就绪]\n```\n\n### 主入口代码\n\n```typescript\nasync function main() {\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...\"\n    );\n    process.exit(1);\n  }\n  // ... 启动服务\n}\n```\n\n资料来源：[src/index.ts:58-65]()\n\n## TypeScript 编译配置\n\n### 项目配置\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"lib\": [\"ES2022\"],\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"resolveJsonModule\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"sourceMap\": true\n  },\n  \"include\": [\"src/**/*\"],\n exclude\": [\"node_modules\", \"dist\"]\n}\n```\n\n编译产物输出至 `dist` 目录，包含以下文件：\n\n| 目录 | 内容 |\n|------|------|\n| dist/common/ | 通用模块（config、http、errors） |\n| dist/tools/ | 工具模块 |\n| dist/index.js | 主入口 |\n| dist/*.d.ts | 类型声明文件 |\n\n资料来源：[tsconfig.json]()\n\n## 开发环境搭建\n\n### 克隆项目\n\n```bash\ngit clone https://github.com/justoneapi/justoneapi-mcp.git\ncd justoneapi-mcp\n```\n\n### 安装依赖\n\n```bash\nnpm install\n```\n\n### TypeScript 类型检查\n\n```bash\nnpm run typecheck\n```\n\n### 代码格式化\n\n```bash\nnpm run format\n```\n\n### ESLint 检查\n\n```bash\nnpm run lint\n```\n\n### 构建项目\n\n```bash\nnpm run build\n```\n\n### 启动服务（开发模式）\n\n```bash\nnpm run start\n```\n\n## 项目文件结构\n\n```\njustoneapi-mcp/\n├── src/\n│   ├── index.ts                    # 主入口文件\n│   ├── version.ts                  # 版本信息\n│   ├── common/\n│   │   ├── config.ts               # 配置管理\n│   │   ├── http.ts                 # HTTP 请求封装\n│   │   └── errors.ts               # 错误处理\n│   └── tools/\n│       └── search/\n│           └── unified_search_v1.ts # 统一搜索工具\n├── dist/                           # 编译输出\n├── package.json                    # 项目配置\n├── tsconfig.json                   # TypeScript 配置\n└── eslint.config.js                # ESLint 配置\n```\n\n## 故障排查\n\n### 常见问题\n\n#### 1. Token 未设置错误\n\n```\n[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\n```\n\n**解决方案**：确保在 MCP 主机配置中正确设置 `JUSTONEAPI_TOKEN` 环境变量。\n\n#### 2. 请求超时\n\n```\nERROR[NETWORK_TIMEOUT]: Request timed out\n```\n\n**解决方案**：增加 `JUSTONEAPI_TIMEOUT_MS` 配置值（默认 20000ms）。\n\n#### 3. 速率限制\n\n```\nERROR[RATE_LIMITED]: Rate limit exceeded\n```\n\n**解决方案**：降低请求频率，等待一段时间后重试。\n\n### 调试模式\n\n启用调试日志以排查问题：\n\n```json\n{\n  \"env\": {\n    \"JUSTONEAPI_DEBUG\": \"true\"\n  }\n}\n```\n\n调试模式下会输出所有 HTTP 请求详情（令牌已脱敏）。\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- JustOneAPI 官网：https://justoneapi.com\n\n---\n\n<a id='configuration'></a>\n\n## 配置管理\n\n### 相关页面\n\n相关主题：[安装部署](#installation), [认证授权](#authentication)\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/version.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/version.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- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n</details>\n\n# 配置管理\n\n## 概述\n\njustoneapi-mcp 采用简洁而健壮的环境变量配置方案。配置管理系统负责验证必需参数、管理可选行为、确保敏感信息安全性，并在服务启动时进行完整性检查。资料来源：[README.md:108-120]()\n\n## 核心配置架构\n\n配置系统围绕环境变量构建，遵循\"约定优于配置\"的设计原则。所有配置项通过 `process.env` 访问，核心 token 验证在服务初始化阶段强制执行。\n\n```mermaid\ngraph TD\n    A[服务启动] --> B[检查 JUSTONEAPI_TOKEN]\n    B --> C{Token 是否存在且非空?}\n    C -->|是| D[配置验证通过]\n    C -->|否| E[输出错误信息并退出]\n    D --> F[初始化 MCP Server]\n    F --> G[注册工具集]\n    E --> H[进程终止]\n    \n    I[运行时配置] --> J[HTTP 请求]\n    J --> K[Token 注入]\n    K --> L[URL 安全日志]\n    \n    D --> I\n```\n\n资料来源：[src/index.ts:55-68]()\n\n## 环境变量配置项\n\n### 必需配置\n\n| 配置变量 | 类型 | 说明 |\n|---------|------|------|\n| `JUSTONEAPI_TOKEN` | string | API 访问令牌，用于认证上游 JustOneAPI 服务 |\n\n服务启动时，若 `JUSTONEAPI_TOKEN` 未设置或为空字符串，将输出错误信息并终止进程。资料来源：[src/index.ts:55-68]()\n\n```typescript\n// 启动验证逻辑\nif (!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```\n\n### 可选配置\n\n| 配置变量 | 默认值 | 类型 | 说明 |\n|---------|--------|------|------|\n| `JUSTONEAPI_BASE_URL` | `https://api.justoneapi.com` | string | API 端点地址 |\n| `JUSTONEAPI_TIMEOUT_MS` | `20000` | number | 请求超时时间（毫秒） |\n| `JUSTONEAPI_RETRY` | `1` | number | 首次请求失败后的重试次数 |\n| `JUSTONEAPI_DEBUG` | `false` | boolean | 启用调试日志输出到 stderr |\n\n资料来源：[README.md:114-119]()\n\n## Token 管理机制\n\n### Token 验证函数\n\n`requireToken()` 函数封装了 token 的获取与验证逻辑，确保在所有需要认证的 API 调用前进行校验。资料来源：[src/common/config.ts:1-20]()\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN;\n  if (!token?.trim()) {\n    throw new Error(\"JUSTONEAPI_TOKEN environment variable is not set or is empty\");\n  }\n  return token;\n}\n```\n\n### Token 掩码处理\n\n为防止敏感信息在日志中泄露，系统提供了 Token 掩码功能。对于长度为 12 位以内的 Token，保留首尾各 2 位字符，中间用 `*` 替换；超过 12 位的 Token 保留前 6 位和后 4 位。资料来源：[src/common/config.ts:26-35]()\n\n```typescript\nfunction maskToken(token: string): string {\n  if (token.length <= 12) {\n    return token.slice(0, 2) + \"*\".repeat(token.length - 4) + token.slice(-2);\n  }\n  return token.slice(0, 6) + \"*\".repeat(8) + token.slice(-4);\n}\n```\n\n## URL 安全日志\n\n在 HTTP 请求处理过程中，敏感 Token 参数会被自动掩码处理后再输出日志，确保生产环境中不会泄露认证凭据。资料来源：[src/common/config.ts:40-55]()\n\n```mermaid\nsequenceDiagram\n    participant Client as 调用方\n    participant HTTP as HTTP 模块\n    participant Config as 配置模块\n    participant Log as 日志输出\n    \n    Client->>HTTP: 发起 API 请求\n    HTTP->>Config: 调用 toSafeUrlForLog()\n    Config->>Config: 检测 URL 中的 token 参数\n    Config->>Config: 执行 maskToken() 掩码\n    Config-->>Log: 返回安全 URL\n    HTTP-->>Client: 返回响应\n```\n\n## HTTP 请求与配置联动\n\n### 超时控制\n\n超时时间通过 `JUSTONEAPI_TIMEOUT_MS` 配置控制，内部使用 `AbortController` 实现。超时错误会被映射为 `NETWORK_TIMEOUT` 错误码。资料来源：[src/common/http.ts:35-45]()\n\n### 重试机制\n\n`JUSTONEAPI_RETRY` 配置指定初始请求失败后的重试次数。重试策略包含 250 毫秒的指数退避延迟。资料来源：[src/common/http.ts:50-60]()\n\n```mermaid\ngraph TD\n    A[发送请求] --> B{成功?}\n    B -->|是| C[返回结果]\n    B -->|否| D{可重试错误?}\n    D -->|AbortError| E[重试]\n    D -->|5xx 错误| E\n    D -->|ECONNRESET| E\n    D -->|ECONNREFUSED| E\n    D -->|ENOTFOUND| E\n    D -->|否| F[抛出异常]\n    E -->|attempt < retry| A\n    E -->|attempt >= retry| F\n```\n\n重试条件判断逻辑：资料来源：[src/common/http.ts:20-35]()\n\n## 版本配置\n\n版本信息从项目根目录的 `package.json` 动态读取，确保版本号与发布的包保持同步。若读取失败，默认回退至 `0.0.0`。资料来源：[src/version.ts:1-22]()\n\n## 错误处理与配置\n\n配置相关的错误会被规范化为 MCP 错误码，提供可操作的错误信息和明确的错误来源。\n\n| 错误码 | 触发条件 | 建议操作 |\n|--------|----------|---------|\n| `INVALID_TOKEN` | Token 无效或未激活 | 更新 `JUSTONEAPI_TOKEN` |\n| `RATE_LIMITED` | 请求频率超限 | 减慢请求速度 |\n| `DAILY_QUOTA_EXCEEDED` | 日配额用尽 | 等待次日或升级套餐 |\n| `INSUFFICIENT_BALANCE` | 账户余额不足 | 充值账户 |\n| `NETWORK_TIMEOUT` | 请求超时 | 检查网络或重试 |\n| `NETWORK_ERROR` | 网络连接失败 | 检查网络连接 |\n\n资料来源：[src/common/errors.ts:25-65]()\n\n## 配置验证流程\n\n```mermaid\nflowchart TD\n    A[进程启动] --> B[加载环境变量]\n    B --> C[验证 JUSTONEAPI_TOKEN]\n    C --> D{验证结果}\n    D -->|通过| E[初始化 Zod Schema]\n    D -->|失败| K[输出错误并退出]\n    E --> F[注册 MCP 工具]\n    F --> G[启动服务监听]\n    G --> H[等待请求]\n    H --> I{收到请求}\n    I -->|unified_search_v1| J1[执行统一搜索]\n    I -->|kuaishou_search_video_v2| J2[执行快手搜索]\n    J1 --> L[注入 token 并调用 API]\n    J2 --> L\n    L --> M[返回原始 JSON]\n```\n\n## 配置文件示例\n\n### Claude Desktop 配置\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\n资料来源：[README.md:80-96]()\n\n## 最佳实践\n\n1. **Token 安全**：始终通过环境变量传递 Token，避免硬编码在配置文件中\n2. **超时设置**：根据网络环境调整 `JUSTONEAPI_TIMEOUT_MS`，默认 20 秒适合大多数场景\n3. **重试策略**：在不稳定网络环境下可适当增加 `JUSTONEAPI_RETRY` 值\n4. **调试模式**：生产环境应保持 `JUSTONEAPI_DEBUG` 为 `false`，仅在排查问题时启用\n\n---\n\n<a id='tools-overview'></a>\n\n## 工具概览\n\n### 相关页面\n\n相关主题：[统一搜索工具](#unified-search), [平台专用工具](#platform-tools)\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</details>\n\n# 工具概览\n\n## 1. 概述\n\nJustOneAPI MCP（Model Context Protocol）是一个 MCP 服务器项目，旨在为 Claude Desktop、Cursor 等 MCP 主机提供对中国社交媒体和新闻平台的数据搜索能力。该项目采用\"传输而非转换\"（Transport, not transformation）的设计理念，优先保证数据的稳定性和原始性 资料来源：[README.md:1]()。\n\n工具（Tools）是 MCP 协议中的核心概念，每个工具代表一个可调用的功能单元。在 justoneapi-mcp 中，工具通过 `@modelcontextprotocol/sdk` 框架注册到 MCP 主机，用户可以通过自然语言或结构化参数调用这些工具 资料来源：[src/index.ts:1-30]()。\n\n## 2. 架构设计\n\n### 2.1 整体架构\n\n```mermaid\ngraph TD\n    subgraph MCP主机\n        A[Claude Desktop / Cursor]\n    end\n    \n    subgraph justoneapi-mcp\n        B[工具注册层<br/>src/index.ts]\n        C[工具实现层<br/>src/tools/]\n        D[公共组件层<br/>src/common/]\n    end\n    \n    subgraph 外部依赖\n        E[JustOneAPI 服务端]\n    end\n    \n    A -->|MCP 协议调用| B\n    B --> C\n    C --> D\n    D -->|HTTP 请求| E\n    \n    style A fill:#e1f5fe\n    style E fill:#fff3e0\n```\n\n### 2.2 请求处理流程\n\n```mermaid\nsequenceDiagram\n    participant U as 用户\n    participant M as MCP主机\n    participant S as justoneapi-mcp\n    participant A as JustOneAPI\n    \n    U->>M: 自然语言请求\n    M->>S: 调用工具\n    S->>S: 参数验证<br/>Zod Schema\n    S->>A: HTTP GET请求\n    A->>S: JSON响应\n    S->>S: 错误映射\n    S->>M: 结构化结果\n    M->>U: 返回结果\n```\n\n## 3. 可用工具列表\n\n### 3.1 当前版本工具\n\n| 工具名称 | 版本 | 功能描述 | 平台支持 |\n|---------|------|----------|----------|\n| `unified_search_v1` | v1 | 统一多平台搜索 | Weibo、WeChat、Zhihu、Douyin、Xiaohongshu、Bilibili、Kuaishou、News |\n| `kuaishou_search_video_v2` | v2 | 快手视频搜索 | 快手平台专用 |\n\n资料来源：[TOOLS.md:1-25]()\n\n### 3.2 工具命名规范\n\n所有工具遵循统一的命名约定：`{platform}_{action}_{version}` 资料来源：[README.md:45-46]()\n\n- **平台前缀**（platform）：指定目标平台，如 `kuaishou`、`unified`\n- **动作名称**（action）：表示操作类型，如 `search_video`、`search`\n- **版本号**（version）：使用语义化版本，如 `v1`、`v2`\n\n## 4. 统一搜索工具（unified_search_v1）\n\n### 4.1 工具描述\n\n`unified_search_v1` 是该 MCP 服务器的核心工具，支持跨多个中国社交媒体和新闻平台进行联合搜索。用户可以通过单一请求同时查询微博、微信、知乎、抖音、小红书、B站、快手和新闻平台的数据 资料来源：[src/index.ts:31-40]()。\n\n### 4.2 参数说明\n\n| 参数名 | 类型 | 必填 | 默认值 | 描述 |\n|-------|------|------|--------|------|\n| `keyword` | string | **是** | - | 搜索关键词，支持高级语法 |\n| `source` | string | 否 | `ALL` | 平台筛选器 |\n| `start` | string | 条件必填 | - | 开始时间（UTC+8），格式：yyyy-MM-dd HH:mm:ss |\n| `end` | string | 条件必填 | - | 结束时间（UTC+8），格式：yyyy-MM-dd HH:mm:ss |\n| `nextCursor` | string | 否 | - | 分页游标，用于获取后续页面 |\n\n资料来源：[src/tools/search/unified_search_v1.ts:15-42]()\n\n### 4.3 平台选项\n\n| 平台标识 | 描述 |\n|---------|------|\n| `ALL` | 全部平台（默认） |\n| `NEWS` | 新闻 |\n| `WEIBO` | 微博 |\n| `WEIXIN` | 微信 |\n| `ZHIHU` | 知乎 |\n| `DOUYIN` | 抖音 |\n| `XIAOHONGSHU` | 小红书 |\n| `BILIBILI` | B站（哔哩哔哩） |\n| `KUAISHOU` | 快手 |\n\n资料来源：[src/tools/search/unified_search_v1.ts:10-13]()\n\n### 4.4 搜索语法\n\n| 语法类型 | 语法格式 | 示例 | 说明 |\n|---------|---------|------|------|\n| 单关键词 | `keyword` | `deepseek` | 搜索包含指定关键词的内容 |\n| AND 搜索 | `word1 word2` | `deepseek chatgpt` | 同时包含两个关键词 |\n| OR 搜索 | `word1~word2` | `deepseek~chatgpt` | 包含任一关键词 |\n| NOT 搜索 | `word1 -word2` | `deepseek -chatgpt` | 包含前者，排除后者 |\n\n资料来源：[TOOLS.md:43-51]()\n\n### 4.5 参数验证逻辑\n\n```mermaid\ngraph TD\n    A[输入参数] --> B{keyword 是否为空?}\n    B -->|是| C[抛出错误]\n    B -->|否| D{是否使用分页?}\n    D -->|是 nextCursor| E[使用 nextCursor]\n    D -->|否 首頁| F{start 和 end 都存在?}\n    F -->|是| G[构建查询参数]\n    F -->|否| H[抛出错误：需要 start 和 end]\n    C --> I[返回 INVALID 请求]\n    H --> I\n    E --> J[构建查询参数<br/>含 nextCursor]\n    G --> K[调用 getJson]\n    J --> K\n```\n\n首次请求时，`start` 和 `end` 参数必须提供，且时间范围不能超过 84 天。使用分页时，只需提供 `nextCursor` 即可 资料来源：[src/tools/search/unified_search_v1.ts:30-37]()。\n\n## 5. 错误处理机制\n\n### 5.1 错误码映射表\n\n| 错误码 | 描述 | 用户操作建议 |\n|-------|------|-------------|\n| `INVALID_TOKEN` | Token 无效或未激活 | 更新 `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | 数据采集失败 | 稍后重试 |\n| `RATE_LIMITED` | 请求过于频繁 | 降低请求频率，稍后重试 |\n| `DAILY_QUOTA_EXCEEDED` | 达到每日使用限额 | 等待明天或升级套餐 |\n| `INSUFFICIENT_BALANCE` | 账户余额不足 | 充值账户 |\n| `PERMISSION_DENIED` | 无权访问该资源 | 联系技术支持 |\n| `VALIDATION_ERROR` | 请求参数无效 | 检查输入值 |\n| `INTERNAL_ERROR` | 服务器内部错误 | 稍后重试 |\n| `NETWORK_TIMEOUT` | 请求超时 | 检查网络或重试 |\n| `NETWORK_ERROR` | 网络连接失败 | 检查网络连接 |\n| `UPSTREAM_ERROR` | 上游服务未指明错误 | 重试或联系支持 |\n\n资料来源：[README.md:88-108]()\n\n### 5.2 错误格式\n\n所有错误均以统一格式返回：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n示例：\n\n```\nERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\n```\n\n资料来源：[src/common/errors.ts:1-30]()\n\n### 5.3 错误处理流程\n\n```mermaid\ngraph TD\n    A[HTTP 响应] --> B{HTTP 状态码}\n    B -->|200| C{业务 code}\n    B -->|非 200| D[抛出 NETWORK_ERROR]\n    C -->|0| E[返回成功响应]\n    C -->|非 0| F[映射错误码]\n    F --> G[构建 MCP 错误格式]\n    D --> G\n    E --> H[返回 JSON 数据]\n    G --> I[返回错误信息]\n```\n\n错误映射逻辑会自动识别超时、HTTP 状态码、网络错误等不同类型的故障，并将其转换为用户友好的错误信息 资料来源：[src/common/errors.ts:35-70]()。\n\n## 6. HTTP 请求机制\n\n### 6.1 重试策略\n\n```mermaid\ngraph TD\n    A[请求发起] --> B{尝试次数 <= 最大重试次数?}\n    B -->|是| C[发起 HTTP 请求]\n    C --> D{请求成功?}\n    D -->|是| E[返回响应]\n    D -->|否| F{可重试错误?}\n    F -->|是| G[等待 250ms * 尝试次数]\n    F -->|否| H[抛出错误]\n    G --> B\n    B -->|否| H\n```\n\n可重试的错误类型包括：\n\n- 超时错误（`AbortError`）\n- HTTP 5xx 错误\n- 网络连接重置（`ECONNRESET`）\n- 连接被拒绝（`ECONNREFUSED`）\n- DNS 解析失败（`ENOTFOUND`）\n\n资料来源：[src/common/http.ts:1-45]()\n\n### 6.2 超时配置\n\n| 配置项 | 默认值 | 说明 |\n|-------|-------|------|\n| `JUSTONEAPI_TIMEOUT_MS` | 20000ms | 单次请求超时时间 |\n\n## 7. 认证与配置\n\n### 7.1 环境变量配置\n\n| 变量名 | 必填 | 默认值 | 描述 |\n|-------|------|--------|------|\n| `JUSTONEAPI_TOKEN` | **是** | - | JustOneAPI 访问令牌 |\n| `JUSTONEAPI_BASE_URL` | 否 | `https://api.justoneapi.com` | API 端点 |\n| `JUSTONEAPI_TIMEOUT_MS` | 否 | `20000` | 请求超时（毫秒） |\n| `JUSTONEAPI_RETRY` | 否 | `1` | 首次失败后的重试次数 |\n| `JUSTONEAPI_DEBUG` | 否 | `false` | 启用调试日志输出到 stderr |\n\n资料来源：[README.md:119-130]()\n\n### 7.2 Token 安全处理\n\n系统内置 Token 脱敏功能，在日志输出时会自动将 Token 替换为掩码格式（显示前 4 位和后 4 位） 资料来源：[src/common/config.ts:1-20]()。\n\n示例：\n\n```\n原始 Token: sk-abc123def456ghi789\n日志显示:   sk-abc***ghi789\n```\n\n## 8. 分页机制\n\n### 8.1 分页流程\n\n当搜索结果存在多页时，响应中会包含 `nextCursor` 字段。用户可以通过以下方式继续获取更多结果：\n\n- \"Show me the next page of results\"\n- \"Get more results from the previous search\"\n- \"Continue with the next page\"\n\n```mermaid\ngraph LR\n    A[首页请求<br/>start + end] --> B[返回结果<br/>+ nextCursor]\n    B --> C{需要更多结果?}\n    C -->|是| D[下一页请求<br/>nextCursor]\n    C -->|否| E[结束]\n    D --> B\n```\n\n使用 `nextCursor` 分页时，无需再次提供 `start`、`end` 或 `source` 参数，因为游标中已包含这些信息 资料来源：[README.md:64-70]()。\n\n### 8.2 分页参数限制\n\n- 时间范围：首屏请求的时间跨度不能超过 84 天\n- 分页响应：每次返回 10-20 条结果\n\n## 9. 快速入门\n\n### 9.1 Claude Desktop 配置示例\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### 9.2 常用调用示例\n\n**跨平台搜索：**\n```\n使用 unified_search_v1 工具搜索\"AI\"，覆盖所有平台，时间范围为最近一个月。\n```\n\n**单平台搜索：**\n```\n搜索\"chatgpt\"相关内容，仅限微博平台，时间范围为2024年12月1日至2025年1月2日。\n```\n\n**分页获取：**\n```\nShow me more results\n```\n\n## 10. 输出格式\n\n### 10.1 成功响应\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-12-31T14:55:21Z\",\n  \"data\": {\n    // 平台特定数据结构\n  }\n}\n```\n\n### 10.2 错误响应\n\n```json\n{\n  \"isError\": true,\n  \"content\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"ERROR[ERROR_CODE] (upstream=XXX): Human-readable message\"\n    }\n  ]\n}\n```\n\n## 11. 项目依赖\n\n| 依赖包 | 版本 | 用途 |\n|-------|------|------|\n| `@modelcontextprotocol/sdk` | ^1.25.1 | MCP 协议 SDK |\n| `zod` | ^4.3.4 | 参数验证与 Schema 定义 |\n| `dotenv` | ^17.2.3 | 环境变量管理 |\n\n资料来源：[package.json:1-50]()\n\n---\n\n<a id='unified-search'></a>\n\n## 统一搜索工具\n\n### 相关页面\n\n相关主题：[工具概览](#tools-overview), [平台专用工具](#platform-tools)\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- [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# 统一搜索工具\n\n## 概述\n\n统一搜索工具（`unified_search_v1`）是 justoneapi-mcp 项目提供的核心功能，旨在为用户提供跨多个中国社交媒体和新闻平台的统一搜索能力。通过单一接口，用户可以同时检索微博、微信、知乎、抖音、小红书、B站、快手和新闻等多个平台的内容，无需逐个平台调用不同的 API。\n\n该工具遵循项目的核心设计理念——**传输而非转换**，即保持原始数据的完整性和保真度，不对上游响应进行字段解析或数据重组。资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 架构设计\n\n### 技术栈\n\n统一搜索工具基于以下技术组件构建：\n\n| 组件 | 技术选型 | 作用 |\n|------|----------|------|\n| MCP SDK | @modelcontextprotocol/sdk ^1.25.1 | 提供 MCP 服务器基础设施 |\n| 参数验证 | Zod ^4.3.4 | Schema 定义与输入验证 |\n| HTTP 客户端 | Node.js 内置 fetch | API 请求处理 |\n| 配置管理 | dotenv ^17.2.3 | 环境变量加载 |\n\n资料来源：[package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n### 模块依赖关系\n\n```mermaid\ngraph TD\n    A[unified_search_v1] --> B[requireToken]\n    A --> C[getJson]\n    A --> D[UnifiedSearchV1Input]\n    B --> E[config.ts - token验证]\n    C --> F[http.ts - HTTP请求]\n    F --> G[API Endpoint]\n    D --> H[Zod Schema验证]\n```\n\n## 工具注册与入口\n\n统一搜索工具通过 MCP SDK 的 `server.registerTool()` 方法注册到 MCP 服务器。工具注册时需要提供工具名称、描述和输入模式。资料来源：[src/index.ts:22-42](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n```typescript\nserver.registerTool(\n  \"unified_search_v1\",\n  {\n    description:\n      \"Unified search across multiple platforms (Weibo, WeChat, Zhihu, Douyin, Xiaohongshu, Bilibili, Kuaishou, News). Search by keyword with time range. Supports AND/OR/NOT operators and pagination. Returns raw JSON response.\",\n    inputSchema: UnifiedSearchV1Input.shape,\n  },\n  async (input) => {\n    // 处理逻辑\n  }\n);\n```\n\n### 错误处理机制\n\n工具执行过程中捕获所有异常，并通过 `toMcpErrorPayload()` 函数将错误转换为标准化的 MCP 错误格式返回。错误消息格式为：`ERROR[ERROR_CODE] (upstream=XXX): Human-readable message`。资料来源：[src/index.ts:31-39](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n## 输入参数定义\n\n`UnifiedSearchV1Input` 是统一搜索工具的 Zod Schema，定义了所有合法的输入参数及其验证规则。资料来源：[src/tools/search/unified_search_v1.ts:10-32](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n\n### 参数一览\n\n| 参数名 | 类型 | 必填 | 默认值 | 说明 |\n|--------|------|------|--------|------|\n| keyword | string | 是 | - | 搜索关键词，支持高级语法 |\n| source | PlatformType | 否 | ALL | 平台筛选器 |\n| start | string | 条件必填 | - | 开始时间（UTC+8），首页必需 |\n| end | string | 条件必填 | - | 结束时间（UTC+8），首页必需 |\n| nextCursor | string | 否 | - | 分页游标，用于后续页面 |\n\n### 平台类型枚举\n\n统一搜索支持以下平台类型：\n\n```typescript\nexport const PlatformType = z.enum([\n  \"ALL\",\n  \"NEWS\",\n  \"WEIBO\",\n  \"WEIXIN\",\n  \"ZHIHU\",\n  \"DOUYIN\",\n  \"XIAOHONGSHU\",\n  \"BILIBILI\",\n  \"KUAISHOU\",\n]);\n```\n\n资料来源：[src/tools/search/unified_search_v1.ts:7-18](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)\n\n| 枚举值 | 平台名称 |\n|--------|----------|\n| ALL | 所有平台（默认） |\n| NEWS | 新闻 |\n| WEIBO | 微博 |\n| WEIXIN | 微信 |\n| ZHIHU | 知乎 |\n| DOUYIN | 抖音 |\n| XIAOHONGSHU | 小红书 |\n| BILIBILI | B站 |\n| KUAISHOU | 快手 |\n\n### 参数验证规则\n\n1. **keyword**：最短长度 1 个字符，不允许空字符串\n2. **start/end**：首次请求时必须提供，且结束时间必须晚于开始时间\n3. **时间范围**：查询时间跨度必须在 84 天以内\n4. **nextCursor**：用于分页时，必须替代 start/end 参数使用\n\n## 搜索语法\n\n统一搜索工具支持丰富的高级搜索语法，允许用户精确表达搜索意图。资料来源：[TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n\n### 语法类型\n\n| 语法类型 | 示例 | 说明 |\n|----------|------|------|\n| 单关键词 | `deepseek` | 搜索包含该关键词的所有内容 |\n| AND 搜索 | `deepseek chatgpt` | 两个关键词必须同时出现 |\n| OR 搜索 | `deepseek~chatgpt` | 两个关键词任一出现即可 |\n| NOT 搜索 | `deepseek -chatgpt` | 包含第一个词但排除第二个词 |\n\n### 使用示例\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## 请求处理流程\n\n```mermaid\nsequenceDiagram\n    participant User as 用户\n    participant MCP as MCP服务器\n    participant Handler as unifiedSearchV1\n    participant HTTP as getJson\n    participant API as JustOneAPI\n\n    User->>MCP: unified_search_v1 调用\n    MCP->>Handler: 传入输入参数\n    Handler->>Handler: Zod Schema 验证\n    Handler->>Handler: 构建 URL 参数\n    Handler->>HTTP: 发起 GET 请求\n    HTTP->>API: GET /api/search/v1\n    API-->>HTTP: JSON 响应\n    HTTP-->>Handler: 解析后的 JSON\n    Handler-->>MCP: 返回内容数组\n    MCP-->>User: 格式化输出\n```\n\n## 分页机制\n\n统一搜索工具采用游标式分页机制，与传统的页码分页方式不同。当搜索结果存在后续页面时，响应中会包含 `nextCursor` 字段。资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n### 分页流程\n\n```mermaid\ngraph TD\n    A[首次搜索请求] --> B{提供 start/end?}\n    B -->|是| C[发起首页请求]\n    B -->|否| D[使用 nextCursor]\n    C --> E[获取响应]\n    D --> E\n    E --> F{存在 nextCursor?}\n    F -->|是| G[返回 nextCursor 给用户]\n    F -->|否| H[搜索完成]\n    G --> I[用户请求下一页]\n    I --> D\n```\n\n### 分页使用方式\n\n用户获取下一页结果时，无需再次提供 `start`、`end` 或 `source` 参数，因为游标中已包含这些信息：\n\n```\nShow me the next page of results\nGet more results from the previous search\nContinue with the next page\n```\n\n## HTTP 请求处理\n\n### getJson 函数\n\n统一搜索工具内部使用 `getJson()` 函数处理所有 HTTP 请求，该函数位于 `src/common/http.ts`。资料来源：[src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n### 重试策略\n\n`getJson()` 实现了智能重试机制，仅在以下情况下进行重试：\n\n| 重试条件 | 触发场景 |\n|----------|----------|\n| 请求超时 | AbortError 异常 |\n| HTTP 5xx 错误 | 服务器内部错误 |\n| 网络连接重置 | ECONNRESET |\n| 连接被拒绝 | ECONNREFUSED |\n| DNS 解析失败 | ENOTFOUND |\n\n重试逻辑采用指数退避策略，每次重试间隔为 `250 * attempt` 毫秒。\n\n### 请求超时\n\n默认请求超时时间为 20000 毫秒（20秒），可通过 `JUSTONEAPI_TIMEOUT_MS` 环境变量配置。资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 错误处理\n\n### 错误码映射\n\n项目维护了一套标准化的错误码体系，所有错误最终都会映射到这些代码。资料来源：[src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n| 错误码 | 含义 | 建议操作 |\n|--------|------|----------|\n| INVALID_TOKEN | Token 无效或已失效 | 更新 JUSTONEAPI_TOKEN |\n| COLLECT_FAILED | 数据采集失败 | 稍后重试 |\n| RATE_LIMITED | 请求过于频繁 | 降低请求频率 |\n| DAILY_QUOTA_EXCEEDED | 达到日使用限额 | 等待次日或升级套餐 |\n| INSUFFICIENT_BALANCE | 账户余额不足 | 充值账户 |\n| PERMISSION_DENIED | 无权访问该资源 | 联系客服 |\n| VALIDATION_ERROR | 请求参数无效 | 检查输入值 |\n| INTERNAL_ERROR | 服务器内部错误 | 稍后重试 |\n| NETWORK_TIMEOUT | 请求超时 | 检查网络或重试 |\n| NETWORK_ERROR | 网络连接失败 | 检查网络连接 |\n| UPSTREAM_ERROR | 上游未指明错误 | 重试或联系客服 |\n\n### 错误响应格式\n\n所有错误均以统一格式返回：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n其中 `upstream` 字段表示上游 API 返回的原始错误码。\n\n## 配置管理\n\n### 环境变量\n\n统一搜索工具使用以下环境变量进行配置：资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n| 变量名 | 必填 | 默认值 | 说明 |\n|--------|------|--------|------|\n| JUSTONEAPI_TOKEN | 是 | - | 您的 JustOneAPI 令牌 |\n| JUSTONEAPI_BASE_URL | 否 | https://api.justoneapi.com | API 端点 |\n| JUSTONEAPI_TIMEOUT_MS | 否 | 20000 | 请求超时（毫秒） |\n| JUSTONEAPI_RETRY | 否 | 1 | 首次失败后的重试次数 |\n| JUSTONEAPI_DEBUG | 否 | false | 启用调试日志输出 |\n\n### Token 安全\n\n配置模块实现了 Token 脱敏功能，在日志记录时会自动将 Token 遮蔽，防止敏感信息泄露。资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\n\n## 输出格式\n\n统一搜索工具返回原始 JSON 响应，不进行任何字段标准化或数据结构重组。这是项目\"传输而非转换\"设计理念的体现。资料来源：[TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n\n### 成功响应结构\n\n```json\n{\n  \"code\": 0,\n  \"message\": null,\n  \"recordTime\": \"2025-12-31T14:55:00\",\n  \"data\": {\n    // 平台特定的数据结构\n  }\n}\n```\n\n- `code: 0` 表示成功\n- `code != 0` 表示错误（参见错误处理章节）\n\n## 使用示例\n\n### 基础搜索\n\n使用自然语言请求统一搜索：\n\n```\nSearch for AI discussions on Chinese social media from last week\n```\n\nClaude 会自动转换为正确的 API 格式，处理日期格式化（UTC+8 时区），并返回聚合结果。\n\n### 高级搜索\n\n**平台特定搜索：**\n```\nSearch for \"chatgpt\" on Weibo only, from December 1st to January 2nd\n```\n\n**复杂查询：**\n```\nSearch for posts containing \"AI\" OR \"机器学习\" but NOT \"广告\" on Zhihu,\nfrom the last 30 days\n```\n\n### 配置示例\n\n在 Claude Desktop 的 `mcpServers` 配置中添加：\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## 与其他工具的关系\n\njustoneapi-mcp 项目中，除了统一搜索工具外，还提供了平台特定搜索工具，如 `kuaishou_search_video_v2`。两者都基于相同的底层 HTTP 和错误处理机制，但面向不同的使用场景。资料来源：[src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)\n\n| 工具名称 | 搜索范围 | 适用场景 |\n|----------|----------|----------|\n| unified_search_v1 | 多平台聚合搜索 | 跨平台舆情分析、品牌监控 |\n| kuaishou_search_video_v2 | 快手平台 | 快手视频专项研究 |\n\n---\n\n<a id='platform-tools'></a>\n\n## 平台专用工具\n\n### 相关页面\n\n相关主题：[工具概览](#tools-overview), [统一搜索工具](#unified-search)\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/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.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</details>\n\n# 平台专用工具\n\n## 概述\n\n平台专用工具（Platform-Specific Tools）是 justoneapi-mcp 项目中针对特定社交媒体平台提供深度搜索能力的功能模块。与统一搜索工具 `unified_search_v1` 不同，平台专用工具针对单个平台进行优化，提供更精细的参数控制和平台特定的功能实现。\n\n当前已实现的平台专用工具包括：\n\n| 工具名称 | 平台 | 版本 | 功能描述 |\n|---------|------|------|---------|\n| `kuaishou_search_video_v2` | 快手 | v2 | 快手视频关键词搜索 |\n\n资料来源：[src/index.ts:9]()\n\n## 架构设计\n\n### 工具注册机制\n\n平台专用工具通过 MCP SDK 的 `registerTool` 方法注册到服务器中。每个工具包含三个核心组成部分：工具名称、描述信息（含 Zod 输入验证 schema）和异步处理函数。\n\n```mermaid\ngraph TD\n    A[MCP 主机发送请求] --> B[服务器接收工具调用]\n    B --> C[匹配工具名称]\n    C --> D{找到对应工具?}\n    D -->|是| E[执行异步处理函数]\n    D -->|否| F[返回错误]\n    E --> G[调用平台 API]\n    G --> H{请求成功?}\n    H -->|是| I[返回原始 JSON]\n    H -->|否| J[错误处理]\n    J --> K[转换为 MCP 错误格式]\n```\n\n资料来源：[src/index.ts:18-40]()\n\n### 目录结构\n\n平台专用工具遵循统一的目录组织规范：\n\n```\nsrc/tools/\n├── kuaishou/\n│   └── search_video_v2.ts    # 快手视频搜索 v2\n└── search/\n    └── unified_search_v1.ts  # 统一搜索 v1\n```\n\n这种结构确保了代码的模块化组织和可维护性，每个平台拥有独立的子目录，便于后续扩展更多平台工具。\n\n## 快手视频搜索工具\n\n### 功能介绍\n\n`kuaishou_search_video_v2` 是专门用于在快手平台搜索视频内容的工具。该工具通过快手开放 API 获取视频搜索结果，返回未经处理的原始 JSON 数据，确保数据完整性。\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:1-4]()\n\n### 输入参数\n\n| 参数名 | 类型 | 必填 | 默认值 | 说明 |\n|-------|------|------|--------|------|\n| `keyword` | string | 是 | - | 搜索关键词，如 \"dance\" |\n| `page` | number | 否 | 1 | 页码，必须为正整数 |\n\n输入验证由 Zod 库提供支持，确保参数类型的正确性：\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资料来源：[src/tools/kuaishou/search_video_v2.ts:6-9]()\n\n### API 请求构建\n\n工具将输入参数转换为 URL 查询参数并调用内部 HTTP 模块：\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请求流程：\n\n1. 从环境配置获取 API Token 并进行 URL 编码\n2. 对搜索关键词进行 URL 编码处理\n3. 构建完整的 API 端点 URL\n4. 调用 `getJson` 函数发起 HTTP GET 请求\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:11-18]()\n\n## 工具注册流程\n\n### 注册代码示例\n\n在主入口文件中，工具通过标准化的注册流程添加到 MCP 服务器：\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    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          {\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:18-40]()\n\n### 注册参数说明\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| 工具名称 | string | MCP 协议中调用该工具的标识符，遵循 `{platform}_{action}_{version}` 命名规范 |\n| description | string | 工具功能描述，供 MCP 主机（如 Claude Desktop）展示给用户 |\n| inputSchema | ZodObject | 使用 Zod 库定义的输入验证模式，包含参数类型、默认值和描述 |\n| 处理函数 | async function | 接收验证后的输入参数，执行工具逻辑并返回结果 |\n\n## 错误处理机制\n\n### 错误转换流程\n\n平台专用工具使用统一的错误处理机制 `toMcpErrorPayload` 将各类错误转换为标准化的 MCP 错误格式：\n\n```mermaid\ngraph TD\n    A[异常发生] --> B{错误类型判断}\n    B -->|AbortError| C[NETWORK_TIMEOUT]\n    B -->|upstreamCode| D[业务错误码映射]\n    B -->|httpStatus| E[UPSTREAM_ERROR]\n    B -->|cause/code| F[NETWORK_ERROR]\n    B -->|其他| G[UPSTREAM_ERROR]\n    \n    D --> H[返回 MCP 错误对象]\n    C --> H\n    E --> H\n    F --> H\n    G --> H\n    \n    H --> I[格式化错误消息]\n    I --> J[ERROR[CODE] (upstream=X): message]\n```\n\n资料来源：[src/common/errors.ts:30-60]()\n\n### 错误码映射表\n\n| 上游错误码 | MCP 错误码 | 说明 |\n|-----------|-----------|------|\n| 100 | INVALID_TOKEN | Token 无效或已失效 |\n| 301 | COLLECT_FAILED | 数据采集失败 |\n| 302 | RATE_LIMITED | 请求频率超限 |\n| 303 | DAILY_QUOTA_EXCEEDED | 每日配额已用尽 |\n| 400 | VALIDATION_ERROR | 参数验证错误 |\n| 500 | INTERNAL_ERROR | 服务器内部错误 |\n| 600 | PERMISSION_DENIED | 无权限访问 |\n| 601 | INSUFFICIENT_BALANCE | 账户余额不足 |\n\n资料来源：[src/common/errors.ts:68-85]()\n\n## 底层支持模块\n\n### HTTP 请求模块\n\n平台专用工具通过 `getJson` 函数发起 API 请求，该函数具备以下特性：\n\n- **自动重试机制**：对超时、5xx 错误和网络连接错误进行自动重试\n- **可配置超时**：支持通过 `JUSTONEAPI_TIMEOUT_MS` 环境变量配置请求超时时间，默认 20000ms\n- **请求重试次数**：可通过 `JUSTONEAPI_RETRY` 环境变量配置，默认 1 次重试\n- **Token 注入**：自动将认证 Token 添加到请求头\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:20-30]()\n\n### 配置管理模块\n\n工具通过 `requireToken` 函数获取环境变量中配置的 API Token：\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN;\n  if (!token?.trim()) {\n    throw new Error(\"JUSTONEAPI_TOKEN is required\");\n  }\n  return token;\n}\n```\n\n资料来源：[src/common/config.ts]()\n\n## 工具命名规范\n\n平台专用工具遵循统一的命名约定：\n\n```\n{platform}_{action}_{version}\n```\n\n| 组成部分 | 说明 | 示例 |\n|---------|------|------|\n| platform | 目标平台标识（小写） | kuaishou、douyin、weibo |\n| action | 操作类型 | search_video、get_user |\n| version | API 版本号 | v1、v2 |\n\n当前已实现的工具：\n\n| 工具名称 | 平台 | 版本 | 状态 |\n|---------|------|------|------|\n| kuaishou_search_video_v2 | 快手 | v2 | ✅ 已实现 |\n| unified_search_v1 | 统一搜索 | v1 | ✅ 已实现 |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 扩展指南\n\n### 添加新平台工具的步骤\n\n1. **创建工具目录**：在 `src/tools/` 下创建平台专属目录\n2. **定义输入模式**：使用 Zod 定义输入参数验证 schema\n3. **实现工具函数**：调用 `getJson` 发起 API 请求\n4. **注册工具**：在 `src/index.ts` 中使用 `server.registerTool` 注册\n5. **更新文档**：在 README.md 和 TOOLS.md 中添加工具说明\n\n### 依赖要求\n\n项目使用以下核心依赖实现平台专用工具功能：\n\n| 依赖包 | 版本 | 用途 |\n|-------|------|------|\n| @modelcontextprotocol/sdk | ^1.25.1 | MCP 服务器 SDK |\n| zod | ^4.3.4 | 输入参数验证 |\n| dotenv | ^17.2.3 | 环境变量管理 |\n\n资料来源：[package.json:18-30]()\n\n## 与统一搜索工具的对比\n\n| 特性 | 平台专用工具 | 统一搜索工具 |\n|------|-------------|-------------|\n| 覆盖范围 | 单平台 | 多平台聚合 |\n| 参数设计 | 平台特定参数 | 通用参数 |\n| 使用场景 | 深度平台分析 | 跨平台概览 |\n| 实现复杂度 | 较高 | 较低 |\n| 扩展方式 | 按平台添加 | 通用扩展 |\n\n资料来源：[src/tools/search/unified_search_v1.ts]()\n\n## 未来规划\n\n根据项目规划，以下平台专用工具即将推出：\n\n- 抖音视频搜索\n- 微博帖子搜索\n- Bilibili 视频搜索\n- 微信内容搜索\n- 知乎内容搜索\n- 小红书内容搜索\n- 新闻聚合搜索\n\n资料来源：[TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)\n\n---\n\n<a id='error-handling'></a>\n\n## 错误处理\n\n### 相关页面\n\n相关主题：[配置管理](#configuration), [认证授权](#authentication)\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- [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</details>\n\n# 错误处理\n\n## 概述\n\njustoneapi-mcp 采用统一的错误处理机制，将上游 API 的原始响应转换为标准化的 MCP 错误格式。该项目遵循\"传输而非转换\"（Transport, not transformation）的设计理念，在保持数据完整性的同时，为用户提供清晰、可操作的错误信息。 资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n错误处理模块位于 `src/common/errors.ts`，负责以下核心功能：\n\n- 定义标准化错误码体系（`JOAErrorCode`）\n- 映射上游 API 错误码到 MCP 错误码\n- 构建用户友好的错误消息\n- 将各类异常转换为统一的 MCP 错误负载\n\n## 错误码体系\n\n### JOAErrorCode 类型定义\n\n项目定义了 11 种标准化错误码，涵盖认证失败、网络问题、配额限制等各种场景。 资料来源：[src/common/errors.ts:58-69]()\n\n```typescript\nexport type JOAErrorCode =\n  | \"INVALID_TOKEN\"\n  | \"COLLECT_FAILED\"\n  | \"RATE_LIMITED\"\n  | \"DAILY_QUOTA_EXCEEDED\"\n  | \"VALIDATION_ERROR\"\n  | \"INTERNAL_ERROR\"\n  | \"PERMISSION_DENIED\"\n  | \"INSUFFICIENT_BALANCE\"\n  | \"NETWORK_TIMEOUT\"\n  | \"NETWORK_ERROR\"\n  | \"UPSTREAM_ERROR\";\n```\n\n### 错误码对照表\n\n| 错误码 | 说明 | 用户操作 |\n|--------|------|----------|\n| `INVALID_TOKEN` | Token 无效或未激活 | 更新 `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | 数据采集失败 | 稍后重试 |\n| `RATE_LIMITED` | 请求频率超限 | 降低请求频率后重试 |\n| `DAILY_QUOTA_EXCEEDED` | 达到每日用量限制 | 明天重试或升级套餐 |\n| `VALIDATION_ERROR` | 请求参数无效 | 检查输入值 |\n| `INTERNAL_ERROR` | 服务器内部错误 | 稍后重试 |\n| `PERMISSION_DENIED` | 无权访问该资源 | 联系客服 |\n| `INSUFFICIENT_BALANCE` | 账户余额不足 | 充值账户 |\n| `NETWORK_TIMEOUT` | 请求超时 | 检查网络或重试 |\n| `NETWORK_ERROR` | 网络连接失败 | 检查网络连接 |\n| `UPSTREAM_ERROR` | 上游未指定错误 | 重试或联系客服 |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 错误映射机制\n\n### 上游错误码到 MCP 错误码的转换\n\n`mapUpstreamCode()` 函数将上游 API 返回的数字错误码映射为标准化的 JOA 错误码。 资料来源：[src/common/errors.ts:77-94]()\n\n```typescript\nexport function mapUpstreamCode(code: number | undefined): JOAErrorCode {\n  switch (code) {\n    case 100:\n      return \"INVALID_TOKEN\";\n    case 301:\n      return \"COLLECT_FAILED\";\n    case 302:\n      return \"RATE_LIMITED\";\n    case 303:\n      return \"DAILY_QUOTA_EXCEEDED\";\n    case 400:\n      return \"VALIDATION_ERROR\";\n    case 500:\n      return \"INTERNAL_ERROR\";\n    case 600:\n      return \"PERMISSION_DENIED\";\n    case 601:\n      return \"INSUFFICIENT_BALANCE\";\n    default:\n      return \"UPSTREAM_ERROR\";\n  }\n}\n```\n\n### 映射关系图\n\n```mermaid\ngraph LR\n    A[\"上游错误码\"] --> B{\"code 值\"}\n    B -->|100| C[\"INVALID_TOKEN\"]\n    B -->|301| D[\"COLLECT_FAILED\"]\n    B -->|302| E[\"RATE_LIMITED\"]\n    B -->|303| F[\"DAILY_QUOTA_EXCEEDED\"]\n    B -->|400| G[\"VALIDATION_ERROR\"]\n    B -->|500| H[\"INTERNAL_ERROR\"]\n    B -->|600| I[\"PERMISSION_DENIED\"]\n    B -->|601| J[\"INSUFFICIENT_BALANCE\"]\n    B -->|其他| K[\"UPSTREAM_ERROR\"]\n```\n\n## 用户消息构建\n\n### buildUserMessage 函数\n\n`buildUserMessage()` 函数为每种错误码生成用户友好的错误消息。当上游返回消息时，优先使用上游消息；否则使用默认消息。 资料来源：[src/common/errors.ts:96-128]()\n\n```typescript\nexport function buildUserMessage(mcpCode: JOAErrorCode, upstreamMessage?: string | null): string {\n  const base = upstreamMessage && upstreamMessage.trim() ? upstreamMessage.trim() : undefined;\n\n  switch (mcpCode) {\n    case \"INVALID_TOKEN\":\n      return base ?? \"Invalid or inactive token. Please update JUSTONEAPI_TOKEN.\";\n    case \"COLLECT_FAILED\":\n      return base ?? \"Collection failed. Please retry after a short delay.\";\n    case \"RATE_LIMITED\":\n      return base ?? \"Rate limit exceeded. Please slow down and retry later.\";\n    case \"DAILY_QUOTA_EXCEEDED\":\n      return base ?? \"Daily quota exceeded. Please try again tomorrow or upgrade your plan.\";\n    case \"VALIDATION_ERROR\":\n      return base ?? \"Invalid parameters. Please check the input values.\";\n    case \"PERMISSION_DENIED\":\n      return base ?? \"Permission denied. Please verify your account permissions.\";\n    case \"INSUFFICIENT_BALANCE\":\n      return base ?? \"Insufficient balance. Please top up your account.\";\n    case \"INTERNAL_ERROR\":\n      return base ?? \"Internal server error. Please retry later.\";\n    case \"NETWORK_TIMEOUT\":\n      return base ?? \"Network timeout. Please retry later.\";\n    case \"NETWORK_ERROR\":\n      return base ?? \"Network error. Please retry later.\";\n    default:\n      return base ?? \"Upstream error. Please retry later.\";\n  }\n}\n```\n\n## 错误转换\n\n### toMcpErrorPayload 函数\n\n`toMcpErrorPayload()` 是核心错误转换函数，将各种类型的异常统一转换为 MCP 错误负载格式。 资料来源：[src/common/errors.ts:130-173]()\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    code?: string;\n    cause?: unknown;\n  };\n\n  // AbortController 超时\n  if (error.name === \"AbortError\") {\n    return { code: \"NETWORK_TIMEOUT\", message: buildUserMessage(\"NETWORK_TIMEOUT\") };\n  }\n\n  // 业务错误码\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  // HTTP 级别错误\n  if (typeof error.httpStatus === \"number\") {\n    return {\n      code: \"UPSTREAM_ERROR\",\n      message: error.message ?? `HTTP error ${error.httpStatus}`,\n      httpStatus: error.httpStatus,\n    };\n  }\n\n  // 网络连接错误\n  if (error.cause || error.code === \"ECONNREFUSED\" || error.code === \"ENOTFOUND\") {\n    return {\n      code: \"NETWORK_ERROR\",\n      message: error.message ?? buildUserMessage(\"NETWORK_ERROR\"),\n    };\n  }\n\n  return { code: \"UPSTREAM_ERROR\", message: error.message ?? \"Unknown error\" };\n}\n```\n\n### 错误转换流程图\n\n```mermaid\ngraph TD\n    A[\"捕获异常 e\"] --> B{\"error.name === 'AbortError'?\"}\n    B -->|是| C[\"返回 NETWORK_TIMEOUT\"]\n    B -->|否| D{\"error.upstreamCode !== undefined?\"}\n    D -->|是| E[\"mapUpstreamCode + buildUserMessage\"]\n    D -->|否| F{\"typeof error.httpStatus === 'number'?\"}\n    F -->|是| G[\"返回 UPSTREAM_ERROR\"]\n    F -->|否| H{\"error.cause || ECONNREFUSED || ENOTFOUND?\"}\n    H -->|是| I[\"返回 NETWORK_ERROR\"]\n    H -->|否| J[\"返回 UPSTREAM_ERROR + Unknown error\"]\n```\n\n## 上游响应验证\n\n### isUpstreamOk 函数\n\n用于判断上游 API 响应是否成功。 资料来源：[src/common/errors.ts:71-75]()\n\n```typescript\nexport type UpstreamResponse = {\n  code?: number;\n  message?: string | null;\n  recordTime?: string;\n  data?: unknown;\n};\n\nexport function isUpstreamOk(resp: UpstreamResponse): boolean {\n  return Number(resp?.code) === 0;\n}\n```\n\n### UpstreamResponse 类型定义\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `code` | number | 响应状态码，`0` 表示成功 |\n| `message` | string \\| null | 响应消息 |\n| `recordTime` | string | 记录时间 |\n| `data` | unknown | 响应数据 |\n\n资料来源：[src/common/errors.ts:54-56]()\n\n## HTTP 请求重试机制\n\n### getJson 函数中的重试逻辑\n\n`src/common/http.ts` 中的 `getJson()` 函数实现了智能重试机制，针对特定错误进行自动重试。 资料来源：[src/common/http.ts]()\n\n重试条件：\n\n- `AbortError`（超时）\n- HTTP 5xx 错误\n- `ECONNRESET`\n- `ECONNREFUSED`\n- `ENOTFOUND`\n\n```mermaid\ngraph TD\n    A[\"发起 HTTP 请求\"] --> B{\"请求成功?\"}\n    B -->|是| C[\"返回响应 JSON\"]\n    B -->|否| D{\"可重试错误?\"}\n    D -->|否| E[\"抛出异常\"]\n    D -->|是| F{\"尝试次数 < 最大次数?\"}\n    F -->|是| G[\"等待 250ms * attempt\"]\n    G --> H[\"重新发起请求\"]\n    H --> B\n    F -->|否| E\n```\n\n## MCP 工具中的错误处理\n\n### 统一搜索工具示例\n\n在 `src/index.ts` 中，所有工具都使用统一的错误处理模式： 资料来源：[src/index.ts]()\n\n```typescript\nasync (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\n### 错误格式规范\n\n所有错误按照统一格式返回：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n### 示例\n\n| 场景 | 错误输出 |\n|------|----------|\n| Token 无效 | `ERROR[INVALID_TOKEN] (upstream=100): Invalid or inactive token. Please update JUSTONEAPI_TOKEN.` |\n| 频率限制 | `ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.` |\n| 网络超时 | `ERROR[NETWORK_TIMEOUT] (upstream=N/A): Network timeout. Please retry later.` |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n### MCP 工具返回格式\n\n当工具调用出错时，返回包含 `isError: true` 的响应：\n\n```json\n{\n  \"isError\": true,\n  \"content\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.\"\n    }\n  ]\n}\n```\n\n## 配置与环境变量\n\n### 错误处理相关配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `JUSTONEAPI_TOKEN` | *(必填)* | API 认证令牌 |\n| `JUSTONEAPI_BASE_URL` | `https://api.justoneapi.com` | API 端点 |\n| `JUSTONEAPI_TIMEOUT_MS` | `20000` | 请求超时（毫秒） |\n| `JUSTONEAPI_RETRY` | `1` | 首次失败后的重试次数 |\n| `JUSTONEAPI_DEBUG` | `false` | 启用调试日志输出到 stderr |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 设计理念\n\n### Transport, not transformation\n\n该项目坚持\"传输而非转换\"的设计哲学：\n\n- 返回上游 API 的原始 JSON 响应\n- 不进行字段解析或数据规范化\n- 不重构数据结构\n- 确保长期兼容性\n\n错误处理模块在保持数据完整性的同时，提供了必要的错误信息翻译层，使用户能够快速定位和解决问题。 资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 相关文件\n\n| 文件路径 | 说明 |\n|----------|------|\n| `src/common/errors.ts` | 核心错误处理模块 |\n| `src/common/http.ts` | HTTP 请求与重试机制 |\n| `src/common/config.ts` | 配置管理（含 URL 安全日志） |\n| `src/index.ts` | MCP 工具注册与错误处理集成 |\n| `README.md` | 错误处理文档 |\n| `TOOLS.md` | 工具文档中的错误处理说明 |\n\n---\n\n<a id='authentication'></a>\n\n## 认证授权\n\n### 相关页面\n\n相关主题：[安装部署](#installation), [配置管理](#configuration)\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- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n</details>\n\n# 认证授权\n\n## 概述\n\njustoneapi-mcp 采用基于令牌（Token）的简洁认证机制。所有 API 请求必须携带有效的 JustOneAPI 令牌才能访问上游服务。该设计遵循 \"Transport, not transformation\" 原则，在令牌验证通过后直接透传请求，不进行额外的数据转换或协议转换。\n\n认证流程的核心组件位于 `src/common/config.ts` 模块中，负责令牌的读取、验证和安全传输。\n\n## 核心配置\n\n### 环境变量配置\n\n| 变量名 | 必填 | 默认值 | 说明 |\n|--------|------|--------|------|\n| `JUSTONEAPI_TOKEN` | 是 | 无 | 用户的 JustOneAPI 访问令牌 |\n| `JUSTONEAPI_BASE_URL` | 否 | `https://api.justoneapi.com` | API 端点地址 |\n| `JUSTONEAPI_TIMEOUT_MS` | 否 | `20000` | 请求超时时间（毫秒） |\n| `JUSTONEAPI_RETRY` | 否 | `1` | 首次失败后的重试次数 |\n| `JUSTONEAPI_DEBUG` | 否 | `false` | 是否启用调试日志输出 |\n\n### 令牌获取\n\n用户需访问 [justoneapi.com](https://dashboard.justoneapi.com/en/login) 注册账号并获取 API 令牌。令牌将作为查询参数附加到每个 API 请求中。\n\n## 认证流程\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Server\n    participant Config as config.ts\n    participant HTTP as http.ts\n    participant API as JustOneAPI\n    \n    Note over MCP: 服务启动\n    MCP->>Config: 读取 JUSTONEAPI_TOKEN\n    alt Token 为空或空白\n        Config-->>MCP: 抛出配置错误\n        MCP->>MCP: 终止启动并输出错误信息\n    end\n    \n    Note over MCP: 用户发起工具调用\n    MCP->>Config: requireToken()\n    Config->>Config: 验证令牌存在\n    MCP->>HTTP: 构建请求（含令牌）\n    HTTP->>API: GET /api/xxx?token=xxx\n    API-->>HTTP: 响应 (code=0 或 code!=0)\n    \n    alt 认证失败\n        API-->>HTTP: code != 0\n        HTTP-->>MCP: 抛出 UpstreamError\n        MCP-->>用户: ERROR[INVALID_TOKEN]\n    end\n```\n\n## 令牌验证实现\n\n### requireToken 函数\n\n`src/common/config.ts` 中实现了令牌验证函数：\n\n```typescript\nexport function requireToken(): string {\n  const token = process.env.JUSTONEAPI_TOKEN?.trim();\n  if (!token) {\n    throw new 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  }\n  return token;\n}\n```\n\n资料来源：[src/common/config.ts:1-50]()\n\n### 启动时验证\n\n服务启动时会在 `src/index.ts` 中进行强制验证：\n\n```typescript\nasync function main() {\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  // ... 继续初始化\n}\n```\n\n资料来源：[src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n## 令牌在请求中的传递\n\n所有工具实现都遵循统一的令牌传递模式。以统一搜索为例：\n\n```typescript\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  \n  return await getJson(`/api/search/v1?${params.toString()}`);\n}\n```\n\n资料来源：[src/tools/search/unified_search_v1.ts:30-50]()\n\n## 令牌安全处理\n\n### URL 安全日志\n\n为防止令牌在日志中泄露，系统提供了安全 URL 构建函数：\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该函数会在调试模式下将日志输出中的令牌进行脱敏处理，仅保留首尾字符。\n\n资料来源：[src/common/config.ts:60-80]()\n\n## 认证错误处理\n\n### 错误码映射\n\n`src/common/errors.ts` 负责将上游错误码映射为统一的 MCP 错误码：\n\n| 上游错误码 | MCP 错误码 | 说明 | 用户操作 |\n|-----------|-----------|------|----------|\n| - | `INVALID_TOKEN` | 令牌无效或未激活 | 更新 `JUSTONEAPI_TOKEN` |\n| 302 | `RATE_LIMITED` | 请求过于频繁 | 减缓请求频率 |\n| - | `INSUFFICIENT_BALANCE` | 账户余额不足 | 充值账户 |\n| - | `PERMISSION_DENIED` | 无权访问该资源 | 联系客服支持 |\n\n资料来源：[src/common/errors.ts:1-60]()\n\n### 错误响应格式\n\n认证错误以统一格式返回：\n\n```\nERROR[INVALID_TOKEN] (upstream=N/A): Token is invalid or inactive. Please update your JUSTONEAPI_TOKEN environment variable.\n```\n\n## 请求重试与超时\n\n### 重试机制\n\nHTTP 客户端在以下情况会进行重试：\n\n- `AbortError`（请求超时）\n- HTTP 5xx 状态码\n- 网络错误（`ECONNRESET`、`ECONNREFUSED`、`ENOTFOUND`）\n\n重试间隔采用指数退避策略：\n\n```typescript\n// small backoff\nawait new Promise((r) => setTimeout(r, 250 * attempt));\n```\n\n资料来源：[src/common/http.ts:40-80]()\n\n### 超时配置\n\n默认超时时间为 20 秒（20000 毫秒），可通过 `JUSTONEAPI_TIMEOUT_MS` 环境变量自定义。\n\n## MCP Host 配置示例\n\n### Claude Desktop 配置\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### 自定义配置\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## 最佳实践\n\n1. **令牌安全**：不要将令牌硬编码在代码中，使用环境变量传递\n2. **调试模式**：生产环境建议关闭 `JUSTONEAPI_DEBUG`\n3. **超时设置**：根据网络环境调整 `JUSTONEAPI_TIMEOUT_MS`\n4. **错误处理**：捕获 `INVALID_TOKEN` 错误并提示用户更新令牌\n\n---\n\n<a id='system-architecture'></a>\n\n## 系统架构\n\n### 相关页面\n\n相关主题：[项目概述](#project-overview), [开发指南](#development-guide)\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# 系统架构\n\n## 概述\n\njustoneapi-mcp 是一个基于 Model Context Protocol (MCP) 的服务器实现，旨在为 AI 助手（如 Claude Desktop、Cursor 等）提供统一的中国社交媒体和新闻平台搜索能力。该项目采用\"传输而非转换\"（Transport, not transformation）的设计理念，直接返回上游 API 的原始 JSON 数据，确保最大程度的数据保真度。资料来源：[README.md]()\n\n## 架构分层\n\n系统采用模块化分层架构，主要分为以下四层：\n\n```mermaid\ngraph TD\n    A[MCP Host<br/>Claude Desktop/Cursor] --> B[工具注册层<br/>src/index.ts]\n    B --> C[业务逻辑层<br/>src/tools/]\n    C --> D[公共基础设施层<br/>src/common/]\n    D --> E[外部服务<br/>JustOneAPI]\n    \n    C --> C1[unified_search_v1]\n    C --> C2[kuaishou_search_video_v2]\n    \n    D --> D1[config.ts<br/>配置管理]\n    D --> D2[http.ts<br/>HTTP客户端]\n    D --> D3[errors.ts<br/>错误处理]\n```\n\n| 层级 | 文件路径 | 职责 |\n|------|----------|------|\n| 工具注册层 | `src/index.ts` | MCP 工具注册、请求路由、错误格式化 |\n| 业务逻辑层 | `src/tools/**` | 各个工具的具体实现（搜索、视频等） |\n| 公共基础设施层 | `src/common/**` | 配置管理、HTTP 请求、错误处理 |\n| 外部服务层 | JustOneAPI | 第三方数据源 API |\n\n资料来源：[src/index.ts:1-80]()\n\n## 核心组件\n\n### 1. 工具注册层 (src/index.ts)\n\n作为 MCP 服务器的入口点，负责：\n\n- 初始化 MCP SDK 服务器实例\n- 注册所有可用工具及其输入 schema\n- 统一处理工具执行中的异常\n- 格式化错误响应为 MCP 错误格式\n\n```mermaid\nsequenceDiagram\n    participant Host as MCP Host\n    participant Server as MCP Server\n    participant Tool as Tool Handler\n    participant API as JustOneAPI\n    \n    Host->>Server: 工具调用请求\n    Server->>Tool: 传递输入参数\n    Tool->>API: HTTP 请求\n    API-->>Tool: JSON 响应\n    Tool-->>Server: 返回数据\n    Server-->>Host: MCP 响应格式\n    \n    Note over Tool,API: 异常时返回错误格式\n    Tool-->>Server: ERROR[CODE]: message\n    Server-->>Host: isError: true\n```\n\n关键代码结构：\n\n```typescript\n// 工具注册示例\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          type: \"text\",\n          text: `ERROR[${m.code}] (upstream=${m.upstreamCode ?? \"N/A\"}): ${m.message}`,\n        }],\n      };\n    }\n  }\n);\n```\n\n资料来源：[src/index.ts:40-65]()\n\n### 2. 配置管理 (src/common/config.ts)\n\n负责管理和验证环境变量配置：\n\n| 配置项 | 必填 | 默认值 | 说明 |\n|--------|------|--------|------|\n| `JUSTONEAPI_TOKEN` | 是 | - | API 访问令牌 |\n| `JUSTONEAPI_BASE_URL` | 否 | `https://api.justoneapi.com` | API 端点 |\n| `JUSTONEAPI_TIMEOUT_MS` | 否 | `20000` | 请求超时（毫秒） |\n| `JUSTONEAPI_RETRY` | 否 | `1` | 首次尝试后的重试次数 |\n| `JUSTONEAPI_DEBUG` | 否 | `false` | 启用调试日志 |\n\n配置验证在服务器启动时执行：\n\n```typescript\nasync function main() {\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...\"\n    );\n    process.exit(1);\n  }\n  // ...\n}\n```\n\n资料来源：[src/common/config.ts:1-30]() 和 [src/index.ts:75-85]()\n\n### 3. HTTP 客户端 (src/common/http.ts)\n\n封装 HTTP 请求逻辑，提供重试机制：\n\n```mermaid\ngraph TD\n    A[发起请求] --> B{attempt < attempts?}\n    B -->|是| C[发送 HTTP 请求]\n    C --> D{响应状态?}\n    D -->|成功 2xx| E[返回 JSON]\n    D -->|超时/5xx/网络错误| F[等待 backoff]\n    F --> G[attempt++]\n    G --> B\n    D -->|其他错误| H[立即抛出异常]\n    B -->|否| I[抛出最后一次错误]\n```\n\n**可重试的错误类型**：\n\n| 错误类型 | 条件 |\n|----------|------|\n| 超时 | `error.name === \"AbortError\"` |\n| HTTP 5xx | `httpStatus >= 500` |\n| 连接重置 | `error.code === \"ECONNRESET\"` |\n| 连接被拒绝 | `error.code === \"ECONNREFUSED\"` |\n| 主机未找到 | `error.code === \"ENOTFOUND\"` |\n\n**重试策略**：指数退避，每次重试间隔 `250 * attempt` 毫秒。\n\n资料来源：[src/common/http.ts:1-60]()\n\n### 4. 错误处理 (src/common/errors.ts)\n\n统一错误码映射和用户友好消息生成：\n\n```mermaid\ngraph TD\n    A[原始错误] --> B{错误类型判断}\n    B -->|AbortError| C[NETWORK_TIMEOUT]\n    B -->|upstreamCode| D[mapUpstreamCode]\n    B -->|httpStatus| E[UPSTREAM_ERROR]\n    B -->|cause/code| F[NETWORK_ERROR]\n    B -->|其他| G[UPSTREAM_ERROR]\n    \n    D --> H[错误码映射表]\n    H --> H1[INVALID_TOKEN<br/>302]\n    H --> H2[COLLECT_FAILED<br/>500]\n    H --> H3[RATE_LIMITED<br/>429]\n    H --> H4[DAILY_QUOTA_EXCEEDED<br/>403]\n    H --> H5[INSUFFICIENT_BALANCE<br/>402]\n    H --> H6[PERMISSION_DENIED<br/>401]\n    H --> H7[VALIDATION_ERROR<br/>400]\n```\n\n**MCP 错误码对照表**：\n\n| MCP 错误码 | 说明 | 上游响应码 | 用户操作建议 |\n|------------|------|------------|--------------|\n| `INVALID_TOKEN` | Token 无效或未激活 | 302 | 更新 `JUSTONEAPI_TOKEN` |\n| `COLLECT_FAILED` | 数据采集失败 | 500 | 稍后重试 |\n| `RATE_LIMITED` | 请求过于频繁 | 429 | 降低请求频率 |\n| `DAILY_QUOTA_EXCEEDED` | 达到日用量限额 | 403 | 等待明天或升级套餐 |\n| `INSUFFICIENT_BALANCE` | 账户余额不足 | 402 | 充值账户 |\n| `PERMISSION_DENIED` | 无权访问该资源 | 401 | 联系客服 |\n| `VALIDATION_ERROR` | 请求参数无效 | 400 | 检查输入值 |\n| `INTERNAL_ERROR` | 服务器内部错误 | 其他 5xx | 稍后重试 |\n| `NETWORK_TIMEOUT` | 请求超时 | - | 检查网络或重试 |\n| `NETWORK_ERROR` | 网络连接失败 | - | 检查网络连接 |\n| `UPSTREAM_ERROR` | 未指定的上游错误 | - | 重试或联系客服 |\n\n**错误输出格式**：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n资料来源：[src/common/errors.ts:1-80]()\n\n## 工具实现\n\n### 统一搜索 (unified_search_v1)\n\n支持跨多个平台进行搜索，返回统一的 JSON 响应：\n\n```mermaid\ngraph LR\n    A[keyword] --> B[参数构建]\n    B --> C{分页?}\n    C -->|首页| D[start, end]\n    C -->|后续页| E[nextCursor]\n    D --> F[URLSearchParams]\n    E --> F\n    F --> G[/api/search/v1]\n    G --> H[getJson]\n```\n\n**输入参数 Schema**：\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `keyword` | string | 是 | 搜索关键词，支持 AND/OR/NOT 语法 |\n| `source` | enum | 否 | 平台筛选：`ALL`（默认）、`NEWS`、`WEIBO`、`WEIXIN`、`ZHIHU`、`DOUYIN`、`XIAOHONGSHU`、`BILIBILI`、`KUAISHOU` |\n| `start` | string | 首页必填 | 开始时间 `yyyy-MM-dd HH:mm:ss`（UTC+8），需在 84 天内 |\n| `end` | string | 首页必填 | 结束时间，需晚于开始时间 |\n| `nextCursor` | string | 分页用 | 上一页返回的游标 |\n\n**搜索语法**：\n\n- 单关键词：`deepseek`\n- AND 搜索（同时包含）：`deepseek chatgpt`\n- OR 搜索（任一包含）：`deepseek~chatgpt`\n- NOT 搜索（排除）：`deepseek -chatgpt`\n\n资料来源：[src/tools/search/unified_search_v1.ts:1-60]()\n\n### 快手视频搜索 (kuaishou_search_video_v2)\n\n针对快手平台的专用视频搜索工具：\n\n| 参数 | 类型 | 必填 | 默认值 | 说明 |\n|------|------|------|--------|------|\n| `keyword` | string | 是 | - | 搜索关键词，如 `'dance'` |\n| `page` | number | 否 | `1` | 页码，从 1 开始 |\n\n资料来源：[src/tools/kuaishou/search_video_v2.ts:1-25]()\n\n## 数据流\n\n```mermaid\nsequenceDiagram\n    participant User as 用户\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    User->>MCP: 自然语言搜索请求\n    MCP->>Server: unified_search_v1(keyword, source, start, end)\n    \n    Server->>HTTP: getJson(url)\n    HTTP->>HTTP: Token 编码\n    HTTP->>HTTP: 参数序列化\n    \n    HTTP->>API: GET /api/search/v1?...\n    API-->>HTTP: JSON 响应\n    \n    HTTP-->>Server: 原始 JSON 数据\n    Server-->>MCP: { content: [{type:\"text\", text: JSON}] }\n    MCP-->>User: 搜索结果摘要\n    \n    Note over API: code=0 表示成功<br/>code≠0 表示错误\n```\n\n## 依赖关系\n\n项目依赖项及其版本：\n\n| 依赖类型 | 包名 | 版本要求 | 用途 |\n|----------|------|----------|------|\n| 生产依赖 | `@modelcontextprotocol/sdk` | `^1.25.1` | MCP 协议实现 |\n| 生产依赖 | `zod` | `^4.3.4` | 输入验证和 Schema 定义 |\n| 生产依赖 | `dotenv` | `^17.2.3` | 环境变量管理 |\n| 开发依赖 | `typescript` | `^5.9.3` | TypeScript 编译 |\n| 开发依赖 | `eslint` | `^9.39.2` | 代码检查 |\n| 开发依赖 | `prettier` | `^3.7.4` | 代码格式化 |\n\n**运行环境要求**：Node.js >= 18.0.0\n\n资料来源：[package.json:1-50]()\n\n## 启动验证流程\n\n```mermaid\ngraph TD\n    A[服务器启动] --> B{检查 JUSTONEAPI_TOKEN}\n    B -->|未设置| C[输出错误信息]\n    C --> D[进程退出]\n    B -->|已设置| E[服务器就绪]\n    E --> F[注册所有工具]\n    F --> G[等待 MCP Host 调用]\n    G --> H{收到工具调用}\n    H -->|unified_search_v1| I[执行统一搜索]\n    H -->|kuaishou_search_video_v2| J[执行快手搜索]\n    I --> K[返回结果或错误]\n    J --> K\n```\n\n## 设计原则\n\n1. **传输而非转换**：直接返回上游 API 的原始响应，不进行字段解析或数据重组，确保长期兼容性。\n2. **透明性**：错误信息包含上游错误码，便于调试和问题定位。\n3. **稳定性**：通过 HTTP 重试机制和超时控制提高系统可靠性。\n4. **模块化**：各功能模块职责清晰，便于维护和扩展。\n\n## 扩展性\n\n项目采用插件化架构添加新工具：\n\n1. 在 `src/tools/` 下创建新的工具目录\n2. 定义 Zod 输入 Schema\n3. 实现工具逻辑函数\n4. 在 `src/index.ts` 中注册工具\n\n即将支持的工具：\n\n- Douyin 视频搜索\n- Weibo 帖子搜索\n- Bilibili 视频搜索\n\n---\n\n<a id='development-guide'></a>\n\n## 开发指南\n\n### 相关页面\n\n相关主题：[系统架构](#system-architecture), [平台专用工具](#platform-tools)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n- [eslint.config.js](https://github.com/justoneapi/justoneapi-mcp/blob/main/eslint.config.js)\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- [src/version.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/version.ts)\n</details>\n\n# 开发指南\n\n本开发指南旨在帮助开发者快速上手 justoneapi-mcp 项目的开发工作，涵盖项目结构、环境配置、代码规范、工具开发以及构建发布等核心内容。\n\n## 项目概述\n\njustoneapi-mcp 是一个基于 Model Context Protocol (MCP) 的服务器实现，用于连接 Claude 等 AI 助手与中国主流社交媒体平台的数据搜索接口。该项目支持统一搜索、快手视频搜索等多个工具，为用户提供跨平台社交媒体数据分析能力。\n\n核心设计理念：**Transport, not transformation** — 即优先保证数据传输的稳定性、透明性和原始数据完整性，而非对数据进行转换或处理。\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n## 项目结构\n\n```\njustoneapi-mcp/\n├── src/\n│   ├── index.ts              # MCP 服务器主入口\n│   ├── version.ts            # 版本管理模块\n│   ├── common/\n│   │   ├── config.ts         # 配置管理\n│   │   ├── errors.ts         # 错误处理\n│   │   └── http.ts           # HTTP 请求封装\n│   └── tools/\n│       ├── search/\n│       │   └── unified_search_v1.ts  # 统一搜索工具\n│       └── kuaishou/\n│           └── search_video_v2.ts     # 快手视频搜索工具\n├── eslint.config.js          # ESLint 配置\n├── tsconfig.json             # TypeScript 配置\n├── package.json              # 项目依赖配置\n└── README.md                 # 项目文档\n```\n\n### 目录职责说明\n\n| 目录/文件 | 职责 | 关键依赖 |\n|-----------|------|---------|\n| `src/index.ts` | MCP 服务器启动、工具注册、错误处理 | @modelcontextprotocol/sdk |\n| `src/common/` | 公共基础设施模块 | zod, dotenv |\n| `src/tools/` | 具体业务工具实现 | 继承 common 模块 |\n\n资料来源：[src/index.ts:1-50](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n## 环境配置\n\n### 运行时要求\n\n项目要求 Node.js 版本不低于 18.0.0。\n\n资料来源：[package.json:22](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n### 必需环境变量\n\n| 变量名 | 必填 | 默认值 | 说明 |\n|--------|------|--------|------|\n| `JUSTONEAPI_TOKEN` | **是** | 无 | JustOneAPI 访问令牌 |\n| `JUSTONEAPI_BASE_URL` | 否 | `https://api.justoneapi.com` | API 端点地址 |\n| `JUSTONEAPI_TIMEOUT_MS` | 否 | `20000` | 请求超时时间（毫秒） |\n| `JUSTONEAPI_RETRY` | 否 | `1` | 首次请求后的重试次数 |\n| `JUSTONEAPI_DEBUG` | 否 | `false` | 是否启用调试日志 |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n### 配置验证机制\n\n项目在启动时（`src/index.ts` 的 `main()` 函数）会验证 `JUSTONEAPI_TOKEN` 是否已设置。若未设置，服务器将输出错误信息并终止运行：\n\n```typescript\nif (!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...\"\n  );\n  process.exit(1);\n}\n```\n\n资料来源：[src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n## 开发工具配置\n\n### TypeScript 配置\n\n项目使用 TypeScript 5.9.3，编译配置位于 `tsconfig.json`。关键配置项包括：\n\n- **target**: ES2022\n- **module**: ESNext (ES 模块系统)\n- **moduleResolution**: bundler\n- **strict mode**: 启用严格类型检查\n\n资料来源：[package.json:29-31](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n### ESLint 配置\n\nESLint 配置集成了 TypeScript ESLint 插件和 Prettier 配置：\n\n```javascript\nrules: {\n  ...tseslint.configs.recommended.rules,\n  \"@typescript-eslint/no-explicit-any\": \"warn\",\n  \"@typescript-eslint/no-unused-vars\": [\"error\", { argsIgnorePattern: \"^_\" }],\n  \"no-console\": [\"warn\", { allow: [\"error\", \"warn\"] }],\n}\n```\n\n**规则说明：**\n\n| 规则 | 级别 | 说明 |\n|------|------|------|\n| `no-explicit-any` | warn | 允许使用 any 类型但会警告 |\n| `no-unused-vars` | error | 未使用的变量报错，下划线开头的参数除外 |\n| `no-console` | warn | 禁止使用 console.log，允许 error 和 warn |\n\n资料来源：[eslint.config.js](https://github.com/justoneapi/justoneapi-mcp/blob/main/eslint.config.js)\n\n### 项目依赖\n\n**生产依赖：**\n\n| 依赖包 | 版本 | 用途 |\n|--------|------|------|\n| @modelcontextprotocol/sdk | ^1.25.1 | MCP 协议实现 |\n| dotenv | ^17.2.3 | 环境变量加载 |\n| zod | ^4.3.4 | 输入验证与 Schema 定义 |\n\n**开发依赖：**\n\n| 依赖包 | 版本 | 用途 |\n|--------|------|------|\n| typescript | ^5.9.3 | TypeScript 编译器 |\n| eslint | ^9.39.2 | 代码检查 |\n| prettier | ^3.7.4 | 代码格式化 |\n| ts-node | ^10.9.2 | TypeScript 执行环境 |\n\n资料来源：[package.json:24-45](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n## 工具开发\n\n### 工具注册流程\n\nMCP 服务器通过 `server.registerTool()` 方法注册工具。注册时需提供工具名称、描述和输入 Schema：\n\n```typescript\nserver.registerTool(\n  \"tool_name_v1\",\n  {\n    description: \"工具描述字符串\",\n    inputSchema: ToolInputSchema.shape,\n  },\n  async (input) => {\n    // 工具实现逻辑\n    return {\n      content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n    };\n  }\n);\n```\n\n资料来源：[src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)\n\n### 工具命名规范\n\n项目采用统一的工具命名规范：`{platform}_{action}_{version}`\n\n| 示例 | 含义 |\n|------|------|\n| `unified_search_v1` | 统一搜索工具，第一版本 |\n| `kuaishou_search_video_v2` | 快手平台视频搜索，第二版本 |\n\n资料来源：[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)\n\n### 输入验证\n\n项目使用 Zod v4 进行输入验证。每个工具需要定义 `InputSchema`：\n\n```typescript\nimport { z } from \"zod\";\n\nexport const UnifiedSearchV1Input = z.object({\n  keyword: z.string().min(1).describe(\"搜索关键词\"),\n  source: PlatformType.optional().describe(\"平台来源\"),\n  start: z.string().optional().describe(\"开始时间\"),\n  end: z.string().optional().describe(\"结束时间\"),\n  nextCursor: z.string().optional().describe(\"分页游标\"),\n});\n```\n\n**Zod Schema 特性说明：**\n\n| 方法 | 用途 |\n|------|------|\n| `z.string().min(1)` | 非空字符串验证 |\n| `.optional()` | 可选字段 |\n| `.default(value)` | 默认值 |\n| `.describe(\"...\")` | 字段描述（用于 MCP 文档生成） |\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```typescript\nimport { z } from \"zod\";\nimport { requireToken } from \"../../common/config.js\";\nimport { getJson } from \"../../common/http.js\";\n\n// 1. 定义输入 Schema\nexport const ToolInput = z.object({\n  param1: z.string().min(1).describe(\"参数描述\"),\n  param2: z.number().int().min(1).default(1).describe(\"可选参数\"),\n});\n\n// 2. 实现工具函数\nexport async function toolFunction(input: z.infer<typeof ToolInput>) {\n  const token = encodeURIComponent(requireToken());\n  const param = encodeURIComponent(input.param1);\n  const page = input.param2;\n\n  return await getJson(\n    `/api/path?token=${token}&param=${param}&page=${page}`\n  );\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\n## HTTP 请求封装\n\n### 请求重试机制\n\n`getJson()` 函数封装了带重试逻辑的 HTTP 请求：\n\n```mermaid\ngraph TD\n    A[发起请求] --> B{成功?}\n    B -->|是| C[返回响应]\n    B -->|否| D{可重试?}\n    D -->|超时/5xx/网络错误| E[等待 250ms × attempt]\n    E --> F[重试]\n    F --> A\n    D -->|不可重试| G[抛出异常]\n    G --> H[错误处理]\n    C --> H\n```\n\n**可重试条件：**\n\n| 条件 | 说明 |\n|------|------|\n| `AbortError` | 请求超时 |\n| HTTP 5xx | 服务器内部错误 |\n| `ECONNRESET` | 连接被重置 |\n| `ECONNREFUSED` | 连接被拒绝 |\n| `ENOTFOUND` | DNS 解析失败 |\n\n资料来源：[src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)\n\n## 错误处理机制\n\n### 错误代码映射\n\n项目定义了一套标准化的 MCP 错误代码：\n\n| 错误代码 | 上游代码 | 说明 | 处理建议 |\n|----------|----------|------|----------|\n| `INVALID_TOKEN` | - | Token 无效或未激活 | 更新 JUSTONEAPI_TOKEN |\n| `COLLECT_FAILED` | - | 数据采集失败 | 稍后重试 |\n| `RATE_LIMITED` | 302 | 请求过于频繁 | 降低请求频率 |\n| `DAILY_QUOTA_EXCEEDED` | - | 达到日配额限制 | 等待明天或升级套餐 |\n| `INSUFFICIENT_BALANCE` | - | 账户余额不足 | 充值账户 |\n| `PERMISSION_DENIED` | - | 无权访问该资源 | 联系支持 |\n| `VALIDATION_ERROR` | - | 请求参数无效 | 检查输入值 |\n| `INTERNAL_ERROR` | - | 服务器内部错误 | 稍后重试 |\n| `NETWORK_TIMEOUT` | - | 请求超时 | 检查网络或重试 |\n| `NETWORK_ERROR` | - | 网络连接失败 | 检查网络连接 |\n| `UPSTREAM_ERROR` | - | 未指定的上游错误 | 重试或联系支持 |\n\n### 错误格式\n\n错误以以下格式返回：\n\n```\nERROR[ERROR_CODE] (upstream=XXX): Human-readable message\n```\n\n### 错误处理流程\n\n```mermaid\ngraph TD\n    A[捕获异常] --> B{AbortError?}\n    B -->|是| C[返回 NETWORK_TIMEOUT]\n    B -->|否| D{upstreamCode 存在?}\n    D -->|是| E[映射上游错误码]\n    E --> F[返回业务错误]\n    D -->|否| G{httpStatus 存在?}\n    G -->|是| H[返回 UPSTREAM_ERROR]\n    G -->|否| I{网络错误?}\n    I -->|是| J[返回 NETWORK_ERROR]\n    I -->|否| K[返回 UPSTREAM_ERROR]\n```\n\n资料来源：[src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)\n\n## 版本管理\n\n项目使用动态版本读取机制，从 `package.json` 中提取版本号：\n\n```typescript\nconst packageJsonPath = join(__dirname, \"../package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\nversion = packageJson.version || \"0.0.0\";\n```\n\n此设计确保构建产物中的版本号与 `package.json` 保持同步。\n\n资料来源：[src/version.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/version.ts)\n\n## 构建和发布\n\n### 安装依赖\n\n```bash\nnpm install\n```\n\n### 代码检查\n\n```bash\nnpm run lint      # ESLint 检查\nnpm run format    # Prettier 格式化\n```\n\n### 构建\n\n```bash\nnpm run build     # TypeScript 编译到 dist/\n```\n\n### 发布配置\n\n`package.json` 中的发布文件配置：\n\n```json\n{\n  \"files\": [\"dist\", \"README.md\", \"LICENSE\"]\n}\n```\n\n仅 `dist` 目录（编译产物）、`README.md` 和 `LICENSE` 会被发布到 npm。\n\n资料来源：[package.json:19-22](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)\n\n## Claude Desktop 集成\n\n### 配置示例\n\n在 Claude Desktop 配置文件中添加以下内容：\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### 配置文件位置\n\n| 操作系统 | 路径 |\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## 开发工作流程\n\n```mermaid\ngraph LR\n    A[创建工具文件] --> B[定义 Zod Schema]\n    B --> C[实现工具函数]\n    C --> D[注册工具到服务器]\n    D --> E[配置环境变量]\n    E --> F[本地测试]\n    F --> G[代码检查]\n    G --> H{通过?}\n    H -->|否| I[修复问题]\n    I --> G\n    H -->|是| J[构建发布]\n    J --> K[end]\n```\n\n## 常见问题\n\n### Token 配置问题\n\n**问题**: 服务器启动时报错 `JUSTONEAPI_TOKEN is required but not set`\n\n**解决**: 确保在 MCP host 配置中正确设置了 `JUSTONEAPI_TOKEN` 环境变量\n\n### 请求超时\n\n**问题**: 请求返回 `NETWORK_TIMEOUT`\n\n**解决**: 增加 `JUSTONEAPI_TIMEOUT_MS` 配置值（默认 20000ms）\n\n### 调试模式\n\n启用调试模式可查看详细的请求日志：\n\n```json\n{\n  \"env\": {\n    \"JUSTONEAPI_DEBUG\": \"true\"\n  }\n}\n```\n\n资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)\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. project-overview：项目概述。围绕“项目概述”模拟一次用户任务，不展示安装或运行结果。\n2. configuration：配置管理。围绕“配置管理”模拟一次用户任务，不展示安装或运行结果。\n3. tools-overview：工具概览。围绕“工具概览”模拟一次用户任务，不展示安装或运行结果。\n4. unified-search：统一搜索工具。围绕“统一搜索工具”模拟一次用户任务，不展示安装或运行结果。\n5. error-handling：错误处理。围绕“错误处理”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. project-overview\n输入：用户提供的“项目概述”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. configuration\n输入：用户提供的“配置管理”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. tools-overview\n输入：用户提供的“工具概览”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. unified-search\n输入：用户提供的“统一搜索工具”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. error-handling\n输入：用户提供的“错误处理”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / project-overview：Step 1 必须围绕“项目概述”形成一个小中间产物，并等待用户确认。\n- Step 2 / configuration：Step 2 必须围绕“配置管理”形成一个小中间产物，并等待用户确认。\n- Step 3 / tools-overview：Step 3 必须围绕“工具概览”形成一个小中间产物，并等待用户确认。\n- Step 4 / unified-search：Step 4 必须围绕“统一搜索工具”形成一个小中间产物，并等待用户确认。\n- Step 5 / error-handling：Step 5 必须围绕“错误处理”形成一个小中间产物，并等待用户确认。\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- README.zh-CN.md\n- src/common/config.ts\n- src/version.ts\n- TOOLS.md\n- src/index.ts\n- src/tools/search/unified_search_v1.ts\n- src/common/errors.ts\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"
}
