Doramagic 项目包 · 项目说明书

justoneapi-mcp 项目

生成时间:2026-05-15 01:49:03 UTC

项目概述

justoneapi-mcp 是一个基于 Model Context Protocol (MCP) 协议构建的服务器应用程序,专门用于在中国社交媒体平台和新闻网站上进行统一搜索和数据采集。该项目作为 MCP 主机(如 Claude Desktop、Cursor 等)与 JustOneAPI 之间的桥梁,使 AI 助手能够直接访问和分析中国主流社交媒体的内容。资料来源:[RE...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 系统架构图

继续阅读本节完整说明和来源证据。

章节 技术栈

继续阅读本节完整说明和来源证据。

章节 模块职责说明

继续阅读本节完整说明和来源证据。

项目简介

justoneapi-mcp 是一个基于 Model Context Protocol (MCP) 协议构建的服务器应用程序,专门用于在中国社交媒体平台和新闻网站上进行统一搜索和数据采集。该项目作为 MCP 主机(如 Claude Desktop、Cursor 等)与 JustOneAPI 之间的桥梁,使 AI 助手能够直接访问和分析中国主流社交媒体的内容。资料来源:README.md:1

该项目的核心设计理念是"传输而非转换"(Transport, not transformation),强调数据的稳定性和原始保真度,返回未经修改的上游 API 响应。资料来源:README.md:180

技术架构

系统架构图

graph TD
    subgraph MCP主机 ["MCP 主机"]
        A[Claude Desktop / Cursor]
    end
    
    subgraph justoneapi-mcp ["justoneapi-mcp 服务器"]
        B[入口模块 src/index.ts]
        C[工具注册模块]
        D[HTTP 请求模块]
        E[错误处理模块]
        F[配置管理模块]
        G[统一搜索工具]
        H[快手搜索工具]
    end
    
    subgraph JustOneAPI ["JustOneAPI 服务"]
        I[API 网关]
        J[上游数据源]
    end
    
    A -->|MCP 协议| B
    B --> C
    C --> G
    C --> H
    G --> D
    H --> D
    D --> F
    D -->|HTTP 请求| I
    I --> J
    
    J -->|微博| K[WEIBO]
    J -->|微信| L[WEIXIN]
    J -->|知乎| M[ZHIHU]
    J -->|抖音| N[DOUYIN]
    J -->|小红书| O[XIAOHONGSHU]
    J -->|哔哩哔哩| P[BILIBILI]
    J -->|快手| Q[KUAISHOU]
    J -->|新闻| R[NEWS]

技术栈

技术组件版本要求用途说明
Node.js>=18.0.0运行时环境
TypeScript^5.9.3开发语言
@modelcontextprotocol/sdk^1.25.1MCP 协议实现
Zod^4.3.4参数验证与 schema 定义
dotenv^17.2.3环境变量管理

资料来源:package.json:7-18

核心模块设计

模块职责说明

graph LR
    subgraph 核心模块
        A[config.ts]
        B[http.ts]
        C[errors.ts]
    end
    
    subgraph 工具模块
        D[unified_search_v1.ts]
        E[search_video_v2.ts]
    end
    
    subgraph 入口模块
        F[index.ts]
    end
    
    F --> A
    F --> D
    F --> E
    D --> B
    E --> B
    B --> C

配置管理模块

src/common/config.ts 负责管理和验证环境变量配置。资料来源:src/common/config.ts:1

配置项默认值必填说明
JUSTONEAPI_TOKEN-JustOneAPI 访问令牌
JUSTONEAPI_BASE_URLhttps://api.justoneapi.comAPI 端点地址
JUSTONEAPI_TIMEOUT_MS20000请求超时时间(毫秒)
JUSTONEAPI_RETRY1失败后重试次数
JUSTONEAPI_DEBUGfalse启用调试日志

资料来源:README.md:195-202

配置模块还提供令牌掩码功能,用于日志输出时保护敏感信息:

export function toSafeUrlForLog(fullUrl: string): string {
  // 移除或掩码 token 查询参数
}

资料来源:src/common/config.ts:27-39

HTTP 请求模块

src/common/http.ts 实现统一的 HTTP 请求处理机制,具备以下特性:资料来源:src/common/http.ts:1

重试机制

  • 仅对以下情况触发重试:
  • 请求超时(AbortError)
  • HTTP 5xx 状态码
  • 网络连接重置(ECONNRESET)
  • 连接被拒绝(ECONNREFUSED)
  • DNS 解析失败(ENOTFOUND)

退避策略:每次重试间隔为 250 * attempt 毫秒。资料来源:src/common/http.ts:28-29

graph TD
    A[发起请求] --> B{请求成功?}
    B -->|是| C[返回 JSON 响应]
    B -->|否| D{可重试错误?}
    D -->|超时/5xx/网络错误| E[等待退避时间]
    D -->|其他错误| F[抛出异常]
    E --> G[重试]
    G --> A
    D -->|达到最大重试次数| F

错误处理模块

src/common/errors.ts 实现标准化的 MCP 错误码映射系统。资料来源:src/common/errors.ts:1

错误码映射表

上游错误码MCP 错误码描述用户操作
302RATE_LIMITED请求频率超限降低请求频率后重试
-INVALID_TOKEN令牌无效或未激活更新 JUSTONEAPI_TOKEN
-COLLECT_FAILED数据采集失败短暂延迟后重试
-DAILY_QUOTA_EXCEEDED日用量超限等待明天或升级套餐
-INSUFFICIENT_BALANCE账户余额不足充值账户
-PERMISSION_DENIED无权访问资源联系客服
-VALIDATION_ERROR请求参数无效检查输入值
-INTERNAL_ERROR服务器内部错误稍后重试
-NETWORK_TIMEOUT请求超时检查网络或重试
-NETWORK_ERROR网络连接失败检查网络连接
-UPSTREAM_ERROR上游未指明错误重试或联系客服

资料来源:README.md:152-169

错误输出格式

ERROR[ERROR_CODE] (upstream=XXX): Human-readable message

示例:ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later. 资料来源:README.md:170-174

可用工具

工具清单

工具名称版本功能描述
unified_search_v1v1跨平台统一搜索
kuaishou_search_video_v2v2快手视频搜索

资料来源:TOOLS.md:15-19

统一搜索工具 (unified_search_v1)

统一搜索工具支持在多个中国社交媒体和新闻平台上一站式搜索。资料来源:src/tools/search/unified_search_v1.ts:1

支持的平台

  • ALL - 全部平台(默认)
  • NEWS - 新闻
  • WEIBO - 微博
  • WEIXIN - 微信
  • ZHIHU - 知乎
  • DOUYIN - 抖音
  • XIAOHONGSHU - 小红书
  • BILIBILI - 哔哩哔哩
  • KUAISHOU - 快手

资料来源:README.md:30-38

参数定义

参数类型必填说明
keywordstring搜索关键词,支持高级语法
sourcestring平台过滤器,默认 ALL
startstring首次请求必填开始时间 yyyy-MM-dd HH:mm:ss (UTC+8),范围不超过 84 天
endstring首次请求必填结束时间 yyyy-MM-dd HH:mm:ss (UTC+8),必须晚于开始时间
nextCursorstring分页时使用来自上一页响应的游标

资料来源:src/tools/search/unified_search_v1.ts:14-35

搜索语法

语法类型格式示例说明
单关键词worddeepseek搜索单个关键词
AND 搜索word1 word2deepseek chatgpt两个关键词必须同时出现
OR 搜索word1~word2deepseek~chatgpt任一关键词出现即可
NOT 搜索word -excludeddeepseek -chatgpt排除指定关键词

资料来源:README.md:122-127

API 调用示例

{
  "keyword": "AI",
  "source": "ALL",
  "start": "2025-01-01 00:00:00",
  "end": "2025-01-02 23:59:59"
}

快手视频搜索工具 (kuaishou_search_video_v2)

快手视频搜索是平台特定的工具,专注于快手平台的视频内容搜索。资料来源:src/tools/kuaishou/search_video_v2.ts:1

参数定义

参数类型必填默认值说明
keywordstring-搜索关键词,如 dance
pagenumber1页码,从 1 开始

资料来源:src/tools/kuaishou/search_video_v2.ts:5-8

输出契约

成功响应格式

所有工具返回原始 JSON 响应,设计原则是"最大数据保真度、无字段解析、无数据重组"。资料来源:README.md:149-152

{
  "code": 0,
  "message": null,
  "recordTime": "2025-12-31T14:55:21Z",
  "data": {
    // 平台特定数据结构
  }
}
字段类型说明
codeinteger0 表示成功,非 0 表示错误
messagestring/null错误信息,成功时为 null
recordTimestring响应记录时间(ISO 8601 格式)
dataobject平台特定数据内容

分页机制

当搜索结果存在更多页面时,响应会包含 nextCursor 字段。用户可以通过以下方式继续获取下一页:

  • "显示更多结果"
  • "继续获取上一页的更多结果"
  • "继续下一页"

系统会自动从上一条响应中提取 nextCursor 并用于后续请求。资料来源:README.md:128-141

graph LR
    A[首次请求] -->|无 nextCursor| B[返回第一页 + nextCursor]
    B --> C[请求第二页]
    C -->|携带 nextCursor| D[返回第二页 + nextCursor]
    D --> E[继续...直到无 nextCursor]

安装与配置

安装方式

推荐方式:npx(无需安装)

直接使用 npx 运行,无需本地安装:

{
  "mcpServers": {
    "justoneapi": {
      "command": "npx",
      "args": ["-y", "justoneapi-mcp"],
      "env": {
        "JUSTONEAPI_TOKEN": "your_token_here"
      }
    }
  }
}

资料来源:README.md:70-80

Claude Desktop 配置

配置文件位置:

操作系统配置文件路径
macOS~/Library/Application Support/Claude/claude_desktop_config.json
Windows%APPDATA%\Claude\claude_desktop_config.json
Linux~/.config/Claude/claude_desktop_config.json

自定义配置示例

{
  "mcpServers": {
    "justoneapi": {
      "command": "npx",
      "args": ["-y", "justoneapi-mcp"],
      "env": {
        "JUSTONEAPI_TOKEN": "your_token_here",
        "JUSTONEAPI_TIMEOUT_MS": "30000",
        "JUSTONEAPI_DEBUG": "true"
      }
    }
  }
}

版本管理

项目使用动态版本管理机制,从 package.json 读取版本号:资料来源:src/version.ts:1

const packageJsonPath = join(__dirname, "../package.json");
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
version = packageJson.version || "0.0.0";

项目结构

justoneapi-mcp/
├── src/
│   ├── index.ts                 # 入口模块
│   ├── version.ts               # 版本管理
│   ├── common/
│   │   ├── config.ts            # 配置管理
│   │   ├── http.ts              # HTTP 请求处理
│   │   └── errors.ts            # 错误处理
│   └── tools/
│       ├── search/
│       │   └── unified_search_v1.ts    # 统一搜索工具
│       └── kuaishou/
│           └── search_video_v2.ts      # 快手搜索工具
├── package.json
├── eslint.config.js
├── README.md
├── TOOLS.md
└── LICENSE

设计哲学

传输,而非转换

该 MCP 服务器的设计优先级为:资料来源:README.md:179-182

  1. 稳定性:确保服务可靠运行
  2. 透明度:返回原始数据,不隐藏上游信息
  3. 数据保真度:返回未修改的上游 API 响应

这一设计理念确保了长期兼容性和最大化的数据完整性,用户可以直接访问底层数据并进行自定义分析。

许可证

本项目采用 MIT 许可证开源授权。资料来源:README.md:206

资料来源:[package.json:7-18]()

安装部署

本文档详细说明 justoneapi-mcp 的安装、配置和部署流程。justoneapi-mcp 是一个基于 Model Context Protocol (MCP) 的服务器,用于连接 JustOneAPI 社交媒体数据搜索服务。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 运行环境

继续阅读本节完整说明和来源证据。

章节 依赖包

继续阅读本节完整说明和来源证据。

章节 方式一:npx 方式(推荐)

继续阅读本节完整说明和来源证据。

系统要求

运行环境

组件最低版本要求
Node.js>= 18.0.0

资料来源:package.json:28

依赖包

依赖包版本用途
@modelcontextprotocol/sdk^1.25.1MCP 协议实现
zod^4.3.4参数验证与 Schema 定义
dotenv^17.2.3环境变量管理

资料来源:package.json:33-36

安装方式

方式一:npx 方式(推荐)

使用 npx 可以直接运行,无需预先安装:

{
  "mcpServers": {
    "justoneapi": {
      "command": "npx",
      "args": ["-y", "justoneapi-mcp"],
      "env": {
        "JUSTONEAPI_TOKEN": "your_actual_token_here"
      }
    }
  }
}

这种方式的优势在于:

  • 无需手动安装
  • 始终使用最新版本
  • 配置简单快捷

资料来源:README.md:71-79

方式二:本地安装

如果需要特定版本或离线部署:

npm install -g justoneapi-mcp

或项目依赖方式:

npm install justoneapi-mcp

MCP 主机配置

Claude Desktop 配置

#### macOS

配置文件路径:~/Library/Application Support/Claude/claude_desktop_config.json

#### Windows

配置文件路径:%APPDATA%\Claude\claude_desktop_config.json

#### Linux

配置文件路径:~/.config/Claude/claude_desktop_config.json

完整配置示例

{
  "mcpServers": {
    "justoneapi": {
      "command": "npx",
      "args": ["-y", "justoneapi-mcp"],
      "env": {
        "JUSTONEAPI_TOKEN": "your_actual_token_here",
        "JUSTJUSTONEAPI_TIMEOUT_MS": "30000",
        "JUSTONEAPI_DEBUG": "true"
      }
    }
  }
}

资料来源:README.md:64-89

环境变量配置

必需配置

变量名说明默认值
JUSTONEAPI_TOKENJustOneAPI 访问令牌必需

可选配置

变量名默认值说明
JUSTONEAPI_BASE_URLhttps://api.justoneapi.comAPI 端点地址
JUSTONEAPI_TIMEOUT_MS20000请求超时时间(毫秒)
JUSTONEAPI_RETRY1首次请求失败后的重试次数
JUSTONEAPI_DEBUGfalse是否启用调试日志

资料来源:README.md:91-100

令牌获取

访问 JustOneAPI Dashboard 注册并获取 API 令牌。

配置模块详解

配置加载流程

graph TD
    A[启动 MCP Server] --> B[检查 JUSTONEAPI_TOKEN]
    B --> C{Token 是否存在且非空?}
    C -->|是| D[加载可选配置]
    C -->|否| E[输出错误信息并退出]
    D --> F[配置加载完成]
    F --> G[注册工具并启动服务]
    E --> H[进程终止]

配置模块负责在服务启动时验证必要参数,核心逻辑位于 src/common/config.ts

资料来源:src/common/config.ts

令牌验证

export function requireToken(): string {
  const token = process.env.JUSTONEAPI_TOKEN;
  if (!token?.trim()) {
    throw new Error("JUSTONEAPI_TOKEN is required");
  }
  return token;
}

该函数在所有 API 请求前被调用,确保令牌有效。

资料来源:src/common/config.ts

安全日志处理

配置模块提供令牌脱敏功能,避免在日志中泄露敏感信息:

export function toSafeUrlForLog(fullUrl: string): string {
  try {
    const u = new URL(fullUrl);
    if (u.searchParams.has("token")) {
      u.searchParams.set("token", maskToken(u.searchParams.get("token") ?? ""));
    }
    return u.toString();
  } catch {
    return fullUrl.replace(/token=([^&]+)/g, (_m, g1) => `token=${maskToken(g1)}`);
  }
}

资料来源:src/common/config.ts

HTTP 请求机制

请求流程

graph TD
    A[发起请求] --> B{重试次数 < maxRetries?}
    B -->|是| C[创建 AbortController]
    C --> D[设置超时定时器]
    D --> E[发送 GET 请求]
    E --> F{响应状态码 < 500?}
    F -->|是| G[解析 JSON 响应]
    G --> H{业务代码 == 0?}
    H -->|是| I[返回响应数据]
    H -->|否| J[抛出业务错误]
    F -->|否| K{可重试错误?}
    K -->|是| L[等待后重试]
    K -->|否| M[抛出错误]
    J --> N[返回错误响应]
    B -->|否| M
    L --> B

重试策略

请求失败时,HTTP 模块会自动重试以下情况:

错误类型是否重试
AbortError(超时)✅ 重试
HTTP 5xx 错误✅ 重试
ECONNRESET✅ 重试
ECONNREFUSED✅ 重试
ENOTFOUND✅ 重试
HTTP 4xx 错误❌ 不重试
业务代码 != 0❌ 不重试

重试间隔采用简单退避策略:250ms * attempt

资料来源:src/common/http.ts:24-36

超时配置

默认超时时间为 20 秒,可通过 JUSTONEAPI_TIMEOUT_MS 环境变量自定义:

const timer = setTimeout(() => controller.abort(), config.timeoutMs);

资料来源:src/common/http.ts:41

服务启动流程

启动时验证

graph TD
    A[main 函数入口] --> B[检查环境变量]
    B --> C{JUSTONEAPI_TOKEN 是否设置?}
    C -->|否| D[输出错误信息]
    D --> E[进程终止]
    C -->|是| F[创建 MCP Server]
    F --> G[注册 unified_search_v1 工具]
    G --> H[注册 kuaishou_search_video_v2 工具]
    H --> I[连接 stdio 传输]
    I --> J[服务就绪]

主入口代码

async function main() {
  if (!process.env.JUSTONEAPI_TOKEN?.trim()) {
    console.error(
      "[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\n" +
        "Please set the JUSTONEAPI_TOKEN environment variable..."
    );
    process.exit(1);
  }
  // ... 启动服务
}

资料来源:src/index.ts:58-65

TypeScript 编译配置

项目配置

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "lib": ["ES2022"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  },
  "include": ["src/**/*"],
 exclude": ["node_modules", "dist"]
}

编译产物输出至 dist 目录,包含以下文件:

目录内容
dist/common/通用模块(config、http、errors)
dist/tools/工具模块
dist/index.js主入口
dist/*.d.ts类型声明文件

资料来源:tsconfig.json

开发环境搭建

克隆项目

git clone https://github.com/justoneapi/justoneapi-mcp.git
cd justoneapi-mcp

安装依赖

npm install

TypeScript 类型检查

npm run typecheck

代码格式化

npm run format

ESLint 检查

npm run lint

构建项目

npm run build

启动服务(开发模式)

npm run start

项目文件结构

justoneapi-mcp/
├── src/
│   ├── index.ts                    # 主入口文件
│   ├── version.ts                  # 版本信息
│   ├── common/
│   │   ├── config.ts               # 配置管理
│   │   ├── http.ts                 # HTTP 请求封装
│   │   └── errors.ts               # 错误处理
│   └── tools/
│       └── search/
│           └── unified_search_v1.ts # 统一搜索工具
├── dist/                           # 编译输出
├── package.json                    # 项目配置
├── tsconfig.json                   # TypeScript 配置
└── eslint.config.js                # ESLint 配置

故障排查

常见问题

#### 1. Token 未设置错误

[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.

解决方案:确保在 MCP 主机配置中正确设置 JUSTONEAPI_TOKEN 环境变量。

#### 2. 请求超时

ERROR[NETWORK_TIMEOUT]: Request timed out

解决方案:增加 JUSTONEAPI_TIMEOUT_MS 配置值(默认 20000ms)。

#### 3. 速率限制

ERROR[RATE_LIMITED]: Rate limit exceeded

解决方案:降低请求频率,等待一段时间后重试。

调试模式

启用调试日志以排查问题:

{
  "env": {
    "JUSTONEAPI_DEBUG": "true"
  }
}

调试模式下会输出所有 HTTP 请求详情(令牌已脱敏)。

相关资源

  • 官方文档:README.md
  • 工具参考:TOOLS.md
  • JustOneAPI 官网:https://justoneapi.com

资料来源:[package.json:28]()

配置管理

justoneapi-mcp 采用简洁而健壮的环境变量配置方案。配置管理系统负责验证必需参数、管理可选行为、确保敏感信息安全性,并在服务启动时进行完整性检查。资料来源:[README.md:108-120]()

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 必需配置

继续阅读本节完整说明和来源证据。

章节 可选配置

继续阅读本节完整说明和来源证据。

章节 Token 验证函数

继续阅读本节完整说明和来源证据。

概述

justoneapi-mcp 采用简洁而健壮的环境变量配置方案。配置管理系统负责验证必需参数、管理可选行为、确保敏感信息安全性,并在服务启动时进行完整性检查。资料来源:README.md:108-120

核心配置架构

配置系统围绕环境变量构建,遵循"约定优于配置"的设计原则。所有配置项通过 process.env 访问,核心 token 验证在服务初始化阶段强制执行。

graph TD
    A[服务启动] --> B[检查 JUSTONEAPI_TOKEN]
    B --> C{Token 是否存在且非空?}
    C -->|是| D[配置验证通过]
    C -->|否| E[输出错误信息并退出]
    D --> F[初始化 MCP Server]
    F --> G[注册工具集]
    E --> H[进程终止]
    
    I[运行时配置] --> J[HTTP 请求]
    J --> K[Token 注入]
    K --> L[URL 安全日志]
    
    D --> I

资料来源:src/index.ts:55-68

环境变量配置项

必需配置

配置变量类型说明
JUSTONEAPI_TOKENstringAPI 访问令牌,用于认证上游 JustOneAPI 服务

服务启动时,若 JUSTONEAPI_TOKEN 未设置或为空字符串,将输出错误信息并终止进程。资料来源:src/index.ts:55-68

// 启动验证逻辑
if (!process.env.JUSTONEAPI_TOKEN?.trim()) {
  console.error(
    "[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\n" +
      "Please set the JUSTONEAPI_TOKEN environment variable in your MCP host configuration"
  );
  process.exit(1);
}

可选配置

配置变量默认值类型说明
JUSTONEAPI_BASE_URLhttps://api.justoneapi.comstringAPI 端点地址
JUSTONEAPI_TIMEOUT_MS20000number请求超时时间(毫秒)
JUSTONEAPI_RETRY1number首次请求失败后的重试次数
JUSTONEAPI_DEBUGfalseboolean启用调试日志输出到 stderr

资料来源:README.md:114-119

Token 管理机制

Token 验证函数

requireToken() 函数封装了 token 的获取与验证逻辑,确保在所有需要认证的 API 调用前进行校验。资料来源:src/common/config.ts:1-20

export function requireToken(): string {
  const token = process.env.JUSTONEAPI_TOKEN;
  if (!token?.trim()) {
    throw new Error("JUSTONEAPI_TOKEN environment variable is not set or is empty");
  }
  return token;
}

Token 掩码处理

为防止敏感信息在日志中泄露,系统提供了 Token 掩码功能。对于长度为 12 位以内的 Token,保留首尾各 2 位字符,中间用 * 替换;超过 12 位的 Token 保留前 6 位和后 4 位。资料来源:src/common/config.ts:26-35

function maskToken(token: string): string {
  if (token.length <= 12) {
    return token.slice(0, 2) + "*".repeat(token.length - 4) + token.slice(-2);
  }
  return token.slice(0, 6) + "*".repeat(8) + token.slice(-4);
}

URL 安全日志

在 HTTP 请求处理过程中,敏感 Token 参数会被自动掩码处理后再输出日志,确保生产环境中不会泄露认证凭据。资料来源:src/common/config.ts:40-55

sequenceDiagram
    participant Client as 调用方
    participant HTTP as HTTP 模块
    participant Config as 配置模块
    participant Log as 日志输出
    
    Client->>HTTP: 发起 API 请求
    HTTP->>Config: 调用 toSafeUrlForLog()
    Config->>Config: 检测 URL 中的 token 参数
    Config->>Config: 执行 maskToken() 掩码
    Config-->>Log: 返回安全 URL
    HTTP-->>Client: 返回响应

HTTP 请求与配置联动

超时控制

超时时间通过 JUSTONEAPI_TIMEOUT_MS 配置控制,内部使用 AbortController 实现。超时错误会被映射为 NETWORK_TIMEOUT 错误码。资料来源:src/common/http.ts:35-45

重试机制

JUSTONEAPI_RETRY 配置指定初始请求失败后的重试次数。重试策略包含 250 毫秒的指数退避延迟。资料来源:src/common/http.ts:50-60

graph TD
    A[发送请求] --> B{成功?}
    B -->|是| C[返回结果]
    B -->|否| D{可重试错误?}
    D -->|AbortError| E[重试]
    D -->|5xx 错误| E
    D -->|ECONNRESET| E
    D -->|ECONNREFUSED| E
    D -->|ENOTFOUND| E
    D -->|否| F[抛出异常]
    E -->|attempt < retry| A
    E -->|attempt >= retry| F

重试条件判断逻辑:资料来源:src/common/http.ts:20-35

版本配置

版本信息从项目根目录的 package.json 动态读取,确保版本号与发布的包保持同步。若读取失败,默认回退至 0.0.0。资料来源:src/version.ts:1-22

错误处理与配置

配置相关的错误会被规范化为 MCP 错误码,提供可操作的错误信息和明确的错误来源。

错误码触发条件建议操作
INVALID_TOKENToken 无效或未激活更新 JUSTONEAPI_TOKEN
RATE_LIMITED请求频率超限减慢请求速度
DAILY_QUOTA_EXCEEDED日配额用尽等待次日或升级套餐
INSUFFICIENT_BALANCE账户余额不足充值账户
NETWORK_TIMEOUT请求超时检查网络或重试
NETWORK_ERROR网络连接失败检查网络连接

资料来源:src/common/errors.ts:25-65

配置验证流程

flowchart TD
    A[进程启动] --> B[加载环境变量]
    B --> C[验证 JUSTONEAPI_TOKEN]
    C --> D{验证结果}
    D -->|通过| E[初始化 Zod Schema]
    D -->|失败| K[输出错误并退出]
    E --> F[注册 MCP 工具]
    F --> G[启动服务监听]
    G --> H[等待请求]
    H --> I{收到请求}
    I -->|unified_search_v1| J1[执行统一搜索]
    I -->|kuaishou_search_video_v2| J2[执行快手搜索]
    J1 --> L[注入 token 并调用 API]
    J2 --> L
    L --> M[返回原始 JSON]

配置文件示例

Claude Desktop 配置

{
  "mcpServers": {
    "justoneapi": {
      "command": "npx",
      "args": ["-y", "justoneapi-mcp"],
      "env": {
        "JUSTONEAPI_TOKEN": "your_actual_token_here",
        "JUSTONEAPI_TIMEOUT_MS": "30000",
        "JUSTONEAPI_DEBUG": "true"
      }
    }
  }
}

资料来源:README.md:80-96

最佳实践

  1. Token 安全:始终通过环境变量传递 Token,避免硬编码在配置文件中
  2. 超时设置:根据网络环境调整 JUSTONEAPI_TIMEOUT_MS,默认 20 秒适合大多数场景
  3. 重试策略:在不稳定网络环境下可适当增加 JUSTONEAPI_RETRY
  4. 调试模式:生产环境应保持 JUSTONEAPI_DEBUGfalse,仅在排查问题时启用

资料来源:[src/index.ts:55-68]()

工具概览

JustOneAPI MCP(Model Context Protocol)是一个 MCP 服务器项目,旨在为 Claude Desktop、Cursor 等 MCP 主机提供对中国社交媒体和新闻平台的数据搜索能力。该项目采用"传输而非转换"(Transport, not transformation)的设计理念,优先保证数据的稳定性和原始性 资料来源:[README.md...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 2.1 整体架构

继续阅读本节完整说明和来源证据。

章节 2.2 请求处理流程

继续阅读本节完整说明和来源证据。

章节 3.1 当前版本工具

继续阅读本节完整说明和来源证据。

1. 概述

JustOneAPI MCP(Model Context Protocol)是一个 MCP 服务器项目,旨在为 Claude Desktop、Cursor 等 MCP 主机提供对中国社交媒体和新闻平台的数据搜索能力。该项目采用"传输而非转换"(Transport, not transformation)的设计理念,优先保证数据的稳定性和原始性 资料来源:README.md:1

工具(Tools)是 MCP 协议中的核心概念,每个工具代表一个可调用的功能单元。在 justoneapi-mcp 中,工具通过 @modelcontextprotocol/sdk 框架注册到 MCP 主机,用户可以通过自然语言或结构化参数调用这些工具 资料来源:src/index.ts:1-30

2. 架构设计

2.1 整体架构

graph TD
    subgraph MCP主机
        A[Claude Desktop / Cursor]
    end
    
    subgraph justoneapi-mcp
        B[工具注册层<br/>src/index.ts]
        C[工具实现层<br/>src/tools/]
        D[公共组件层<br/>src/common/]
    end
    
    subgraph 外部依赖
        E[JustOneAPI 服务端]
    end
    
    A -->|MCP 协议调用| B
    B --> C
    C --> D
    D -->|HTTP 请求| E
    
    style A fill:#e1f5fe
    style E fill:#fff3e0

2.2 请求处理流程

sequenceDiagram
    participant U as 用户
    participant M as MCP主机
    participant S as justoneapi-mcp
    participant A as JustOneAPI
    
    U->>M: 自然语言请求
    M->>S: 调用工具
    S->>S: 参数验证<br/>Zod Schema
    S->>A: HTTP GET请求
    A->>S: JSON响应
    S->>S: 错误映射
    S->>M: 结构化结果
    M->>U: 返回结果

3. 可用工具列表

3.1 当前版本工具

工具名称版本功能描述平台支持
unified_search_v1v1统一多平台搜索Weibo、WeChat、Zhihu、Douyin、Xiaohongshu、Bilibili、Kuaishou、News
kuaishou_search_video_v2v2快手视频搜索快手平台专用

资料来源:TOOLS.md:1-25

3.2 工具命名规范

所有工具遵循统一的命名约定:{platform}_{action}_{version} 资料来源:README.md:45-46

  • 平台前缀(platform):指定目标平台,如 kuaishouunified
  • 动作名称(action):表示操作类型,如 search_videosearch
  • 版本号(version):使用语义化版本,如 v1v2

4. 统一搜索工具(unified_search_v1)

4.1 工具描述

unified_search_v1 是该 MCP 服务器的核心工具,支持跨多个中国社交媒体和新闻平台进行联合搜索。用户可以通过单一请求同时查询微博、微信、知乎、抖音、小红书、B站、快手和新闻平台的数据 资料来源:src/index.ts:31-40

4.2 参数说明

参数名类型必填默认值描述
keywordstring-搜索关键词,支持高级语法
sourcestringALL平台筛选器
startstring条件必填-开始时间(UTC+8),格式:yyyy-MM-dd HH:mm:ss
endstring条件必填-结束时间(UTC+8),格式:yyyy-MM-dd HH:mm:ss
nextCursorstring-分页游标,用于获取后续页面

资料来源:src/tools/search/unified_search_v1.ts:15-42

4.3 平台选项

平台标识描述
ALL全部平台(默认)
NEWS新闻
WEIBO微博
WEIXIN微信
ZHIHU知乎
DOUYIN抖音
XIAOHONGSHU小红书
BILIBILIB站(哔哩哔哩)
KUAISHOU快手

资料来源:src/tools/search/unified_search_v1.ts:10-13

4.4 搜索语法

语法类型语法格式示例说明
单关键词keyworddeepseek搜索包含指定关键词的内容
AND 搜索word1 word2deepseek chatgpt同时包含两个关键词
OR 搜索word1~word2deepseek~chatgpt包含任一关键词
NOT 搜索word1 -word2deepseek -chatgpt包含前者,排除后者

资料来源:TOOLS.md:43-51

4.5 参数验证逻辑

graph TD
    A[输入参数] --> B{keyword 是否为空?}
    B -->|是| C[抛出错误]
    B -->|否| D{是否使用分页?}
    D -->|是 nextCursor| E[使用 nextCursor]
    D -->|否 首頁| F{start 和 end 都存在?}
    F -->|是| G[构建查询参数]
    F -->|否| H[抛出错误:需要 start 和 end]
    C --> I[返回 INVALID 请求]
    H --> I
    E --> J[构建查询参数<br/>含 nextCursor]
    G --> K[调用 getJson]
    J --> K

首次请求时,startend 参数必须提供,且时间范围不能超过 84 天。使用分页时,只需提供 nextCursor 即可 资料来源:src/tools/search/unified_search_v1.ts:30-37

5. 错误处理机制

5.1 错误码映射表

错误码描述用户操作建议
INVALID_TOKENToken 无效或未激活更新 JUSTONEAPI_TOKEN
COLLECT_FAILED数据采集失败稍后重试
RATE_LIMITED请求过于频繁降低请求频率,稍后重试
DAILY_QUOTA_EXCEEDED达到每日使用限额等待明天或升级套餐
INSUFFICIENT_BALANCE账户余额不足充值账户
PERMISSION_DENIED无权访问该资源联系技术支持
VALIDATION_ERROR请求参数无效检查输入值
INTERNAL_ERROR服务器内部错误稍后重试
NETWORK_TIMEOUT请求超时检查网络或重试
NETWORK_ERROR网络连接失败检查网络连接
UPSTREAM_ERROR上游服务未指明错误重试或联系支持

资料来源:README.md:88-108

5.2 错误格式

所有错误均以统一格式返回:

ERROR[ERROR_CODE] (upstream=XXX): Human-readable message

示例:

ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.

资料来源:src/common/errors.ts:1-30

5.3 错误处理流程

graph TD
    A[HTTP 响应] --> B{HTTP 状态码}
    B -->|200| C{业务 code}
    B -->|非 200| D[抛出 NETWORK_ERROR]
    C -->|0| E[返回成功响应]
    C -->|非 0| F[映射错误码]
    F --> G[构建 MCP 错误格式]
    D --> G
    E --> H[返回 JSON 数据]
    G --> I[返回错误信息]

错误映射逻辑会自动识别超时、HTTP 状态码、网络错误等不同类型的故障,并将其转换为用户友好的错误信息 资料来源:src/common/errors.ts:35-70

6. HTTP 请求机制

6.1 重试策略

graph TD
    A[请求发起] --> B{尝试次数 <= 最大重试次数?}
    B -->|是| C[发起 HTTP 请求]
    C --> D{请求成功?}
    D -->|是| E[返回响应]
    D -->|否| F{可重试错误?}
    F -->|是| G[等待 250ms * 尝试次数]
    F -->|否| H[抛出错误]
    G --> B
    B -->|否| H

可重试的错误类型包括:

  • 超时错误(AbortError
  • HTTP 5xx 错误
  • 网络连接重置(ECONNRESET
  • 连接被拒绝(ECONNREFUSED
  • DNS 解析失败(ENOTFOUND

资料来源:src/common/http.ts:1-45

6.2 超时配置

配置项默认值说明
JUSTONEAPI_TIMEOUT_MS20000ms单次请求超时时间

7. 认证与配置

7.1 环境变量配置

变量名必填默认值描述
JUSTONEAPI_TOKEN-JustOneAPI 访问令牌
JUSTONEAPI_BASE_URLhttps://api.justoneapi.comAPI 端点
JUSTONEAPI_TIMEOUT_MS20000请求超时(毫秒)
JUSTONEAPI_RETRY1首次失败后的重试次数
JUSTONEAPI_DEBUGfalse启用调试日志输出到 stderr

资料来源:README.md:119-130

7.2 Token 安全处理

系统内置 Token 脱敏功能,在日志输出时会自动将 Token 替换为掩码格式(显示前 4 位和后 4 位) 资料来源:src/common/config.ts:1-20

示例:

原始 Token: sk-abc123def456ghi789
日志显示:   sk-abc***ghi789

8. 分页机制

8.1 分页流程

当搜索结果存在多页时,响应中会包含 nextCursor 字段。用户可以通过以下方式继续获取更多结果:

  • "Show me the next page of results"
  • "Get more results from the previous search"
  • "Continue with the next page"
graph LR
    A[首页请求<br/>start + end] --> B[返回结果<br/>+ nextCursor]
    B --> C{需要更多结果?}
    C -->|是| D[下一页请求<br/>nextCursor]
    C -->|否| E[结束]
    D --> B

使用 nextCursor 分页时,无需再次提供 startendsource 参数,因为游标中已包含这些信息 资料来源:README.md:64-70

8.2 分页参数限制

  • 时间范围:首屏请求的时间跨度不能超过 84 天
  • 分页响应:每次返回 10-20 条结果

9. 快速入门

9.1 Claude Desktop 配置示例

{
  "mcpServers": {
    "justoneapi": {
      "command": "npx",
      "args": ["-y", "justoneapi-mcp"],
      "env": {
        "JUSTONEAPI_TOKEN": "your_actual_token_here"
      }
    }
  }
}

9.2 常用调用示例

跨平台搜索:

使用 unified_search_v1 工具搜索"AI",覆盖所有平台,时间范围为最近一个月。

单平台搜索:

搜索"chatgpt"相关内容,仅限微博平台,时间范围为2024年12月1日至2025年1月2日。

分页获取:

Show me more results

10. 输出格式

10.1 成功响应

{
  "code": 0,
  "message": null,
  "recordTime": "2025-12-31T14:55:21Z",
  "data": {
    // 平台特定数据结构
  }
}

10.2 错误响应

{
  "isError": true,
  "content": [
    {
      "type": "text",
      "text": "ERROR[ERROR_CODE] (upstream=XXX): Human-readable message"
    }
  ]
}

11. 项目依赖

依赖包版本用途
@modelcontextprotocol/sdk^1.25.1MCP 协议 SDK
zod^4.3.4参数验证与 Schema 定义
dotenv^17.2.3环境变量管理

资料来源:package.json:1-50

资料来源:[TOOLS.md:1-25]()

平台专用工具

平台专用工具(Platform-Specific Tools)是 justoneapi-mcp 项目中针对特定社交媒体平台提供深度搜索能力的功能模块。与统一搜索工具 unifiedsearchv1 不同,平台专用工具针对单个平台进行优化,提供更精细的参数控制和平台特定的功能实现。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 工具注册机制

继续阅读本节完整说明和来源证据。

章节 目录结构

继续阅读本节完整说明和来源证据。

章节 功能介绍

继续阅读本节完整说明和来源证据。

概述

平台专用工具(Platform-Specific Tools)是 justoneapi-mcp 项目中针对特定社交媒体平台提供深度搜索能力的功能模块。与统一搜索工具 unified_search_v1 不同,平台专用工具针对单个平台进行优化,提供更精细的参数控制和平台特定的功能实现。

当前已实现的平台专用工具包括:

工具名称平台版本功能描述
kuaishou_search_video_v2快手v2快手视频关键词搜索

资料来源:src/index.ts:9

架构设计

工具注册机制

平台专用工具通过 MCP SDK 的 registerTool 方法注册到服务器中。每个工具包含三个核心组成部分:工具名称、描述信息(含 Zod 输入验证 schema)和异步处理函数。

graph TD
    A[MCP 主机发送请求] --> B[服务器接收工具调用]
    B --> C[匹配工具名称]
    C --> D{找到对应工具?}
    D -->|是| E[执行异步处理函数]
    D -->|否| F[返回错误]
    E --> G[调用平台 API]
    G --> H{请求成功?}
    H -->|是| I[返回原始 JSON]
    H -->|否| J[错误处理]
    J --> K[转换为 MCP 错误格式]

资料来源:src/index.ts:18-40

目录结构

平台专用工具遵循统一的目录组织规范:

src/tools/
├── kuaishou/
│   └── search_video_v2.ts    # 快手视频搜索 v2
└── search/
    └── unified_search_v1.ts  # 统一搜索 v1

这种结构确保了代码的模块化组织和可维护性,每个平台拥有独立的子目录,便于后续扩展更多平台工具。

快手视频搜索工具

功能介绍

kuaishou_search_video_v2 是专门用于在快手平台搜索视频内容的工具。该工具通过快手开放 API 获取视频搜索结果,返回未经处理的原始 JSON 数据,确保数据完整性。

资料来源:src/tools/kuaishou/search_video_v2.ts:1-4

输入参数

参数名类型必填默认值说明
keywordstring-搜索关键词,如 "dance"
pagenumber1页码,必须为正整数

输入验证由 Zod 库提供支持,确保参数类型的正确性:

export const KuaishouSearchVideoV2Input = z.object({
  keyword: z.string().min(1).describe("Search keyword, e.g. 'dance'"),
  page: z.number().int().min(1).default(1).describe("Page number, default 1"),
});

资料来源:src/tools/kuaishou/search_video_v2.ts:6-9

API 请求构建

工具将输入参数转换为 URL 查询参数并调用内部 HTTP 模块:

export async function kuaishouSearchVideoV2(input: z.infer<typeof KuaishouSearchVideoV2Input>) {
  const token = encodeURIComponent(requireToken());
  const keyword = encodeURIComponent(input.keyword);
  const page = input.page;

  return await getJson(
    `/api/kuaishou/search-video/v2?token=${token}&keyword=${keyword}&page=${page}`
  );
}

请求流程:

  1. 从环境配置获取 API Token 并进行 URL 编码
  2. 对搜索关键词进行 URL 编码处理
  3. 构建完整的 API 端点 URL
  4. 调用 getJson 函数发起 HTTP GET 请求

资料来源:src/tools/kuaishou/search_video_v2.ts:11-18

工具注册流程

注册代码示例

在主入口文件中,工具通过标准化的注册流程添加到 MCP 服务器:

server.registerTool(
  "kuaishou_search_video_v2",
  {
    description:
      "Search Kuaishou videos by keyword. Returns the original raw JSON response from upstream without field normalization.",
    inputSchema: KuaishouSearchVideoV2Input.shape,
  },
  async (input) => {
    try {
      const data = await kuaishouSearchVideoV2(input);
      return {
        content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
      };
    } catch (e: unknown) {
      const m = toMcpErrorPayload(e);
      return {
        isError: true,
        content: [
          {
            type: "text",
            text: `ERROR[${m.code}] (upstream=${m.upstreamCode ?? "N/A"}): ${m.message}`,
          },
        ],
      };
    }
  }
);

资料来源:src/index.ts:18-40

注册参数说明

参数类型说明
工具名称stringMCP 协议中调用该工具的标识符,遵循 {platform}_{action}_{version} 命名规范
descriptionstring工具功能描述,供 MCP 主机(如 Claude Desktop)展示给用户
inputSchemaZodObject使用 Zod 库定义的输入验证模式,包含参数类型、默认值和描述
处理函数async function接收验证后的输入参数,执行工具逻辑并返回结果

错误处理机制

错误转换流程

平台专用工具使用统一的错误处理机制 toMcpErrorPayload 将各类错误转换为标准化的 MCP 错误格式:

graph TD
    A[异常发生] --> B{错误类型判断}
    B -->|AbortError| C[NETWORK_TIMEOUT]
    B -->|upstreamCode| D[业务错误码映射]
    B -->|httpStatus| E[UPSTREAM_ERROR]
    B -->|cause/code| F[NETWORK_ERROR]
    B -->|其他| G[UPSTREAM_ERROR]
    
    D --> H[返回 MCP 错误对象]
    C --> H
    E --> H
    F --> H
    G --> H
    
    H --> I[格式化错误消息]
    I --> J[ERROR[CODE] (upstream=X): message]

资料来源:src/common/errors.ts:30-60

错误码映射表

上游错误码MCP 错误码说明
100INVALID_TOKENToken 无效或已失效
301COLLECT_FAILED数据采集失败
302RATE_LIMITED请求频率超限
303DAILY_QUOTA_EXCEEDED每日配额已用尽
400VALIDATION_ERROR参数验证错误
500INTERNAL_ERROR服务器内部错误
600PERMISSION_DENIED无权限访问
601INSUFFICIENT_BALANCE账户余额不足

资料来源:src/common/errors.ts:68-85

底层支持模块

HTTP 请求模块

平台专用工具通过 getJson 函数发起 API 请求,该函数具备以下特性:

  • 自动重试机制:对超时、5xx 错误和网络连接错误进行自动重试
  • 可配置超时:支持通过 JUSTONEAPI_TIMEOUT_MS 环境变量配置请求超时时间,默认 20000ms
  • 请求重试次数:可通过 JUSTONEAPI_RETRY 环境变量配置,默认 1 次重试
  • Token 注入:自动将认证 Token 添加到请求头
const retryable =
  error.name === "AbortError" ||
  (typeof httpStatus === "number" && httpStatus >= 500) ||
  error.code === "ECONNRESET" ||
  error.code === "ECONNREFUSED" ||
  error.code === "ENOTFOUND";

资料来源:src/common/http.ts:20-30

配置管理模块

工具通过 requireToken 函数获取环境变量中配置的 API Token:

export function requireToken(): string {
  const token = process.env.JUSTONEAPI_TOKEN;
  if (!token?.trim()) {
    throw new Error("JUSTONEAPI_TOKEN is required");
  }
  return token;
}

资料来源:src/common/config.ts

工具命名规范

平台专用工具遵循统一的命名约定:

{platform}_{action}_{version}
组成部分说明示例
platform目标平台标识(小写)kuaishou、douyin、weibo
action操作类型search_video、get_user
versionAPI 版本号v1、v2

当前已实现的工具:

工具名称平台版本状态
kuaishou_search_video_v2快手v2✅ 已实现
unified_search_v1统一搜索v1✅ 已实现

资料来源:README.md

扩展指南

添加新平台工具的步骤

  1. 创建工具目录:在 src/tools/ 下创建平台专属目录
  2. 定义输入模式:使用 Zod 定义输入参数验证 schema
  3. 实现工具函数:调用 getJson 发起 API 请求
  4. 注册工具:在 src/index.ts 中使用 server.registerTool 注册
  5. 更新文档:在 README.md 和 TOOLS.md 中添加工具说明

依赖要求

项目使用以下核心依赖实现平台专用工具功能:

依赖包版本用途
@modelcontextprotocol/sdk^1.25.1MCP 服务器 SDK
zod^4.3.4输入参数验证
dotenv^17.2.3环境变量管理

资料来源:package.json:18-30

与统一搜索工具的对比

特性平台专用工具统一搜索工具
覆盖范围单平台多平台聚合
参数设计平台特定参数通用参数
使用场景深度平台分析跨平台概览
实现复杂度较高较低
扩展方式按平台添加通用扩展

资料来源:src/tools/search/unified_search_v1.ts

未来规划

根据项目规划,以下平台专用工具即将推出:

  • 抖音视频搜索
  • 微博帖子搜索
  • Bilibili 视频搜索
  • 微信内容搜索
  • 知乎内容搜索
  • 小红书内容搜索
  • 新闻聚合搜索

资料来源:TOOLS.md

资料来源:[src/index.ts:9]()

错误处理

justoneapi-mcp 采用统一的错误处理机制,将上游 API 的原始响应转换为标准化的 MCP 错误格式。该项目遵循"传输而非转换"(Transport, not transformation)的设计理念,在保持数据完整性的同时,为用户提供清晰、可操作的错误信息。 资料来源:README.md

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 JOAErrorCode 类型定义

继续阅读本节完整说明和来源证据。

章节 错误码对照表

继续阅读本节完整说明和来源证据。

章节 上游错误码到 MCP 错误码的转换

继续阅读本节完整说明和来源证据。

概述

justoneapi-mcp 采用统一的错误处理机制,将上游 API 的原始响应转换为标准化的 MCP 错误格式。该项目遵循"传输而非转换"(Transport, not transformation)的设计理念,在保持数据完整性的同时,为用户提供清晰、可操作的错误信息。 资料来源:README.md

错误处理模块位于 src/common/errors.ts,负责以下核心功能:

  • 定义标准化错误码体系(JOAErrorCode
  • 映射上游 API 错误码到 MCP 错误码
  • 构建用户友好的错误消息
  • 将各类异常转换为统一的 MCP 错误负载

错误码体系

JOAErrorCode 类型定义

项目定义了 11 种标准化错误码,涵盖认证失败、网络问题、配额限制等各种场景。 资料来源:src/common/errors.ts:58-69

export type JOAErrorCode =
  | "INVALID_TOKEN"
  | "COLLECT_FAILED"
  | "RATE_LIMITED"
  | "DAILY_QUOTA_EXCEEDED"
  | "VALIDATION_ERROR"
  | "INTERNAL_ERROR"
  | "PERMISSION_DENIED"
  | "INSUFFICIENT_BALANCE"
  | "NETWORK_TIMEOUT"
  | "NETWORK_ERROR"
  | "UPSTREAM_ERROR";

错误码对照表

错误码说明用户操作
INVALID_TOKENToken 无效或未激活更新 JUSTONEAPI_TOKEN
COLLECT_FAILED数据采集失败稍后重试
RATE_LIMITED请求频率超限降低请求频率后重试
DAILY_QUOTA_EXCEEDED达到每日用量限制明天重试或升级套餐
VALIDATION_ERROR请求参数无效检查输入值
INTERNAL_ERROR服务器内部错误稍后重试
PERMISSION_DENIED无权访问该资源联系客服
INSUFFICIENT_BALANCE账户余额不足充值账户
NETWORK_TIMEOUT请求超时检查网络或重试
NETWORK_ERROR网络连接失败检查网络连接
UPSTREAM_ERROR上游未指定错误重试或联系客服

资料来源:README.md

错误映射机制

上游错误码到 MCP 错误码的转换

mapUpstreamCode() 函数将上游 API 返回的数字错误码映射为标准化的 JOA 错误码。 资料来源:src/common/errors.ts:77-94

export function mapUpstreamCode(code: number | undefined): JOAErrorCode {
  switch (code) {
    case 100:
      return "INVALID_TOKEN";
    case 301:
      return "COLLECT_FAILED";
    case 302:
      return "RATE_LIMITED";
    case 303:
      return "DAILY_QUOTA_EXCEEDED";
    case 400:
      return "VALIDATION_ERROR";
    case 500:
      return "INTERNAL_ERROR";
    case 600:
      return "PERMISSION_DENIED";
    case 601:
      return "INSUFFICIENT_BALANCE";
    default:
      return "UPSTREAM_ERROR";
  }
}

映射关系图

graph LR
    A["上游错误码"] --> B{"code 值"}
    B -->|100| C["INVALID_TOKEN"]
    B -->|301| D["COLLECT_FAILED"]
    B -->|302| E["RATE_LIMITED"]
    B -->|303| F["DAILY_QUOTA_EXCEEDED"]
    B -->|400| G["VALIDATION_ERROR"]
    B -->|500| H["INTERNAL_ERROR"]
    B -->|600| I["PERMISSION_DENIED"]
    B -->|601| J["INSUFFICIENT_BALANCE"]
    B -->|其他| K["UPSTREAM_ERROR"]

用户消息构建

buildUserMessage 函数

buildUserMessage() 函数为每种错误码生成用户友好的错误消息。当上游返回消息时,优先使用上游消息;否则使用默认消息。 资料来源:src/common/errors.ts:96-128

export function buildUserMessage(mcpCode: JOAErrorCode, upstreamMessage?: string | null): string {
  const base = upstreamMessage && upstreamMessage.trim() ? upstreamMessage.trim() : undefined;

  switch (mcpCode) {
    case "INVALID_TOKEN":
      return base ?? "Invalid or inactive token. Please update JUSTONEAPI_TOKEN.";
    case "COLLECT_FAILED":
      return base ?? "Collection failed. Please retry after a short delay.";
    case "RATE_LIMITED":
      return base ?? "Rate limit exceeded. Please slow down and retry later.";
    case "DAILY_QUOTA_EXCEEDED":
      return base ?? "Daily quota exceeded. Please try again tomorrow or upgrade your plan.";
    case "VALIDATION_ERROR":
      return base ?? "Invalid parameters. Please check the input values.";
    case "PERMISSION_DENIED":
      return base ?? "Permission denied. Please verify your account permissions.";
    case "INSUFFICIENT_BALANCE":
      return base ?? "Insufficient balance. Please top up your account.";
    case "INTERNAL_ERROR":
      return base ?? "Internal server error. Please retry later.";
    case "NETWORK_TIMEOUT":
      return base ?? "Network timeout. Please retry later.";
    case "NETWORK_ERROR":
      return base ?? "Network error. Please retry later.";
    default:
      return base ?? "Upstream error. Please retry later.";
  }
}

错误转换

toMcpErrorPayload 函数

toMcpErrorPayload() 是核心错误转换函数,将各种类型的异常统一转换为 MCP 错误负载格式。 资料来源:src/common/errors.ts:130-173

export function toMcpErrorPayload(e: unknown): {
  code: JOAErrorCode;
  message: string;
  upstreamCode?: number;
  httpStatus?: number;
} {
  const error = e as {
    name?: string;
    message?: string;
    upstreamCode?: number;
    httpStatus?: number;
    code?: string;
    cause?: unknown;
  };

  // AbortController 超时
  if (error.name === "AbortError") {
    return { code: "NETWORK_TIMEOUT", message: buildUserMessage("NETWORK_TIMEOUT") };
  }

  // 业务错误码
  if (error.upstreamCode !== undefined) {
    const upstreamCode = Number(error.upstreamCode);
    const mcpCode = mapUpstreamCode(upstreamCode);
    return {
      code: mcpCode,
      message: buildUserMessage(mcpCode, error.message),
      upstreamCode,
      httpStatus: typeof error.httpStatus === "number" ? error.httpStatus : undefined,
    };
  }

  // HTTP 级别错误
  if (typeof error.httpStatus === "number") {
    return {
      code: "UPSTREAM_ERROR",
      message: error.message ?? `HTTP error ${error.httpStatus}`,
      httpStatus: error.httpStatus,
    };
  }

  // 网络连接错误
  if (error.cause || error.code === "ECONNREFUSED" || error.code === "ENOTFOUND") {
    return {
      code: "NETWORK_ERROR",
      message: error.message ?? buildUserMessage("NETWORK_ERROR"),
    };
  }

  return { code: "UPSTREAM_ERROR", message: error.message ?? "Unknown error" };
}

错误转换流程图

graph TD
    A["捕获异常 e"] --> B{"error.name === 'AbortError'?"}
    B -->|是| C["返回 NETWORK_TIMEOUT"]
    B -->|否| D{"error.upstreamCode !== undefined?"}
    D -->|是| E["mapUpstreamCode + buildUserMessage"]
    D -->|否| F{"typeof error.httpStatus === 'number'?"}
    F -->|是| G["返回 UPSTREAM_ERROR"]
    F -->|否| H{"error.cause || ECONNREFUSED || ENOTFOUND?"}
    H -->|是| I["返回 NETWORK_ERROR"]
    H -->|否| J["返回 UPSTREAM_ERROR + Unknown error"]

上游响应验证

isUpstreamOk 函数

用于判断上游 API 响应是否成功。 资料来源:src/common/errors.ts:71-75

export type UpstreamResponse = {
  code?: number;
  message?: string | null;
  recordTime?: string;
  data?: unknown;
};

export function isUpstreamOk(resp: UpstreamResponse): boolean {
  return Number(resp?.code) === 0;
}

UpstreamResponse 类型定义

字段类型说明
codenumber响应状态码,0 表示成功
messagestring \null响应消息
recordTimestring记录时间
dataunknown响应数据

资料来源:src/common/errors.ts:54-56

HTTP 请求重试机制

getJson 函数中的重试逻辑

src/common/http.ts 中的 getJson() 函数实现了智能重试机制,针对特定错误进行自动重试。 资料来源:src/common/http.ts

重试条件:

  • AbortError(超时)
  • HTTP 5xx 错误
  • ECONNRESET
  • ECONNREFUSED
  • ENOTFOUND
graph TD
    A["发起 HTTP 请求"] --> B{"请求成功?"}
    B -->|是| C["返回响应 JSON"]
    B -->|否| D{"可重试错误?"}
    D -->|否| E["抛出异常"]
    D -->|是| F{"尝试次数 < 最大次数?"}
    F -->|是| G["等待 250ms * attempt"]
    G --> H["重新发起请求"]
    H --> B
    F -->|否| E

MCP 工具中的错误处理

统一搜索工具示例

src/index.ts 中,所有工具都使用统一的错误处理模式: 资料来源:src/index.ts

async (input) => {
  try {
    const data = await unifiedSearchV1(input);
    return {
      content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
    };
  } catch (e: unknown) {
    const m = toMcpErrorPayload(e);
    return {
      isError: true,
      content: [
        {
          type: "text",
          text: `ERROR[${m.code}] (upstream=${m.upstreamCode ?? "N/A"}): ${m.message}`,
        },
      ],
    };
  }
}

错误输出格式

错误格式规范

所有错误按照统一格式返回:

ERROR[ERROR_CODE] (upstream=XXX): Human-readable message

示例

场景错误输出
Token 无效ERROR[INVALID_TOKEN] (upstream=100): Invalid or inactive token. Please update JUSTONEAPI_TOKEN.
频率限制ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.
网络超时ERROR[NETWORK_TIMEOUT] (upstream=N/A): Network timeout. Please retry later.

资料来源:README.md

MCP 工具返回格式

当工具调用出错时,返回包含 isError: true 的响应:

{
  "isError": true,
  "content": [
    {
      "type": "text",
      "text": "ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later."
    }
  ]
}

配置与环境变量

错误处理相关配置

变量默认值说明
JUSTONEAPI_TOKEN*(必填)*API 认证令牌
JUSTONEAPI_BASE_URLhttps://api.justoneapi.comAPI 端点
JUSTONEAPI_TIMEOUT_MS20000请求超时(毫秒)
JUSTONEAPI_RETRY1首次失败后的重试次数
JUSTONEAPI_DEBUGfalse启用调试日志输出到 stderr

资料来源:README.md

设计理念

Transport, not transformation

该项目坚持"传输而非转换"的设计哲学:

  • 返回上游 API 的原始 JSON 响应
  • 不进行字段解析或数据规范化
  • 不重构数据结构
  • 确保长期兼容性

错误处理模块在保持数据完整性的同时,提供了必要的错误信息翻译层,使用户能够快速定位和解决问题。 资料来源:README.md

相关文件

文件路径说明
src/common/errors.ts核心错误处理模块
src/common/http.tsHTTP 请求与重试机制
src/common/config.ts配置管理(含 URL 安全日志)
src/index.tsMCP 工具注册与错误处理集成
README.md错误处理文档
TOOLS.md工具文档中的错误处理说明

资料来源:[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)

认证授权

justoneapi-mcp 采用基于令牌(Token)的简洁认证机制。所有 API 请求必须携带有效的 JustOneAPI 令牌才能访问上游服务。该设计遵循 "Transport, not transformation" 原则,在令牌验证通过后直接透传请求,不进行额外的数据转换或协议转换。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 环境变量配置

继续阅读本节完整说明和来源证据。

章节 令牌获取

继续阅读本节完整说明和来源证据。

章节 requireToken 函数

继续阅读本节完整说明和来源证据。

概述

justoneapi-mcp 采用基于令牌(Token)的简洁认证机制。所有 API 请求必须携带有效的 JustOneAPI 令牌才能访问上游服务。该设计遵循 "Transport, not transformation" 原则,在令牌验证通过后直接透传请求,不进行额外的数据转换或协议转换。

认证流程的核心组件位于 src/common/config.ts 模块中,负责令牌的读取、验证和安全传输。

核心配置

环境变量配置

变量名必填默认值说明
JUSTONEAPI_TOKEN用户的 JustOneAPI 访问令牌
JUSTONEAPI_BASE_URLhttps://api.justoneapi.comAPI 端点地址
JUSTONEAPI_TIMEOUT_MS20000请求超时时间(毫秒)
JUSTONEAPI_RETRY1首次失败后的重试次数
JUSTONEAPI_DEBUGfalse是否启用调试日志输出

令牌获取

用户需访问 justoneapi.com 注册账号并获取 API 令牌。令牌将作为查询参数附加到每个 API 请求中。

认证流程

sequenceDiagram
    participant MCP as MCP Server
    participant Config as config.ts
    participant HTTP as http.ts
    participant API as JustOneAPI
    
    Note over MCP: 服务启动
    MCP->>Config: 读取 JUSTONEAPI_TOKEN
    alt Token 为空或空白
        Config-->>MCP: 抛出配置错误
        MCP->>MCP: 终止启动并输出错误信息
    end
    
    Note over MCP: 用户发起工具调用
    MCP->>Config: requireToken()
    Config->>Config: 验证令牌存在
    MCP->>HTTP: 构建请求(含令牌)
    HTTP->>API: GET /api/xxx?token=xxx
    API-->>HTTP: 响应 (code=0 或 code!=0)
    
    alt 认证失败
        API-->>HTTP: code != 0
        HTTP-->>MCP: 抛出 UpstreamError
        MCP-->>用户: ERROR[INVALID_TOKEN]
    end

令牌验证实现

requireToken 函数

src/common/config.ts 中实现了令牌验证函数:

export function requireToken(): string {
  const token = process.env.JUSTONEAPI_TOKEN?.trim();
  if (!token) {
    throw new Error(
      "[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\n" +
        "Please set the JUSTONEAPI_TOKEN environment variable in your MCP host configuration."
    );
  }
  return token;
}

资料来源:src/common/config.ts:1-50

启动时验证

服务启动时会在 src/index.ts 中进行强制验证:

async function main() {
  if (!process.env.JUSTONEAPI_TOKEN?.trim()) {
    console.error(
      "[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\n" +
        "Please set the JUSTONEAPI_TOKEN environment variable in your MCP host configuration"
    );
    process.exit(1);
  }
  // ... 继续初始化
}

资料来源:src/index.ts

令牌在请求中的传递

所有工具实现都遵循统一的令牌传递模式。以统一搜索为例:

export async function unifiedSearchV1(input: z.infer<typeof UnifiedSearchV1Input>) {
  const token = encodeURIComponent(requireToken());
  const keyword = encodeURIComponent(input.keyword);
  
  const params = new URLSearchParams();
  params.append("token", token);
  params.append("keyword", keyword);
  // ...
  
  return await getJson(`/api/search/v1?${params.toString()}`);
}

资料来源:src/tools/search/unified_search_v1.ts:30-50

令牌安全处理

URL 安全日志

为防止令牌在日志中泄露,系统提供了安全 URL 构建函数:

export function toSafeUrlForLog(fullUrl: string): string {
  try {
    const u = new URL(fullUrl);
    if (u.searchParams.has("token")) {
      u.searchParams.set("token", maskToken(u.searchParams.get("token") ?? ""));
    }
    return u.toString();
  } catch {
    return fullUrl.replace(/token=([^&]+)/g, (_m, g1) => `token=${maskToken(g1)}`);
  }
}

该函数会在调试模式下将日志输出中的令牌进行脱敏处理,仅保留首尾字符。

资料来源:src/common/config.ts:60-80

认证错误处理

错误码映射

src/common/errors.ts 负责将上游错误码映射为统一的 MCP 错误码:

上游错误码MCP 错误码说明用户操作
-INVALID_TOKEN令牌无效或未激活更新 JUSTONEAPI_TOKEN
302RATE_LIMITED请求过于频繁减缓请求频率
-INSUFFICIENT_BALANCE账户余额不足充值账户
-PERMISSION_DENIED无权访问该资源联系客服支持

资料来源:src/common/errors.ts:1-60

错误响应格式

认证错误以统一格式返回:

ERROR[INVALID_TOKEN] (upstream=N/A): Token is invalid or inactive. Please update your JUSTONEAPI_TOKEN environment variable.

请求重试与超时

重试机制

HTTP 客户端在以下情况会进行重试:

  • AbortError(请求超时)
  • HTTP 5xx 状态码
  • 网络错误(ECONNRESETECONNREFUSEDENOTFOUND

重试间隔采用指数退避策略:

// small backoff
await new Promise((r) => setTimeout(r, 250 * attempt));

资料来源:src/common/http.ts:40-80

超时配置

默认超时时间为 20 秒(20000 毫秒),可通过 JUSTONEAPI_TIMEOUT_MS 环境变量自定义。

MCP Host 配置示例

Claude Desktop 配置

{
  "mcpServers": {
    "justoneapi": {
      "command": "npx",
      "args": ["-y", "justoneapi-mcp"],
      "env": {
        "JUSTONEAPI_TOKEN": "your_actual_token_here"
      }
    }
  }
}

自定义配置

{
  "mcpServers": {
    "justoneapi": {
      "command": "npx",
      "args": ["-y", "justoneapi-mcp"],
      "env": {
        "JUSTONEAPI_TOKEN": "your_token_here",
        "JUSTONEAPI_TIMEOUT_MS": "30000",
        "JUSTONEAPI_DEBUG": "true"
      }
    }
  }
}

最佳实践

  1. 令牌安全:不要将令牌硬编码在代码中,使用环境变量传递
  2. 调试模式:生产环境建议关闭 JUSTONEAPI_DEBUG
  3. 超时设置:根据网络环境调整 JUSTONEAPI_TIMEOUT_MS
  4. 错误处理:捕获 INVALID_TOKEN 错误并提示用户更新令牌

资料来源:[src/common/config.ts:1-50]()

系统架构

justoneapi-mcp 是一个基于 Model Context Protocol (MCP) 的服务器实现,旨在为 AI 助手(如 Claude Desktop、Cursor 等)提供统一的中国社交媒体和新闻平台搜索能力。该项目采用"传输而非转换"(Transport, not transformation)的设计理念,直接返回上游 API 的原始 JSON 数据,确...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 1. 工具注册层 (src/index.ts)

继续阅读本节完整说明和来源证据。

章节 2. 配置管理 (src/common/config.ts)

继续阅读本节完整说明和来源证据。

章节 3. HTTP 客户端 (src/common/http.ts)

继续阅读本节完整说明和来源证据。

概述

justoneapi-mcp 是一个基于 Model Context Protocol (MCP) 的服务器实现,旨在为 AI 助手(如 Claude Desktop、Cursor 等)提供统一的中国社交媒体和新闻平台搜索能力。该项目采用"传输而非转换"(Transport, not transformation)的设计理念,直接返回上游 API 的原始 JSON 数据,确保最大程度的数据保真度。资料来源:README.md

架构分层

系统采用模块化分层架构,主要分为以下四层:

graph TD
    A[MCP Host<br/>Claude Desktop/Cursor] --> B[工具注册层<br/>src/index.ts]
    B --> C[业务逻辑层<br/>src/tools/]
    C --> D[公共基础设施层<br/>src/common/]
    D --> E[外部服务<br/>JustOneAPI]
    
    C --> C1[unified_search_v1]
    C --> C2[kuaishou_search_video_v2]
    
    D --> D1[config.ts<br/>配置管理]
    D --> D2[http.ts<br/>HTTP客户端]
    D --> D3[errors.ts<br/>错误处理]
层级文件路径职责
工具注册层src/index.tsMCP 工具注册、请求路由、错误格式化
业务逻辑层src/tools/各个工具的具体实现(搜索、视频等)
公共基础设施层src/common/配置管理、HTTP 请求、错误处理
外部服务层JustOneAPI第三方数据源 API

资料来源:src/index.ts:1-80

核心组件

1. 工具注册层 (src/index.ts)

作为 MCP 服务器的入口点,负责:

  • 初始化 MCP SDK 服务器实例
  • 注册所有可用工具及其输入 schema
  • 统一处理工具执行中的异常
  • 格式化错误响应为 MCP 错误格式
sequenceDiagram
    participant Host as MCP Host
    participant Server as MCP Server
    participant Tool as Tool Handler
    participant API as JustOneAPI
    
    Host->>Server: 工具调用请求
    Server->>Tool: 传递输入参数
    Tool->>API: HTTP 请求
    API-->>Tool: JSON 响应
    Tool-->>Server: 返回数据
    Server-->>Host: MCP 响应格式
    
    Note over Tool,API: 异常时返回错误格式
    Tool-->>Server: ERROR[CODE]: message
    Server-->>Host: isError: true

关键代码结构:

// 工具注册示例
server.registerTool(
  "unified_search_v1",
  {
    description: "Unified search across multiple platforms...",
    inputSchema: UnifiedSearchV1Input.shape,
  },
  async (input) => {
    try {
      const data = await unifiedSearchV1(input);
      return {
        content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
      };
    } catch (e: unknown) {
      const m = toMcpErrorPayload(e);
      return {
        isError: true,
        content: [{
          type: "text",
          text: `ERROR[${m.code}] (upstream=${m.upstreamCode ?? "N/A"}): ${m.message}`,
        }],
      };
    }
  }
);

资料来源:src/index.ts:40-65

2. 配置管理 (src/common/config.ts)

负责管理和验证环境变量配置:

配置项必填默认值说明
JUSTONEAPI_TOKEN-API 访问令牌
JUSTONEAPI_BASE_URLhttps://api.justoneapi.comAPI 端点
JUSTONEAPI_TIMEOUT_MS20000请求超时(毫秒)
JUSTONEAPI_RETRY1首次尝试后的重试次数
JUSTONEAPI_DEBUGfalse启用调试日志

配置验证在服务器启动时执行:

async function main() {
  if (!process.env.JUSTONEAPI_TOKEN?.trim()) {
    console.error(
      "[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\n" +
      "Please set the JUSTONEAPI_TOKEN environment variable..."
    );
    process.exit(1);
  }
  // ...
}

资料来源:src/common/config.ts:1-30src/index.ts:75-85

3. HTTP 客户端 (src/common/http.ts)

封装 HTTP 请求逻辑,提供重试机制:

graph TD
    A[发起请求] --> B{attempt < attempts?}
    B -->|是| C[发送 HTTP 请求]
    C --> D{响应状态?}
    D -->|成功 2xx| E[返回 JSON]
    D -->|超时/5xx/网络错误| F[等待 backoff]
    F --> G[attempt++]
    G --> B
    D -->|其他错误| H[立即抛出异常]
    B -->|否| I[抛出最后一次错误]

可重试的错误类型

错误类型条件
超时error.name === "AbortError"
HTTP 5xxhttpStatus >= 500
连接重置error.code === "ECONNRESET"
连接被拒绝error.code === "ECONNREFUSED"
主机未找到error.code === "ENOTFOUND"

重试策略:指数退避,每次重试间隔 250 * attempt 毫秒。

资料来源:src/common/http.ts:1-60

4. 错误处理 (src/common/errors.ts)

统一错误码映射和用户友好消息生成:

graph TD
    A[原始错误] --> B{错误类型判断}
    B -->|AbortError| C[NETWORK_TIMEOUT]
    B -->|upstreamCode| D[mapUpstreamCode]
    B -->|httpStatus| E[UPSTREAM_ERROR]
    B -->|cause/code| F[NETWORK_ERROR]
    B -->|其他| G[UPSTREAM_ERROR]
    
    D --> H[错误码映射表]
    H --> H1[INVALID_TOKEN<br/>302]
    H --> H2[COLLECT_FAILED<br/>500]
    H --> H3[RATE_LIMITED<br/>429]
    H --> H4[DAILY_QUOTA_EXCEEDED<br/>403]
    H --> H5[INSUFFICIENT_BALANCE<br/>402]
    H --> H6[PERMISSION_DENIED<br/>401]
    H --> H7[VALIDATION_ERROR<br/>400]

MCP 错误码对照表

MCP 错误码说明上游响应码用户操作建议
INVALID_TOKENToken 无效或未激活302更新 JUSTONEAPI_TOKEN
COLLECT_FAILED数据采集失败500稍后重试
RATE_LIMITED请求过于频繁429降低请求频率
DAILY_QUOTA_EXCEEDED达到日用量限额403等待明天或升级套餐
INSUFFICIENT_BALANCE账户余额不足402充值账户
PERMISSION_DENIED无权访问该资源401联系客服
VALIDATION_ERROR请求参数无效400检查输入值
INTERNAL_ERROR服务器内部错误其他 5xx稍后重试
NETWORK_TIMEOUT请求超时-检查网络或重试
NETWORK_ERROR网络连接失败-检查网络连接
UPSTREAM_ERROR未指定的上游错误-重试或联系客服

错误输出格式

ERROR[ERROR_CODE] (upstream=XXX): Human-readable message

资料来源:src/common/errors.ts:1-80

工具实现

统一搜索 (unified_search_v1)

支持跨多个平台进行搜索,返回统一的 JSON 响应:

graph LR
    A[keyword] --> B[参数构建]
    B --> C{分页?}
    C -->|首页| D[start, end]
    C -->|后续页| E[nextCursor]
    D --> F[URLSearchParams]
    E --> F
    F --> G[/api/search/v1]
    G --> H[getJson]

输入参数 Schema

参数类型必填说明
keywordstring搜索关键词,支持 AND/OR/NOT 语法
sourceenum平台筛选:ALL(默认)、NEWSWEIBOWEIXINZHIHUDOUYINXIAOHONGSHUBILIBILIKUAISHOU
startstring首页必填开始时间 yyyy-MM-dd HH:mm:ss(UTC+8),需在 84 天内
endstring首页必填结束时间,需晚于开始时间
nextCursorstring分页用上一页返回的游标

搜索语法

  • 单关键词:deepseek
  • AND 搜索(同时包含):deepseek chatgpt
  • OR 搜索(任一包含):deepseek~chatgpt
  • NOT 搜索(排除):deepseek -chatgpt

资料来源:src/tools/search/unified_search_v1.ts:1-60

快手视频搜索 (kuaishou_search_video_v2)

针对快手平台的专用视频搜索工具:

参数类型必填默认值说明
keywordstring-搜索关键词,如 'dance'
pagenumber1页码,从 1 开始

资料来源:src/tools/kuaishou/search_video_v2.ts:1-25

数据流

sequenceDiagram
    participant User as 用户
    participant MCP as MCP Host
    participant Server as justoneapi-mcp
    participant HTTP as HTTP Client
    participant API as JustOneAPI
    
    User->>MCP: 自然语言搜索请求
    MCP->>Server: unified_search_v1(keyword, source, start, end)
    
    Server->>HTTP: getJson(url)
    HTTP->>HTTP: Token 编码
    HTTP->>HTTP: 参数序列化
    
    HTTP->>API: GET /api/search/v1?...
    API-->>HTTP: JSON 响应
    
    HTTP-->>Server: 原始 JSON 数据
    Server-->>MCP: { content: [{type:"text", text: JSON}] }
    MCP-->>User: 搜索结果摘要
    
    Note over API: code=0 表示成功<br/>code≠0 表示错误

依赖关系

项目依赖项及其版本:

依赖类型包名版本要求用途
生产依赖@modelcontextprotocol/sdk^1.25.1MCP 协议实现
生产依赖zod^4.3.4输入验证和 Schema 定义
生产依赖dotenv^17.2.3环境变量管理
开发依赖typescript^5.9.3TypeScript 编译
开发依赖eslint^9.39.2代码检查
开发依赖prettier^3.7.4代码格式化

运行环境要求:Node.js >= 18.0.0

资料来源:package.json:1-50

启动验证流程

graph TD
    A[服务器启动] --> B{检查 JUSTONEAPI_TOKEN}
    B -->|未设置| C[输出错误信息]
    C --> D[进程退出]
    B -->|已设置| E[服务器就绪]
    E --> F[注册所有工具]
    F --> G[等待 MCP Host 调用]
    G --> H{收到工具调用}
    H -->|unified_search_v1| I[执行统一搜索]
    H -->|kuaishou_search_video_v2| J[执行快手搜索]
    I --> K[返回结果或错误]
    J --> K

设计原则

  1. 传输而非转换:直接返回上游 API 的原始响应,不进行字段解析或数据重组,确保长期兼容性。
  2. 透明性:错误信息包含上游错误码,便于调试和问题定位。
  3. 稳定性:通过 HTTP 重试机制和超时控制提高系统可靠性。
  4. 模块化:各功能模块职责清晰,便于维护和扩展。

扩展性

项目采用插件化架构添加新工具:

  1. src/tools/ 下创建新的工具目录
  2. 定义 Zod 输入 Schema
  3. 实现工具逻辑函数
  4. src/index.ts 中注册工具

即将支持的工具:

  • Douyin 视频搜索
  • Weibo 帖子搜索
  • Bilibili 视频搜索

资料来源:[src/index.ts:1-80]()

开发指南

本开发指南旨在帮助开发者快速上手 justoneapi-mcp 项目的开发工作,涵盖项目结构、环境配置、代码规范、工具开发以及构建发布等核心内容。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 目录职责说明

继续阅读本节完整说明和来源证据。

章节 运行时要求

继续阅读本节完整说明和来源证据。

章节 必需环境变量

继续阅读本节完整说明和来源证据。

项目概述

justoneapi-mcp 是一个基于 Model Context Protocol (MCP) 的服务器实现,用于连接 Claude 等 AI 助手与中国主流社交媒体平台的数据搜索接口。该项目支持统一搜索、快手视频搜索等多个工具,为用户提供跨平台社交媒体数据分析能力。

核心设计理念:Transport, not transformation — 即优先保证数据传输的稳定性、透明性和原始数据完整性,而非对数据进行转换或处理。

资料来源:README.md

项目结构

justoneapi-mcp/
├── src/
│   ├── index.ts              # MCP 服务器主入口
│   ├── version.ts            # 版本管理模块
│   ├── common/
│   │   ├── config.ts         # 配置管理
│   │   ├── errors.ts         # 错误处理
│   │   └── http.ts           # HTTP 请求封装
│   └── tools/
│       ├── search/
│       │   └── unified_search_v1.ts  # 统一搜索工具
│       └── kuaishou/
│           └── search_video_v2.ts     # 快手视频搜索工具
├── eslint.config.js          # ESLint 配置
├── tsconfig.json             # TypeScript 配置
├── package.json              # 项目依赖配置
└── README.md                 # 项目文档

目录职责说明

目录/文件职责关键依赖
src/index.tsMCP 服务器启动、工具注册、错误处理@modelcontextprotocol/sdk
src/common/公共基础设施模块zod, dotenv
src/tools/具体业务工具实现继承 common 模块

资料来源:src/index.ts:1-50

环境配置

运行时要求

项目要求 Node.js 版本不低于 18.0.0。

资料来源:package.json:22

必需环境变量

变量名必填默认值说明
JUSTONEAPI_TOKENJustOneAPI 访问令牌
JUSTONEAPI_BASE_URLhttps://api.justoneapi.comAPI 端点地址
JUSTONEAPI_TIMEOUT_MS20000请求超时时间(毫秒)
JUSTONEAPI_RETRY1首次请求后的重试次数
JUSTONEAPI_DEBUGfalse是否启用调试日志

资料来源:README.md

配置验证机制

项目在启动时(src/index.tsmain() 函数)会验证 JUSTONEAPI_TOKEN 是否已设置。若未设置,服务器将输出错误信息并终止运行:

if (!process.env.JUSTONEAPI_TOKEN?.trim()) {
  console.error(
    "[justoneapi-mcp] ERROR: JUSTONEAPI_TOKEN is required but not set.\n" +
      "Please set the JUSTONEAPI_TOKEN environment variable..."
  );
  process.exit(1);
}

资料来源:src/index.ts

开发工具配置

TypeScript 配置

项目使用 TypeScript 5.9.3,编译配置位于 tsconfig.json。关键配置项包括:

  • target: ES2022
  • module: ESNext (ES 模块系统)
  • moduleResolution: bundler
  • strict mode: 启用严格类型检查

资料来源:package.json:29-31

ESLint 配置

ESLint 配置集成了 TypeScript ESLint 插件和 Prettier 配置:

rules: {
  ...tseslint.configs.recommended.rules,
  "@typescript-eslint/no-explicit-any": "warn",
  "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
  "no-console": ["warn", { allow: ["error", "warn"] }],
}

规则说明:

规则级别说明
no-explicit-anywarn允许使用 any 类型但会警告
no-unused-varserror未使用的变量报错,下划线开头的参数除外
no-consolewarn禁止使用 console.log,允许 error 和 warn

资料来源:eslint.config.js

项目依赖

生产依赖:

依赖包版本用途
@modelcontextprotocol/sdk^1.25.1MCP 协议实现
dotenv^17.2.3环境变量加载
zod^4.3.4输入验证与 Schema 定义

开发依赖:

依赖包版本用途
typescript^5.9.3TypeScript 编译器
eslint^9.39.2代码检查
prettier^3.7.4代码格式化
ts-node^10.9.2TypeScript 执行环境

资料来源:package.json:24-45

工具开发

工具注册流程

MCP 服务器通过 server.registerTool() 方法注册工具。注册时需提供工具名称、描述和输入 Schema:

server.registerTool(
  "tool_name_v1",
  {
    description: "工具描述字符串",
    inputSchema: ToolInputSchema.shape,
  },
  async (input) => {
    // 工具实现逻辑
    return {
      content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
    };
  }
);

资料来源:src/index.ts

工具命名规范

项目采用统一的工具命名规范:{platform}_{action}_{version}

示例含义
unified_search_v1统一搜索工具,第一版本
kuaishou_search_video_v2快手平台视频搜索,第二版本

资料来源:README.md

输入验证

项目使用 Zod v4 进行输入验证。每个工具需要定义 InputSchema

import { z } from "zod";

export const UnifiedSearchV1Input = z.object({
  keyword: z.string().min(1).describe("搜索关键词"),
  source: PlatformType.optional().describe("平台来源"),
  start: z.string().optional().describe("开始时间"),
  end: z.string().optional().describe("结束时间"),
  nextCursor: z.string().optional().describe("分页游标"),
});

Zod Schema 特性说明:

方法用途
z.string().min(1)非空字符串验证
.optional()可选字段
.default(value)默认值
.describe("...")字段描述(用于 MCP 文档生成)

资料来源:src/tools/search/unified_search_v1.ts

工具实现模板

import { z } from "zod";
import { requireToken } from "../../common/config.js";
import { getJson } from "../../common/http.js";

// 1. 定义输入 Schema
export const ToolInput = z.object({
  param1: z.string().min(1).describe("参数描述"),
  param2: z.number().int().min(1).default(1).describe("可选参数"),
});

// 2. 实现工具函数
export async function toolFunction(input: z.infer<typeof ToolInput>) {
  const token = encodeURIComponent(requireToken());
  const param = encodeURIComponent(input.param1);
  const page = input.param2;

  return await getJson(
    `/api/path?token=${token}&param=${param}&page=${page}`
  );
}

资料来源:src/tools/kuaishou/search_video_v2.ts

HTTP 请求封装

请求重试机制

getJson() 函数封装了带重试逻辑的 HTTP 请求:

graph TD
    A[发起请求] --> B{成功?}
    B -->|是| C[返回响应]
    B -->|否| D{可重试?}
    D -->|超时/5xx/网络错误| E[等待 250ms × attempt]
    E --> F[重试]
    F --> A
    D -->|不可重试| G[抛出异常]
    G --> H[错误处理]
    C --> H

可重试条件:

条件说明
AbortError请求超时
HTTP 5xx服务器内部错误
ECONNRESET连接被重置
ECONNREFUSED连接被拒绝
ENOTFOUNDDNS 解析失败

资料来源:src/common/http.ts

错误处理机制

错误代码映射

项目定义了一套标准化的 MCP 错误代码:

错误代码上游代码说明处理建议
INVALID_TOKEN-Token 无效或未激活更新 JUSTONEAPI_TOKEN
COLLECT_FAILED-数据采集失败稍后重试
RATE_LIMITED302请求过于频繁降低请求频率
DAILY_QUOTA_EXCEEDED-达到日配额限制等待明天或升级套餐
INSUFFICIENT_BALANCE-账户余额不足充值账户
PERMISSION_DENIED-无权访问该资源联系支持
VALIDATION_ERROR-请求参数无效检查输入值
INTERNAL_ERROR-服务器内部错误稍后重试
NETWORK_TIMEOUT-请求超时检查网络或重试
NETWORK_ERROR-网络连接失败检查网络连接
UPSTREAM_ERROR-未指定的上游错误重试或联系支持

错误格式

错误以以下格式返回:

ERROR[ERROR_CODE] (upstream=XXX): Human-readable message

错误处理流程

graph TD
    A[捕获异常] --> B{AbortError?}
    B -->|是| C[返回 NETWORK_TIMEOUT]
    B -->|否| D{upstreamCode 存在?}
    D -->|是| E[映射上游错误码]
    E --> F[返回业务错误]
    D -->|否| G{httpStatus 存在?}
    G -->|是| H[返回 UPSTREAM_ERROR]
    G -->|否| I{网络错误?}
    I -->|是| J[返回 NETWORK_ERROR]
    I -->|否| K[返回 UPSTREAM_ERROR]

资料来源:src/common/errors.ts

版本管理

项目使用动态版本读取机制,从 package.json 中提取版本号:

const packageJsonPath = join(__dirname, "../package.json");
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
version = packageJson.version || "0.0.0";

此设计确保构建产物中的版本号与 package.json 保持同步。

资料来源:src/version.ts

构建和发布

安装依赖

npm install

代码检查

npm run lint      # ESLint 检查
npm run format    # Prettier 格式化

构建

npm run build     # TypeScript 编译到 dist/

发布配置

package.json 中的发布文件配置:

{
  "files": ["dist", "README.md", "LICENSE"]
}

dist 目录(编译产物)、README.mdLICENSE 会被发布到 npm。

资料来源:package.json:19-22

Claude Desktop 集成

配置示例

在 Claude Desktop 配置文件中添加以下内容:

{
  "mcpServers": {
    "justoneapi": {
      "command": "npx",
      "args": ["-y", "justoneapi-mcp"],
      "env": {
        "JUSTONEAPI_TOKEN": "your_token_here",
        "JUSTONEAPI_TIMEOUT_MS": "30000",
        "JUSTONEAPI_DEBUG": "true"
      }
    }
  }
}

配置文件位置

操作系统路径
macOS~/Library/Application Support/Claude/claude_desktop_config.json
Windows%APPDATA%\Claude\claude_desktop_config.json
Linux~/.config/Claude/claude_desktop_config.json

资料来源:README.md

开发工作流程

graph LR
    A[创建工具文件] --> B[定义 Zod Schema]
    B --> C[实现工具函数]
    C --> D[注册工具到服务器]
    D --> E[配置环境变量]
    E --> F[本地测试]
    F --> G[代码检查]
    G --> H{通过?}
    H -->|否| I[修复问题]
    I --> G
    H -->|是| J[构建发布]
    J --> K[end]

常见问题

Token 配置问题

问题: 服务器启动时报错 JUSTONEAPI_TOKEN is required but not set

解决: 确保在 MCP host 配置中正确设置了 JUSTONEAPI_TOKEN 环境变量

请求超时

问题: 请求返回 NETWORK_TIMEOUT

解决: 增加 JUSTONEAPI_TIMEOUT_MS 配置值(默认 20000ms)

调试模式

启用调试模式可查看详细的请求日志:

{
  "env": {
    "JUSTONEAPI_DEBUG": "true"
  }
}

资料来源:src/common/config.ts

资料来源:[README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)

失败模式与踩坑日记

保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

medium 能力判断依赖假设

假设不成立时,用户拿不到承诺的能力。

medium 来源证据:Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of…

可能增加新用户试用和生产接入成本。

medium 维护活跃度未知

新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。

medium 下游验证发现风险项

下游已经要求复核,不能在页面中弱化。

Pitfall Log / 踩坑日志

项目:justoneapi/justoneapi-mcp

摘要:发现 7 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:能力坑 - 能力判断依赖假设。

1. 能力坑 · 能力判断依赖假设

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:README/documentation is current enough for a first validation pass.
  • 对用户的影响:假设不成立时,用户拿不到承诺的能力。
  • 建议检查:将假设转成下游验证清单。
  • 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
  • 证据:capability.assumptions | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | README/documentation is current enough for a first validation pass.

2. 运行坑 · 来源证据:Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of…

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个运行相关的待验证问题:Clawhub skill family: 6 SKILL.md files have description-vs-body operation count mismatches (claim vs documented gap of 2-39)
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_3b8110f2a2a84250a1da5b96b5573463 | https://github.com/justoneapi/justoneapi-mcp/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。

3. 维护坑 · 维护活跃度未知

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:未记录 last_activity_observed。
  • 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
  • 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
  • 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
  • 证据:evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | last_activity_observed missing

4. 安全/权限坑 · 下游验证发现风险项

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:下游已经要求复核,不能在页面中弱化。
  • 建议检查:进入安全/权限治理复核队列。
  • 防护动作:下游风险存在时必须保持 review/recommendation 降级。
  • 证据:downstream_validation.risk_items | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium

5. 安全/权限坑 · 存在评分风险

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:风险会影响是否适合普通用户安装。
  • 建议检查:把风险写入边界卡,并确认是否需要人工复核。
  • 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
  • 证据:risks.scoring_risks | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | no_demo; severity=medium

6. 维护坑 · issue/PR 响应质量未知

  • 严重度:low
  • 证据强度:source_linked
  • 发现:issue_or_pr_quality=unknown。
  • 对用户的影响:用户无法判断遇到问题后是否有人维护。
  • 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
  • 防护动作:issue/PR 响应未知时,必须提示维护风险。
  • 证据:evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | issue_or_pr_quality=unknown

7. 维护坑 · 发布节奏不明确

  • 严重度:low
  • 证据强度:source_linked
  • 发现:release_recency=unknown。
  • 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
  • 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
  • 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
  • 证据:evidence.maintainer_signals | github_repo:1125683257 | https://github.com/justoneapi/justoneapi-mcp | release_recency=unknown

来源:Doramagic 发现、验证与编译记录