# https://github.com/justoneapi/justoneapi-mcp 项目说明书

生成时间：2026-05-15 07:48:52 UTC

## 目录

- [Getting Started with JustOneAPI MCP](#getting-started)
- [Authentication](#authentication)
- [System Architecture](#system-architecture)
- [HTTP Client Implementation](#http-client)
- [Unified Search Tool](#unified-search-tool)
- [Kuaishou Video Search Tool](#kuaishou-video-search)
- [Tool Naming Conventions and Standards](#tool-conventions)
- [Configuration Reference](#configuration-reference)
- [MCP Host Integration](#mcp-integration)
- [Error Handling](#error-handling)

<a id='getting-started'></a>

## Getting Started with JustOneAPI MCP

### 相关页面

相关主题：[Authentication](#authentication), [MCP Host Integration](#mcp-integration)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)
- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)
- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)
- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)
- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)
- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)
- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)
</details>

# Getting Started with JustOneAPI MCP

## Overview

JustOneAPI MCP Server is a Model Context Protocol (MCP) server that exposes JustOneAPI endpoints to AI assistants like Claude Desktop, Cursor, and other MCP-compatible hosts. The server acts as a thin transport layer that handles authentication, retries, timeouts, and error normalization while returning raw JSON responses from upstream platforms.

**Key Characteristics:**

- Returns unmodified upstream JSON responses for maximum data fidelity
- No field parsing or schema normalization
- Designed for AI agents and developer workflows
- Supports multiple Chinese social media and news platforms

资料来源：[README.md:1-20]()

## Architecture

### System Components

```mermaid
graph TD
    A[MCP Host<br/>Claude Desktop/Cursor] --> B[JustOneAPI MCP Server]
    B --> C[JustOneAPI REST API]
    C --> D[Upstream Platforms]
    
    D --> E[Weibo]
    D --> F[WeChat]
    D --> G[Zhihu]
    D --> H[Douyin]
    D --> I[Xiaohongshu]
    D --> J[Bilibili]
    D --> K[Kuaishou]
    D --> L[News]
    
    B --> M[Authentication]
    B --> N[Retry Logic]
    B --> O[Error Normalization]
```

### Technology Stack

| Component | Technology | Version |
|-----------|------------|---------|
| Runtime | Node.js | >= 18.0.0 |
| MCP SDK | @modelcontextprotocol/sdk | ^1.25.1 |
| Validation | Zod | ^4.3.4 |
| Environment | dotenv | ^17.2.3 |
| Language | TypeScript | ^5.9.3 |

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

## Prerequisites

Before using JustOneAPI MCP, ensure you have:

1. **Node.js 18.0.0 or higher** installed
2. **JustOneAPI Token** obtained from [justoneapi.com](https://dashboard.justoneapi.com/en/login)
3. **MCP-compatible host** (Claude Desktop, Cursor, or other)

## Installation

### Option 1: npx (Recommended)

The simplest method requires no installation. Configure your MCP host to run the package directly via npx.

资料来源：[README.md:85-95]()

### Option 2: Local Installation

For production environments, install the package locally:

```bash
npm install -g justoneapi-mcp
```

## Configuration

### Claude Desktop Configuration

Edit the configuration file for your operating system:

| OS | Configuration Path |
|----|---------------------|
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
| Linux | `~/.config/Claude/claude_desktop_config.json` |

**Configuration Example:**

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

资料来源：[README.md:85-102]()

### Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `JUSTONEAPI_TOKEN` | Yes | - | Your JustOneAPI authentication token |
| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint URL |
| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |
| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after first attempt |
| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |

资料来源：[README.md:138-147]()

## Available Tools

### Tool Naming Convention

All tools follow the pattern: `{platform}_{action}_{version}`

### Current Tools

| Tool | Description | Version |
|------|-------------|---------|
| `unified_search_v1` | Unified search across multiple platforms | v1 |
| `kuaishou_search_video_v2` | Platform-specific video search | v2 |

资料来源：[README.md:55-58]()

## Using the Unified Search

### Featured Tool: unified_search_v1

Search across multiple Chinese social media and news platforms in a single request.

**Supported Platforms:**

- Weibo
- WeChat
- Zhihu
- Douyin
- Xiaohongshu
- Bilibili
- Kuaishou
- News (aggregated)

资料来源：[README.md:36-37]()

### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `keyword` | string | Yes | Search keyword with advanced syntax |
| `source` | string | No | Platform filter (default: `ALL`) |
| `start` | string | First page only | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8) |
| `end` | string | First page only | End time `yyyy-MM-dd HH:mm:ss` (UTC+8) |
| `nextCursor` | string | Pagination only | Cursor from previous response |

资料来源：[TOOLS.md:21-28]()

### Search Syntax

```mermaid
graph LR
    A[Search Input] --> B{Syntax Type}
    B --> C[Single: deepseek]
    B --> D[AND: deepseek chatgpt]
    B --> E[OR: deepseek~chatgpt]
    B --> F[NOT: deepseek -chatgpt]
```

| Syntax | Example | Description |
|--------|---------|-------------|
| Single keyword | `deepseek` | Simple search |
| AND search | `deepseek chatgpt` | Both keywords must appear |
| OR search | `deepseek~chatgpt` | Either keyword can appear |
| NOT search | `deepseek -chatgpt` | Exclude keyword |

资料来源：[README.md:48-55]()

### Platform Options

| Value | Description |
|-------|-------------|
| `ALL` | Search all platforms (default) |
| `NEWS` | News articles only |
| `WEIBO` | Weibo posts |
| `WEIXIN` | WeChat public accounts |
| `ZHIHU` | Zhihu Q&A |
| `DOUYIN` | Douyin videos |
| `XIAOHONGSHU` | Xiaohongshu posts |
| `BILIBILI` | Bilibili videos |
| `KUAISHOU` | Kuaishou videos |

资料来源：[src/tools/search/unified_search_v1.ts:12-19]()

## Usage Examples

### Natural Language Queries

Simply ask your MCP host to perform searches:

```
Search for "AI" discussions on Chinese social media from last week
```

```
Find posts about deepseek on Weibo from January 1st to 5th
```

```
Search for chatgpt OR 机器学习 on all platforms, exclude 广告
```

### Code-Level Usage

**First Page Request:**

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

**Pagination Request:**

```json
{
  "keyword": "AI",
  "nextCursor": "eyJsYXN0SWQiOiIxMjM0NTY3ODkwIn0="
}
```

资料来源：[README.md:40-46]()

## Response Format

All tools return raw JSON from upstream APIs without modification.

### Success Response

```json
{
  "code": 0,
  "message": null,
  "recordTime": "2025-12-31T14:55:21Z",
  "data": {
    // Platform-specific data structure
  }
}
```

| Field | Type | Description |
|-------|------|-------------|
| `code` | integer | 0 indicates success, non-zero indicates error |
| `message` | string/null | Error message if applicable |
| `recordTime` | string | ISO timestamp of the response |
| `data` | object | Platform-specific payload |

### Error Response

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

资料来源：[README.md:60-75]()

## Error Handling

The MCP normalizes all errors into stable MCP error codes.

### Error Codes Reference

| Error Code | Description | Recommended Action |
|------------|-------------|-------------------|
| `INVALID_TOKEN` | Token is invalid or inactive | Update `JUSTONEAPI_TOKEN` |
| `COLLECT_FAILED` | Data collection failed | Retry after a short delay |
| `RATE_LIMITED` | Too many requests | Slow down and retry later |
| `DAILY_QUOTA_EXCEEDED` | Daily usage limit reached | Wait until tomorrow or upgrade plan |
| `INSUFFICIENT_BALANCE` | Account balance too low | Top up your account |
| `PERMISSION_DENIED` | No access to this resource | Contact support |
| `VALIDATION_ERROR` | Invalid request parameters | Check input values |
| `INTERNAL_ERROR` | Server error | Retry later |
| `NETWORK_TIMEOUT` | Request timed out | Check network or retry |
| `NETWORK_ERROR` | Network connection failed | Check internet connection |
| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |

资料来源：[README.md:109-130]()

### Error Format Example

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

资料来源：[README.md:132-134]()

## Pagination

When search results have more pages, responses include a `nextCursor` field.

### How to Paginate

Simply ask for more results:

- "Show me the next page of results"
- "Get more results from the previous search"
- "Continue with the next page"

The MCP host automatically:

1. Extracts the `nextCursor` from the previous response
2. Uses it to fetch the next page
3. Continues until no more results are available

**Note:** When using `nextCursor` for pagination, you don't need to provide `start`, `end`, or `source` again—the cursor already contains this information.

资料来源：[README.md:76-95]()

## Design Philosophy

### Transport, Not Transformation

JustOneAPI MCP prioritizes:

- **Stability** — Minimal abstraction over upstream APIs
- **Transparency** — Raw data fidelity without modification
- **Compatibility** — Long-term compatibility through unchanged responses

### What This MCP Does

- Exposes JustOneAPI endpoints as MCP tools
- Handles authentication, retries, timeouts, and error normalization
- Returns raw upstream JSON without field parsing
- Designed for AI agents and developer workflows

### What This MCP Does NOT Do

- No field parsing or schema normalization
- No data restructuring
- No assumptions about upstream response structure

资料来源：[README.md:10-24]()

## Advanced Configuration

### Complete Configuration Example

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

### Retry Behavior

The HTTP client implements automatic retry for:

- Timeout errors (AbortError)
- HTTP 5xx responses
- Network failures (ECONNRESET, ECONNREFUSED, ENOTFOUND)

| Attempt | Delay |
|---------|-------|
| 1 | Immediate |
| 2 | 250ms backoff |
| 3+ | 250ms × attempt |

资料来源：[src/common/http.ts:30-40]()

## Discovery and Verification

### Listing Available Tools

**In Claude Desktop:**

```
Please list all available tools from justoneapi-mcp
```

**In Cursor or other MCP hosts:**

Use your host's tool discovery feature to see all available tools and their parameters.

Each tool includes:
- Complete parameter descriptions
- Input validation with Zod schemas
- Detailed error messages
- Example values in parameter descriptions

资料来源：[README.md:30-38]()

## Next Steps

After setup:

1. **Obtain an API token** from [justoneapi.com](https://dashboard.justoneapi.com/en/login)
2. **Configure your MCP host** with the token
3. **Try the unified search** with a simple query
4. **Explore pagination** for large result sets
5. **Review error codes** for troubleshooting

## License

MIT License

资料来源：[README.md:152]()

## External Resources

- [JustOneAPI Dashboard](https://dashboard.justoneapi.com/en/login)
- [JustOneAPI Official Site](https://justoneapi.com)
- [npm Package](https://www.npmjs.com/package/justoneapi-mcp)
- [GitHub Repository](https://github.com/justoneapi/justoneapi-mcp)

---

<a id='authentication'></a>

## Authentication

### 相关页面

相关主题：[Getting Started with JustOneAPI MCP](#getting-started), [Configuration Reference](#configuration-reference)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)
- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)
- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)
- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)
- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)
- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)
</details>

# Authentication

## Overview

The justoneapi-mcp server implements a token-based authentication mechanism for securing API access to the JustOneAPI platform. All requests to upstream APIs are authenticated using a bearer-style token passed via query parameters. The authentication system performs early validation at startup and before each API call to ensure credentials are present and properly configured.

The authentication layer serves as the gatekeeper for all MCP tools, including `unified_search_v1` and `kuaishou_search_video_v2`. It validates the token's presence, encodes it safely for transmission, and provides clear error messages when authentication fails.

## Architecture

```mermaid
graph TD
    A[MCP Host Request] --> B{Token Present?}
    B -->|No| C[Startup Validation<br/>src/index.ts:45-52]
    B -->|Yes| D[requireToken Call]
    
    D --> E{Token Valid?}
    E -->|Empty/Whitespace| F[INVALID_TOKEN Error]
    E -->|Valid| G[Encode Token]
    
    G --> H[Append to Query Params]
    H --> I[HTTP Request via getJson]
    
    I --> J{Response Code = 0?}
    J -->|Yes| K[Return Data]
    J -->|No| L[Error Mapping<br/>src/common/errors.ts]
    
    style F fill:#ffcccc
    style K fill:#ccffcc
```

## Configuration

### Environment Variables

Authentication is configured through environment variables in the MCP server configuration.

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `JUSTONEAPI_TOKEN` | Yes | — | Your JustOneAPI authentication token |
| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint base URL |
| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |
| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after initial attempt |
| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |

### Token Configuration File

The token configuration is managed in `src/common/config.ts`.

```typescript
// src/common/config.ts:1-15
export function requireToken(): string {
  const token = process.env.JUSTONEAPI_TOKEN;
  if (!token || !token.trim()) {
    throw new Error(
      "JUSTONEAPI_TOKEN environment variable is required. " +
        "Get your token at https://justoneapi.com"
    );
  }
  return token;
}
```

The `requireToken()` function validates that the token exists and is not empty or whitespace-only. If validation fails, it throws an error with instructions for obtaining a token. 资料来源：[src/common/config.ts:1-15]()

### Startup Validation

The server performs authentication validation during startup to fail fast if credentials are missing.

```typescript
// src/index.ts:45-52
async function main() {
  // Validate configuration on startup
  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);
  }
  // ... continue with server initialization
}
```

资料来源：[src/index.ts:45-52]()

## Token Transmission

### Query Parameter Encoding

Tokens are transmitted via URL query parameters for all API requests. The token is URL-encoded to handle special characters safely.

```typescript
// src/tools/search/unified_search_v1.ts:35-36
export async function unifiedSearchV1(input: z.infer<typeof UnifiedSearchV1Input>) {
  const token = encodeURIComponent(requireToken());
  const keyword = encodeURIComponent(input.keyword);
  
  // Build query parameters
  const params = new URLSearchParams();
  params.append("token", token);
  params.append("keyword", keyword);
  // ...
}
```

资料来源：[src/tools/search/unified_search_v1.ts:35-36]()

### HTTP Request Flow

All authenticated requests flow through the `getJson()` helper in `src/common/http.ts`.

```mermaid
sequenceDiagram
    participant MCP as MCP Host
    participant Server as justoneapi-mcp
    participant API as JustOneAPI
    
    MCP->>Server: Tool Request
    Server->>Server: requireToken()
    Note over Server: Validate token exists
    Server->>Server: getJson(pathWithQuery)
    Server->>API: GET with token in query
    API-->>Server: JSON Response
    Server->>Server: Check response.code
    alt code != 0
        Server->>Server: toMcpErrorPayload()
    end
    Server-->>MCP: Result or Error
```

The `getJson()` function includes the following security and reliability features:

| Feature | Implementation | Purpose |
|---------|---------------|---------|
| Early token validation | `requireToken()` at start | Fail fast on missing credentials |
| Timeout handling | `AbortController` | Prevent hanging requests |
| Automatic retry | Configurable via `JUSTONEAPI_RETRY` | Handle transient failures |
| Safe logging | `toSafeUrlForLog()` | Mask tokens in debug output |

```typescript
// src/common/http.ts:40-55
export async function getJson(pathWithQuery: string): Promise<UpstreamResponse> {
  // ensure token exists early (so we can return INVALID_TOKEN)
  requireToken();

  const url = `${config.baseUrl}${pathWithQuery}`;

  const attempts = 1 + Math.max(0, Number.isFinite(config.retry) ? config.retry : 0);
  let lastErr: ApiError | unknown;

  for (let attempt = 1; attempt <= attempts; attempt++) {
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), config.timeoutMs);
    // ...
  }
}
```

资料来源：[src/common/http.ts:40-55]()

## Error Handling

### Token-Related Error Codes

When authentication fails, the server returns normalized MCP error codes.

| Error Code | Upstream Equivalent | Description | Resolution |
|------------|---------------------|-------------|------------|
| `INVALID_TOKEN` | — | Token missing or invalid | Update `JUSTONEAPI_TOKEN` |
| `RATE_LIMITED` | 302 | Too many requests | Slow down and retry |
| `DAILY_QUOTA_EXCEEDED` | — | Usage limit reached | Wait or upgrade plan |
| `INSUFFICIENT_BALANCE` | — | Account balance low | Top up account |

### Error Mapping

The `mapUpstreamCode()` function in `src/common/errors.ts` maps upstream error codes to MCP error codes.

```typescript
// src/common/errors.ts:1-30
function mapUpstreamCode(code: number): JOAErrorCode {
  switch (code) {
    case 10001:
      return "INVALID_TOKEN";
    case 10002:
      return "INSUFFICIENT_BALANCE";
    case 10003:
      return "PERMISSION_DENIED";
    // ... other mappings
    default:
      return "UPSTREAM_ERROR";
  }
}
```

资料来源：[src/common/errors.ts:1-30]()

### Error Payload Construction

```typescript
// src/common/errors.ts:60-75
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;
  };
  
  // Timeout from AbortController
  if (error.name === "AbortError") {
    return { code: "NETWORK_TIMEOUT", message: buildUserMessage("NETWORK_TIMEOUT") };
  }

  // Our own thrown upstreamCode (business code)
  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,
    };
  }
  // ...
}
```

资料来源：[src/common/errors.ts:60-75]()

### Error Response Format

All errors are returned in a standardized format:

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

Example error responses:

| Scenario | Response Format |
|----------|-----------------|
| Invalid token | `ERROR[INVALID_TOKEN] (upstream=N/A): Token is invalid or inactive. Update your JUSTONEAPI_TOKEN` |
| Rate limited | `ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.` |
| Network timeout | `ERROR[NETWORK_TIMEOUT] (upstream=N/A): Request timed out. Check network or retry.` |

## Security Considerations

### Token Masking in Logs

Debug logging masks tokens to prevent accidental exposure.

```typescript
// src/common/config.ts:50-65
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 {
    // Fallback: best-effort masking
    return fullUrl.replace(/token=([^&]+)/g, (_m, g1) => `token=${maskToken(g1)}`);
  }
}
```

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

### Retry Behavior with Tokens

Retry logic applies only to transient failures, not authentication errors:

```typescript
// src/common/http.ts:70-80
const retryable =
  error.name === "AbortError" ||
  (typeof httpStatus === "number" && httpStatus >= 500) ||
  error.code === "ECONNRESET" ||
  error.code === "ECONNREFUSED" ||
  error.code === "ENOTFOUND";
```

| Retryable | Not Retryable |
|-----------|---------------|
| Timeout (`AbortError`) | HTTP 4xx errors |
| HTTP 5xx errors | Business code != 0 |
| Network reset | Invalid token |

## Configuration Examples

### Claude Desktop Configuration

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

### Custom Timeout and Debug Settings

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

When debug mode is enabled, logs appear with masked tokens:

```
[justoneapi] GET https://api.justoneapi.com/api/search/v1?token=sk_***&keyword=AI (attempt 1/2)
```

## Obtaining a Token

1. Visit [https://justoneapi.com](https://justoneapi.com)
2. Create an account or sign in at [https://dashboard.justoneapi.com](https://dashboard.justoneapi.com/en/login)
3. Generate an API token from your dashboard
4. Configure the token in your MCP host

## Related Documentation

- [README.md](README.md) — Installation and quick start guide
- [TOOLS.md](TOOLS.md) — Complete tool reference with authentication parameters

---

<a id='system-architecture'></a>

## System Architecture

### 相关页面

相关主题：[HTTP Client Implementation](#http-client), [Unified Search Tool](#unified-search-tool), [Kuaishou Video Search Tool](#kuaishou-video-search)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)
- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)
- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)
- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)
- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)
- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)
- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)
</details>

# System Architecture

## Overview

The justoneapi-mcp is a Model Context Protocol (MCP) server that provides a bridge between AI assistants and the JustOneAPI social media search platform. The system enables natural language querying across multiple Chinese social media platforms including Weibo, WeChat, Zhihu, Douyin, Xiaohongshu, Bilibili, Kuaishou, and news sources.

The architecture follows a **transport-oriented design philosophy**, prioritizing stability, transparency, and raw data fidelity over convenience. The MCP server returns unmodified upstream API responses to ensure maximum data fidelity and long-term compatibility.

## High-Level Architecture

```mermaid
graph TD
    subgraph "MCP Host Environment"
        A[MCP Client<br/>Claude Desktop/Cursor]
    end
    
    subgraph "justoneapi-mcp Server"
        B[MCP SDK Server]
        C[Tool Handlers]
        D[Common Libraries]
        E[HTTP Client]
    end
    
    subgraph "External Services"
        F[JustOneAPI<br/>api.justoneapi.com]
        G[Chinese Social Media<br/>Platforms]
    end
    
    A -->|MCP Protocol| B
    B --> C
    C --> D
    D --> E
    E -->|HTTPS| F
    F -->|API Responses| G
    
    style A fill:#e1f5fe
    style F fill:#fff3e0
    style G fill:#f3e5f5
```

## Core Components

### Component Overview

| Component | File Location | Purpose |
|-----------|---------------|---------|
| MCP Server | `src/index.ts` | Entry point, tool registration, request routing |
| Tool Handlers | `src/tools/*` | Individual tool implementations |
| HTTP Client | `src/common/http.ts` | HTTP request management with retry logic |
| Configuration | `src/common/config.ts` | Token management, URL sanitization |
| Error Handling | `src/common/errors.ts` | Error code mapping and payload transformation |

### Module Dependency Graph

```mermaid
graph LR
    subgraph "Entry Point"
        A[src/index.ts]
    end
    
    subgraph "Tool Layer"
        B[unified_search_v1.ts]
        C[kuaishou_search_video_v2.ts]
    end
    
    subgraph "Common Layer"
        D[config.ts]
        E[http.ts]
        F[errors.ts]
    end
    
    subgraph "External"
        G[JustOneAPI]
    end
    
    A --> B
    A --> C
    B --> D
    B --> E
    B --> F
    C --> D
    C --> E
    C --> F
    E --> F
    E --> G
    
    style A fill:#ffecb3
    style D fill:#c8e6c9
    style E fill:#c8e6c9
    style F fill:#c8e6c9
    style G fill:#fff3e0
```

## Tool Registration System

### Request Flow

```mermaid
sequenceDiagram
    participant Client as MCP Client
    participant Server as MCP Server
    participant Handler as Tool Handler
    participant HTTP as HTTP Client
    participant API as JustOneAPI
    
    Client->>Server: Tool Request (unified_search_v1)
    Server->>Handler: Forward Input
    Handler->>Handler: Validate with Zod Schema
    Handler->>HTTP: GET /api/search/v1
    HTTP->>HTTP: Token encoding
    HTTP->>API: Request with token
    API-->>HTTP: JSON Response
    HTTP-->>Handler: Raw JSON
    Handler-->>Server: JSON Response
    Server-->>Client: MCP Response
```

### Tool Registration Pattern

Tools are registered in `src/index.ts` using the MCP SDK's `registerTool` method. Each tool registration includes:

1. **Tool name** - Unique identifier following `{platform}_{action}_{version}` pattern
2. **Input schema** - Zod schema for parameter validation
3. **Handler function** - Async function that processes requests

```typescript
// Registration pattern from src/index.ts:55-72
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}]: ${m.message}` }],
      };
    }
  }
);
```

## HTTP Client Architecture

### Retry Strategy

The HTTP client in `src/common/http.ts` implements an intelligent retry mechanism with exponential backoff.

```mermaid
graph TD
    A[Request] --> B{Attempt < Max?}
    B -->|Yes| C{Check Retryable?}
    C -->|AbortError| D[Retry]
    C -->|HTTP 5xx| D
    C -->|ECONNRESET| D
    C -->|ECONNREFUSED| D
    C -->|ENOTFOUND| D
    C -->|No| E[Throw Error]
    D --> F[Wait 250ms × Attempt]
    F --> G[Retry Request]
    G --> B
    B -->|No| H[Throw Last Error]
    
    style E fill:#ffcdd2
    style H fill:#ffcdd2
    style D fill:#c8e6c9
```

### Retryable Conditions

| Condition | Type | Retry Behavior |
|-----------|------|----------------|
| `AbortError` | Timeout | ✅ Retry |
| HTTP 5xx | Server Error | ✅ Retry |
| `ECONNRESET` | Connection Reset | ✅ Retry |
| `ECONNREFUSED` | Connection Refused | ✅ Retry |
| `ENOTFOUND` | DNS Lookup Failed | ✅ Retry |
| HTTP 4xx | Client Error | ❌ No Retry |
| Business Errors | API Code | ❌ No Retry |

资料来源：[src/common/http.ts:29-36]()

## Error Handling System

### Error Flow

```mermaid
graph TD
    A[Exception Thrown] --> B{Error Type?}
    B -->|AbortError| C[NETWORK_TIMEOUT]
    B -->|upstreamCode exists| D[Map Upstream Code]
    B -->|httpStatus exists| E[UPSTREAM_ERROR]
    B -->|cause or network code| F[NETWORK_ERROR]
    B -->|Unknown| G[UPSTREAM_ERROR]
    
    D --> H[Return MCP Error Payload]
    C --> H
    E --> H
    F --> H
    G --> H
    
    style C fill:#fff9c4
    style D fill:#fff9c4
    style E fill:#fff9c4
    style F fill:#fff9c4
```

### Error Code Mapping

| MCP Error Code | Upstream Code | Description | User Action |
|----------------|---------------|-------------|-------------|
| `INVALID_TOKEN` | N/A | Token invalid/inactive | Update `JUSTONEAPI_TOKEN` |
| `COLLECT_FAILED` | N/A | Data collection failed | Retry after delay |
| `RATE_LIMITED` | 302 | Too many requests | Slow down, retry later |
| `DAILY_QUOTA_EXCEEDED` | N/A | Daily limit reached | Wait until tomorrow |
| `INSUFFICIENT_BALANCE` | N/A | Low account balance | Top up account |
| `PERMISSION_DENIED` | N/A | No access to resource | Contact support |
| `VALIDATION_ERROR` | N/A | Invalid parameters | Check input values |
| `INTERNAL_ERROR` | N/A | Server error | Retry later |
| `NETWORK_TIMEOUT` | N/A | Request timed out | Check network |
| `NETWORK_ERROR` | N/A | Connection failed | Check internet |
| `UPSTREAM_ERROR` | N/A | Unspecified upstream | Retry or contact support |

## Configuration Management

### Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `JUSTONEAPI_TOKEN` | ✅ Yes | - | API authentication token |
| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint base URL |
| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |
| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after first attempt |
| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |

### Token Management

The `requireToken()` function in `src/common/config.ts` validates and retrieves the API token:

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

### URL Sanitization for Logging

The `toSafeUrlForLog()` function masks sensitive tokens in URLs before logging:

```mermaid
graph LR
    A[Full URL with token] --> B[Parse URL]
    B --> C{Token param exists?}
    C -->|Yes| D[Mask token value]
    C -->|No| E[Return original]
    D --> F[Return sanitized URL]
    E --> F
```

## Tool Specifications

### Available Tools

| Tool Name | Purpose | Version |
|-----------|---------|---------|
| `unified_search_v1` | Multi-platform social media search | v1 |
| `kuaishou_search_video_v2` | Kuaishou-specific video search | v2 |

### Platform Support

The unified search supports the following platforms:

| Platform | Identifier | Type |
|----------|------------|------|
| All Platforms | `ALL` | Default |
| News | `NEWS` | News content |
| Weibo | `WEIBO` | Social posts |
| WeChat | `WEIXIN` | Articles |
| Zhihu | `ZHIHU` | Q&A content |
| Douyin | `DOUYIN` | Short videos |
| Xiaohongshu | `XIAOHONGSHU` | Lifestyle content |
| Bilibili | `BILIBILI` | Long-form videos |
| Kuaishou | `KUAISHOU` | Short videos |

### Search Syntax Support

| Operator | Syntax | Description |
|----------|--------|-------------|
| Single keyword | `deepseek` | Basic search |
| AND search | `deepseek chatgpt` | Both keywords required |
| OR search | `deepseek~chatgpt` | Either keyword matches |
| NOT search | `deepseek -chatgpt` | Exclude keyword |

## Data Flow Architecture

### Unified Search Flow

```mermaid
sequenceDiagram
    participant User
    participant Handler as unified_search_v1
    participant HTTP as getJson
    participant API as JustOneAPI
    
    User->>Handler: {keyword, source, start, end}
    Handler->>Handler: Encode parameters
    Handler->>HTTP: GET /api/search/v1?token=...&keyword=...
    HTTP->>API: HTTPS Request
    API-->>HTTP: {code, message, data, nextCursor}
    HTTP-->>Handler: Raw JSON response
    Handler-->>User: JSON with raw data
    
    Note over User,API: Raw upstream data returned unchanged
```

## Technology Stack

### Production Dependencies

| Package | Version | Purpose |
|---------|---------|---------|
| `@modelcontextprotocol/sdk` | ^1.25.1 | MCP protocol implementation |
| `zod` | ^4.3.4 | Schema validation |
| `dotenv` | ^17.2.3 | Environment variable loading |

### Development Dependencies

| Package | Version | Purpose |
|---------|---------|---------|
| `typescript` | ^5.9.3 | Type safety |
| `eslint` | ^9.39.2 | Code linting |
| `prettier` | ^3.7.4 | Code formatting |
| `ts-node` | ^10.9.2 | TypeScript execution |

### Node.js Requirement

- **Minimum version**: Node.js 18.0.0
- **Runtime**: ES2022+ module system

## Startup and Initialization

### Configuration Validation

On server startup, the main function validates that required configuration exists:

```mermaid
graph TD
    A[Server Start] --> B{JUSTONEAPI_TOKEN set?}
    B -->|No| C[Exit with Error]
    B -->|Yes| D[Start MCP Server]
    D --> E[Register Tools]
    E --> F[Listen for Requests]
    
    style C fill:#ffcdd2
    style F fill:#c8e6c9
```

The token validation occurs in `src/index.ts` before the MCP server begins accepting connections, ensuring early failure with clear error messages.

## Design Philosophy

The architecture embodies the **"Transport, not transformation"** principle:

1. **Maximum Data Fidelity** - Raw upstream responses are returned unmodified
2. **No Field Parsing** - Data structures remain as received from upstream APIs
3. **No Data Restructuring** - No normalization or transformation of response formats
4. **Long-term Compatibility** - Stable interface despite upstream API changes

---

<a id='http-client'></a>

## HTTP Client Implementation

### 相关页面

相关主题：[System Architecture](#system-architecture), [Error Handling](#error-handling), [Configuration Reference](#configuration-reference)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)
- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)
- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)
- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)
- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)
</details>

# HTTP Client Implementation

## Overview

The HTTP Client Implementation provides a centralized, reusable HTTP communication layer for the JustOneAPI MCP server. It handles all outbound API requests with built-in retry logic, timeout management, error normalization, and secure logging. The implementation follows a "transport, not transformation" philosophy, returning raw upstream responses to maintain maximum data fidelity.

**Key Responsibilities:**
- Execute HTTP GET requests to the JustOneAPI backend
- Manage request timeouts using AbortController
- Implement automatic retry with exponential backoff for transient failures
- Normalize errors into structured MCP error codes
- Ensure secure logging by masking sensitive tokens

资料来源：[src/common/http.ts:48-68]()

## Architecture

```mermaid
graph TD
    A[Tool Handler] --> B[API Function<br/>e.g., unifiedSearchV1]
    B --> C[getJson]
    C --> D{Token Validation}
    D -->|Invalid| E[INVALID_TOKEN Error]
    D -->|Valid| F[Build URL]
    F --> G[Fetch with Timeout]
    G --> H{Response OK?}
    H -->|No| I[Retry Logic]
    I --> G
    H -->|Yes| J[Parse JSON]
    J --> K[Business Code OK?]
    K -->|No| L[Error Mapping]
    K -->|Yes| M[Return Response]
    L --> N[MCP Error Payload]
    
    style E fill:#ff6b6b
    style N fill:#ffa500
    style M fill:#51cf66
```

### Request Flow

1. **Token Validation** - Ensures `JUSTONEAPI_TOKEN` exists before making requests 资料来源：[src/common/http.ts:60]() [src/common/config.ts]()

2. **URL Construction** - Builds full URL with base URL and query parameters 资料来源：[src/common/http.ts:62]()

3. **Fetch Execution** - Makes HTTP request with AbortController timeout 资料来源：[src/common/http.ts:70-76]()

4. **Response Processing** - Validates HTTP status and parses JSON 资料来源：[src/common/http.ts:78-88]()

5. **Business Logic Check** - Validates upstream `code === 0` for success 资料来源：[src/common/errors.ts:1-18]()

## Core Components

### ApiError Type

The `ApiError` interface extends the standard `Error` type with additional properties for HTTP-level and business-level error information.

| Property | Type | Description |
|----------|------|-------------|
| `httpStatus` | `number \| undefined` | HTTP status code from the fetch response |
| `upstreamCode` | `number \| undefined` | Business error code from upstream API response |
| `payload` | `unknown \| undefined` | Full response payload when available |
| `code` | `string \| undefined` | Node.js error code for network errors |
| `cause` | `unknown \| undefined` | Underlying error cause |

资料来源：[src/common/http.ts:39-45]()

### getJson Function

The main HTTP client function that performs GET requests with comprehensive error handling.

```typescript
export async function getJson(pathWithQuery: string): Promise<UpstreamResponse>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `pathWithQuery` | `string` | API endpoint path including query string |

**Returns:** `Promise<UpstreamResponse>` - Parsed JSON response from the API

**Behavior:**
- Validates token presence before any network call
- Supports configurable retry attempts (default: 1 retry after initial attempt)
- Implements 250ms backoff between retries
- Returns raw upstream JSON without transformation

资料来源：[src/common/http.ts:48-68]()

## Retry Logic

The HTTP client implements intelligent retry behavior for transient failures.

### Retry Conditions

| Condition | Retryable | Description |
|-----------|-----------|-------------|
| `AbortError` | Yes | Request timeout |
| HTTP 5xx | Yes | Server-side errors |
| `ECONNRESET` | Yes | Connection reset by peer |
| `ECONNREFUSED` | Yes | Connection refused |
| `ENOTFOUND` | Yes | DNS lookup failure |
| HTTP 4xx | No | Client errors |
| Business code != 0 | No | Application-level errors |

```mermaid
graph LR
    A[Request Attempt] --> B{Error Type?}
    B -->|AbortError| C[Retry]
    B -->|5xx| C
    B -->|Network Error| C
    B -->|4xx| D[No Retry]
    B -->|Business Error| D
    C --> E{Attempts<br/>Exhausted?}
    E -->|No| A
    E -->|Yes| F[Throw Error]
    D --> F
```

**Retry Configuration:**
- Maximum attempts: `1 + JUSTONEAPI_RETRY` (default: 2 total attempts)
- Backoff delay: `250ms * attempt_number`

资料来源：[src/common/http.ts:68-96]()

## Timeout Management

Timeouts are implemented using the AbortController API for native browser/Node.js compatibility.

| Setting | Environment Variable | Default | Description |
|---------|---------------------|---------|-------------|
| Request Timeout | `JUSTONEAPI_TIMEOUT_MS` | `20000` | Timeout in milliseconds |

**Implementation:**

```typescript
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), config.timeoutMs);

const res = await fetch(url, { method: "GET", signal: controller.signal });
// ... process response ...
clearTimeout(timer); // Clean up timer
```

When a timeout occurs, an `AbortError` is thrown, which triggers the retry logic.

资料来源：[src/common/http.ts:70-76]()

## Error Handling

### Error Code Mapping

The system maps upstream error codes to standardized MCP error codes.

| Upstream Code | MCP Code | Description |
|---------------|----------|-------------|
| 301 | `INVALID_TOKEN` | Token is invalid or inactive |
| 302 | `INVALID_TOKEN` | Token validation failed |
| 401 | `INVALID_TOKEN` | Authentication required |
| 402 | `INSUFFICIENT_BALANCE` | Account balance too low |
| 403 | `PERMISSION_DENIED` | No access to resource |
| 404 | `PERMISSION_DENIED` | Resource not found |
| 422 | `VALIDATION_ERROR` | Invalid request parameters |
| 429 | `RATE_LIMITED` | Too many requests |
| 500 | `INTERNAL_ERROR` | Server error |
| 503 | `UPSTREAM_ERROR` | Service unavailable |

资料来源：[src/common/errors.ts:19-53]()

### Error Payload Structure

When an error occurs, the `toMcpErrorPayload` function converts the error to a structured format.

```typescript
{
  code: JOAErrorCode;      // Normalized MCP error code
  message: string;         // Human-readable message
  upstreamCode?: number;  // Original upstream error code
  httpStatus?: number;     // HTTP status code
}
```

**Error Priority:**
1. `AbortError` → `NETWORK_TIMEOUT`
2. `upstreamCode` present → Maps to appropriate MCP code
3. `httpStatus` present → `UPSTREAM_ERROR`
4. `cause` or network error code → `NETWORK_ERROR`
5. Fallback → `UPSTREAM_ERROR`

资料来源：[src/common/errors.ts:55-91]()

## Security Features

### Token Masking

All API tokens are masked in logs to prevent credential leakage.

```typescript
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 {
    // Fallback: best-effort masking
    return fullUrl.replace(/token=([^&]+)/g, (_m, g1) => `token=${maskToken(g1)}`);
  }
}
```

**Features:**
- Primary method uses URL API for accurate parsing
- Fallback regex for non-standard URLs
- Two-level fallback to prevent logging failures

资料来源：[src/common/config.ts:58-74]()

### Debug Logging

When `JUSTONEAPI_DEBUG=true`, requests are logged to stderr with masked tokens:

```
[justoneapi] GET https://api.justoneapi.com/api/search/v1?token=***&keyword=AI (attempt 1/2)
```

资料来源：[src/common/http.ts:72-74]()

## Configuration

### Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `JUSTONEAPI_TOKEN` | Yes | - | API authentication token |
| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint base URL |
| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |
| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after initial attempt |
| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging |

资料来源：[README.md:103-110]()

## Usage Examples

### Basic Tool Implementation

Tools in this MCP server use the HTTP client through dedicated API functions:

```typescript
// From unified_search_v1.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);

  if (input.source) {
    params.append("source", input.source);
  }

  if (input.nextCursor) {
    params.append("nextCursor", input.nextCursor);
  } else {
    params.append("start", input.start);
    params.append("end", input.end);
  }

  return await getJson(`/api/search/v1?${params.toString()}`);
}
```

资料来源：[src/tools/search/unified_search_v1.ts:29-54]()

### Error Response Format

All errors are returned in a consistent MCP format:

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

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

资料来源：[README.md:86-89]()

## Integration with MCP Server

The HTTP client is integrated into the MCP server's tool registration system:

```typescript
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:50-70]()

## Dependencies

The HTTP client implementation uses the following dependencies:

| Package | Version | Purpose |
|---------|---------|---------|
| `@modelcontextprotocol/sdk` | `^1.25.1` | MCP server framework |
| `zod` | `^4.3.4` | Schema validation |
| `dotenv` | `^17.2.3` | Environment variable loading |

资料来源：[package.json:16-23]()

---

<a id='unified-search-tool'></a>

## Unified Search Tool

### 相关页面

相关主题：[Kuaishou Video Search Tool](#kuaishou-video-search), [Tool Naming Conventions and Standards](#tool-conventions), [Error Handling](#error-handling)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)
- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)
- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)
- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)
- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)
</details>

# Unified Search Tool

## Overview

The Unified Search Tool (`unified_search_v1`) is the primary MCP (Model Context Protocol) tool provided by justoneapi-mcp. It enables aggregated searching across multiple Chinese social media platforms and news sources through a single API interface.

**Key Characteristics:**
- Searches 8 platforms simultaneously in one request
- Returns raw, unmodified JSON from upstream APIs
- Supports advanced search syntax (AND, OR, NOT operators)
- Implements cursor-based pagination
- UTC+8 timezone for all date/time operations

资料来源：[TOOLS.md:43-60]()

## Architecture

### System Context

```mermaid
graph TD
    subgraph "MCP Host"
        A[Claude / Cursor]
    end
    
    subgraph "justoneapi-mcp"
        B[Server Entry<br/>src/index.ts]
        C[Tool Handler<br/>unified_search_v1]
        D[HTTP Client<br/>src/common/http.ts]
        E[Error Handler<br/>src/common/errors.ts]
    end
    
    subgraph "External"
        F[JustOneAPI<br/>api.justoneapi.com]
    end
    
    A -->|MCP Protocol| B
    B --> C
    C --> D
    D -->|GET /api/search/v1| F
    F -->|JSON Response| D
    D --> E
    
    style F fill:#f9f,stroke:#333
    style D fill:#bbf,stroke:#333
    style E fill:#fbb,stroke:#333
```

### Request Flow

```mermaid
sequenceDiagram
    participant MCP as MCP Host
    participant Server as justoneapi-mcp
    participant HTTP as HTTP Client
    participant API as JustOneAPI
    
    MCP->>Server: unified_search_v1(params)
    Server->>HTTP: getJson(endpoint, params)
    
    loop Retry Logic (max 2 attempts)
        HTTP->>API: GET /api/search/v1
        API-->>HTTP: JSON Response
        
        alt Success (code=0)
            HTTP-->>Server: data
        else Retryable Error (5xx, timeout)
            HTTP->>HTTP: Wait 250ms * attempt
        end
    end
    
    alt Non-retryable Error
        Server->>Server: toMcpErrorPayload(e)
        Server-->>MCP: ERROR[...]
    else Success
        Server-->>MCP: Raw JSON response
    end
```

资料来源：[src/index.ts:29-47]()
资料来源：[src/common/http.ts:1-44]()

## Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `keyword` | string | Yes | Search keyword with advanced syntax support |
| `source` | string | No | Platform filter (default: `ALL`) |
| `start` | string | Conditional | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8) |
| `end` | string | Conditional | End time `yyyy-MM-dd HH:mm:ss` (UTC+8) |
| `nextCursor` | string | No | Pagination cursor from previous response |

**Note:** `start` and `end` are required for the first page request. They must be omitted when using `nextCursor` for pagination.

资料来源：[src/tools/search/unified_search_v1.ts:16-41]()

## Supported Platforms

| Platform ID | Description |
|-------------|-------------|
| `ALL` | Search all platforms (default) |
| `NEWS` | News articles |
| `WEIBO` | Sina Weibo |
| `WEIXIN` | WeChat public accounts |
| `ZHIHU` | Zhihu Q&A |
| `DOUYIN` | Douyin (TikTok China) |
| `XIAOHONGSHU` | Xiaohongshu (Little Red Book) |
| `BILIBILI` | Bilibili video platform |
| `KUAISHOU` | Kuaishou short video |

资料来源：[src/tools/search/unified_search_v1.ts:9-16]()

## Search Syntax

The unified search supports advanced query operators:

| Operator | Syntax | Example | Description |
|----------|--------|---------|-------------|
| Single keyword | `word` | `deepseek` | Search for exact term |
| AND (implicit) | `word1 word2` | `deepseek chatgpt` | Both terms must appear |
| OR | `word1~word2` | `deepseek~chatgpt` | Either term may appear |
| NOT | `word -exclude` | `deepseek -chatgpt` | Exclude term from results |

**Syntax Rules:**
- Single keyword: Plain text match
- AND operator: Space-separated terms (implicit)
- OR operator: Tilde (`~`) separator
- NOT operator: Dash (`-`) prefix on exclusion term

资料来源：[TOOLS.md:62-69]()

## Pagination

### Cursor-Based Pagination

```mermaid
graph LR
    A[First Request<br/>start, end] --> B[Response<br/>data + nextCursor]
    B --> C{Next Page?}
    C -->|Yes| D[Next Request<br/>nextCursor]
    D --> E[Response<br/>data + nextCursor]
    E --> C
    C -->|No| F[Done]
```

### Pagination Rules

1. **First Request:** Include `start` and `end` time parameters
2. **Subsequent Requests:** Use `nextCursor` instead of time parameters
3. **Final Page:** Response without `nextCursor` indicates completion

When `nextCursor` is provided, `start`, `end`, and `source` parameters should be omitted—the cursor contains all necessary pagination context.

资料来源：[TOOLS.md:32-42]()

## Response Format

### Success Response

```json
{
  "code": 0,
  "message": null,
  "recordTime": "2025-01-02T14:55:21Z",
  "data": {
    // Platform-specific data structure
  }
}
```

### Error Response

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

| Error Code | Description | Recovery Action |
|------------|-------------|-----------------|
| `INVALID_TOKEN` | Token invalid or inactive | Update `JUSTONEAPI_TOKEN` |
| `RATE_LIMITED` | Too many requests | Slow down and retry |
| `DAILY_QUOTA_EXCEEDED` | Daily limit reached | Wait or upgrade plan |
| `INSUFFICIENT_BALANCE` | Low account balance | Top up account |
| `VALIDATION_ERROR` | Invalid parameters | Check input values |
| `NETWORK_TIMEOUT` | Request timed out | Check network/retry |
| `NETWORK_ERROR` | Connection failed | Check internet |
| `UPSTREAM_ERROR` | Server error | Retry or contact support |

资料来源：[src/common/errors.ts:1-72]()

## Configuration

### Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `JUSTONEAPI_TOKEN` | Yes | — | API authentication token |
| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint |
| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout (ms) |
| `JUSTONEAPI_RETRY` | No | `1` | Retry attempts |
| `JUSTONEAPI_DEBUG` | No | `false` | Debug logging |

### MCP Server Configuration

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

## Usage Examples

### Basic Multi-Platform Search

```
Search for "AI" discussions on all platforms from January 1-5, 2025
```

**Generated Parameters:**
```json
{
  "keyword": "AI",
  "source": "ALL",
  "start": "2025-01-01 00:00:00",
  "end": "2025-01-05 23:59:59"
}
```

### Platform-Specific Search

```
Search for "chatgpt" on Weibo only, from December 1st to January 2nd
```

**Generated Parameters:**
```json
{
  "keyword": "chatgpt",
  "source": "WEIBO",
  "start": "2024-12-01 00:00:00",
  "end": "2025-01-02 23:59:59"
}
```

### Complex Query with OR and NOT

```
Search for posts containing "deepseek" OR "机器学习" but NOT "广告"
```

**Generated Parameters:**
```json
{
  "keyword": "deepseek~机器学习 -广告",
  "source": "ZHIHU",
  "start": "2025-01-01 00:00:00",
  "end": "2025-01-31 23:59:59"
}
```

### Pagination Request

When continuing from a previous response:

```json
{
  "keyword": "AI",
  "nextCursor": "eyJsYXN0SWQiOiIxMjM0NTY3ODkwIn0="
}
```

资料来源：[README.md:1-80]()

## Design Philosophy

The Unified Search Tool follows the **"Transport, not transformation"** principle:

- **Maximum data fidelity:** Returns unmodified upstream JSON responses
- **No field parsing:** Raw response structure preserved
- **No data restructuring:** Original field names and hierarchy maintained
- **Long-term compatibility:** Interface stability prioritized over convenience

This approach ensures that clients receive complete, unmodified data for any downstream processing needs.

资料来源：[README.md:95-105]()

## Implementation
Error with Openai API: output new_sensitive (1027)

Please check that you have set the OPENAI_API_KEY environment variable with a valid API key.

---

<a id='kuaishou-video-search'></a>

## Kuaishou Video Search Tool

### 相关页面

相关主题：[Unified Search Tool](#unified-search-tool), [Tool Naming Conventions and Standards](#tool-conventions)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)
- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)
- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)
- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)
- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)
- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)
</details>

# Kuaishou Video Search Tool

## Overview

The **Kuaishou Video Search Tool** (`kuaishou_search_video_v2`) is a Model Context Protocol (MCP) tool that enables users to search for videos on Kuaishou, a major Chinese short-video platform. It integrates with the JustOneAPI service to provide programmatic access to Kuaishou's video search functionality.

**Key Characteristics:**
- Platform-specific search targeting Kuaishou exclusively
- Pagination support for result browsing
- Returns raw, untransformed JSON responses from the upstream API
- Zod-based input validation with clear parameter descriptions

资料来源：[src/tools/kuaishou/search_video_v2.ts:1-16]()

## Architecture

### System Context

The tool operates within the broader justoneapi-mcp server architecture, which uses the MCP SDK to expose tools to AI hosts like Claude Desktop or Cursor.

```mermaid
graph TD
    A[MCP Host<br/>Claude Desktop/Cursor] -->|registerTool| B[justoneapi-mcp Server]
    B -->|registerTool| C[kuaishou_search_video_v2]
    C -->|requireToken| D[Config Module]
    C -->|HTTP GET| E[JustOneAPI Gateway]
    E -->|Proxies to| F[Kuaishou API]
    F -->|JSON Response| E
    E -->|Raw JSON| C
    C -->|Formatted Result| B
    B -->|MCP Response| A
```

### Component Responsibilities

| Component | File | Responsibility |
|-----------|------|-----------------|
| Tool Handler | `src/tools/kuaishou/search_video_v2.ts` | Input validation, API call orchestration |
| HTTP Client | `src/common/http.ts` | Request execution with retry logic |
| Error Handler | `src/common/errors.ts` | Error code mapping and formatting |
| Config | `src/common/config.ts` | Token retrieval and validation |
| Server Entry | `src/index.ts` | Tool registration with MCP SDK |

资料来源：[src/index.ts:18-37]()

## Input Parameters

The `KuaishouSearchVideoV2Input` schema defines the tool's input contract using Zod validation.

### Parameter Specification

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `keyword` | `string` | Yes | - | Search keyword, e.g., `'dance'` |
| `page` | `number` | No | `1` | Page number for pagination (must be ≥ 1) |

### Zod Schema Definition

```typescript
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"),
});
```

**Validation Rules:**
- `keyword` must be a non-empty string (minimum 1 character)
- `page` must be a positive integer; defaults to `1` if not provided

资料来源：[src/tools/kuaishou/search_video_v2.ts:4-8]()

## API Request Flow

### Request Construction

The tool builds the API request by encoding parameters and appending them to the endpoint URL:

```typescript
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}`
  );
}
```

### Request Flow Diagram

```mermaid
sequenceDiagram
    participant Client as MCP Tool Handler
    participant Config as Config Module
    participant HTTP as HTTP Client
    participant API as JustOneAPI Gateway

    Client->>Config: requireToken()
    Config-->>Client: Returns JUSTONEAPI_TOKEN
    
    Client->>Client: encodeURIComponent(token, keyword, page)
    
    Client->>HTTP: getJson(/api/kuaishou/search-video/v2?...)
    HTTP->>API: GET Request
    
    alt Success (2xx)
        API-->>HTTP: { code: 0, data: {...} }
        HTTP-->>Client: Parsed JSON object
    else Error (4xx/5xx)
        API-->>HTTP: Error response
        HTTP-->>Client: Throws ApiError
    end
```

资料来源：[src/tools/kuaishou/search_video_v2.ts:10-16]()

## Error Handling

All errors are normalized into MCP error codes with actionable messages.

### Error Code Reference

| Error Code | Description | User Action |
|------------|-------------|-------------|
| `INVALID_TOKEN` | Token is invalid or inactive | Update `JUSTONEAPI_TOKEN` |
| `COLLECT_FAILED` | Data collection failed | Retry after a short delay |
| `RATE_LIMITED` | Too many requests | Slow down and retry later |
| `DAILY_QUOTA_EXCEEDED` | Daily usage limit reached | Wait until tomorrow or upgrade plan |
| `INSUFFICIENT_BALANCE` | Account balance too low | Top up account |
| `VALIDATION_ERROR` | Invalid request parameters | Check input values |
| `INTERNAL_ERROR` | Server error | Retry later |
| `NETWORK_TIMEOUT` | Request timed out | Check network or retry |
| `NETWORK_ERROR` | Network connection failed | Check internet connection |
| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |

### Error Response Format

Errors are returned in a standardized format:

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

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

资料来源：[README.md:78-95]()

### Error Processing in MCP Handler

```typescript
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:20-36]()

## HTTP Retry Mechanism

The underlying HTTP client implements automatic retry logic for transient failures.

### Retry Conditions

| Condition | Retryable |
|-----------|-----------|
| Timeout (`AbortError`) | ✅ Yes |
| HTTP 5xx status codes | ✅ Yes |
| `ECONNRESET` | ✅ Yes |
| `ECONNREFUSED` | ✅ Yes |
| `ENOTFOUND` | ✅ Yes |
| HTTP 4xx status codes | ❌ No |

### Retry Strategy

- **Attempts**: Configurable via `JUSTONEAPI_RETRY` (default: 1 retry after first attempt)
- **Backoff**: 250ms × attempt number between retries
- **Timeout**: Configurable via `JUSTONEAPI_TIMEOUT_MS` (default: 20000ms)

```mermaid
graph TD
    A[HTTP Request] --> B{Success?}
    B -->|Yes| C[Return JSON]
    B -->|No| D{Retryable Error?}
    D -->|No| E[Throw Error]
    D -->|Yes| F{Attempts Remaining?}
    F -->|No| E
    F -->|Yes| G[Wait 250ms × attempt]
    G --> A
```

资料来源：[src/common/http.ts:32-42]()

## Tool Registration

The tool is registered with the MCP server using the SDK's `registerTool` method.

```typescript
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) => {
    // Implementation...
  }
);
```

**Registration Details:**
- **Tool Name**: `kuaishou_search_video_v2`
- **Schema**: `KuaishouSearchVideoV2Input.shape` (Zod-derived)
- **Response Type**: Raw JSON text with indentation

资料来源：[src/index.ts:18-37]()

## Configuration

### Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `JUSTONEAPI_TOKEN` | Yes | - | Authentication token for JustOneAPI |
| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint |
| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |
| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after first attempt |
| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging |

### Token Security

The configuration module masks tokens in log output for security:

```typescript
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:27-41]()

## Response Contract

### Success Response Format

```json
{
  "code": 0,
  "message": null,
  "recordTime": "2025-12-31T14:55:21Z",
  "data": {
    // Platform-specific data structure from Kuaishou API
  }
}
```

### Field Descriptions

| Field | Type | Description |
|-------|------|-------------|
| `code` | `number` | `0` indicates success; non-zero indicates error |
| `message` | `string \| null` | Error description if code ≠ 0 |
| `recordTime` | `string` | Timestamp of the response (ISO 8601) |
| `data` | `object` | Raw response from upstream Kuaishou API |

### Raw JSON Philosophy

The tool intentionally returns **unmodified upstream responses**:
- ✅ Maximum data fidelity
- ✅ No field parsing or normalization
- ✅ No data restructuring
- ✅ Long-term compatibility

资料来源：[TOOLS.md:69-86]()

## Usage Examples

### Claude Desktop / Cursor

```
Search for "dance" videos on Kuaishou, page 1
```

### MCP Host Tool Invocation

```json
{
  "name": "kuaishou_search_video_v2",
  "input": {
    "keyword": "dance",
    "page": 1
  }
}
```

### Expected Response Structure

```json
{
  "code": 0,
  "message": null,
  "recordTime": "2025-01-15T10:30:00Z",
  "data": {
    // Kuaishou video search results
    // (exact structure determined by upstream API)
  }
}
```

## Dependencies

The tool relies on the following npm packages:

| Package | Version | Purpose |
|---------|---------|---------|
| `@modelcontextprotocol/sdk` | `^1.25.1` | MCP server and tool framework |
| `zod` | `^4.3.4` | Schema validation and type inference |
| `dotenv` | `^17.2.3` | Environment variable loading |

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

## Related Documentation

| Document | Description |
|----------|-------------|
| [README.md](README.md) | Main project documentation |
| [TOOLS.md](TOOLS.md) | Complete tools reference |
| [unified_search_v1](./unified%20Search%20Tool.md) | Multi-platform search alternative |

---

<a id='tool-conventions'></a>

## Tool Naming Conventions and Standards

### 相关页面

相关主题：[Unified Search Tool](#unified-search-tool), [Kuaishou Video Search Tool](#kuaishou-video-search)

<details>
<summary>Relevant Source Files</summary>

以下源码文件用于生成本页说明：

- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)
- [src/tools/kuaishou/search_video_v2.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/kuaishou/search_video_v2.ts)
- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)
- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)
- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)
- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)
</details>

# Tool Naming Conventions and Standards

## Overview

The justoneapi-mcp project implements a standardized naming convention for all MCP (Model Context Protocol) tools. This convention ensures consistency, predictability, and scalability across the entire tool ecosystem. The naming standard follows a three-part pattern that clearly communicates the tool's scope, purpose, and version in a single identifier.

The primary objectives of this naming standard include:

- **Discoverability**: Tools can be easily identified and located based on their naming pattern
- **Versioning**: API evolution is managed through version suffixes
- **Consistency**: All contributors follow the same pattern, reducing cognitive load
- **Scalability**: New tools can be added following the established convention without ambiguity

资料来源：[README.md:73]()

## Naming Pattern Structure

All tools in the justoneapi-mcp server follow a unified naming pattern:

```
{platform}_{action}_{version}
```

This three-component structure provides immediate context about each tool's purpose and scope.

### Component Breakdown

| Component | Purpose | Examples | Description |
|-----------|---------|----------|-------------|
| `platform` | Identifies the target service | `kuaishou`, `unified` | The platform or scope the tool operates on |
| `action` | Describes the operation | `search`, `search_video` | What the tool does, can be compound with underscore |
| `version` | Indicates API version | `v1`, `v2` | Version of the underlying API endpoint |

### Syntax Rules

1. **Delimiter**: Components are separated by underscores (`_`), not camelCase or hyphens
2. **Lowercase**: All components use lowercase letters exclusively
3. **Compound actions**: Multi-word actions use underscores (e.g., `search_video`)
4. **Version format**: Version uses lowercase `v` followed by a number (e.g., `v1`, `v2`)

资料来源：[README.md:74-76]()

## Current Tool Registry

The following table lists all currently available tools in the justoneapi-mcp server:

| Tool Name | Platform | Action | Version | Purpose |
|-----------|----------|--------|---------|---------|
| `unified_search_v1` | unified | search | v1 | Multi-platform search across Weibo, WeChat, Zhihu, Douyin, Xiaohongshu, Bilibili, Kuaishou, and News |
| `kuaishou_search_video_v2` | kuaishou | search_video | v2 | Platform-specific video search for Kuaishou |

资料来源：[src/index.ts:24-46]()

## Platform Component Standards

### Reserved Platform Identifiers

The platform component identifies the target service or search domain:

| Platform | Description | Supported Actions |
|----------|-------------|-------------------|
| `unified` | Aggregated multi-platform search | `search` |
| `kuaishou` | Kuaishou video platform | `search_video` |
| `weibo` | Weibo social platform (planned) | `search` |
| `zhihu` | Zhihu Q&A platform (planned) | `search` |
| `douyin` | Douyin short video (planned) | `search_video` |
| `bilibili` | Bilibili video platform (planned) | `search_video` |

资料来源：[TOOLS.md:34-40]()

### Naming Future Platforms

When adding new platforms, follow these guidelines:

1. Use the lowercase English name of the platform
2. If the platform name contains multiple words, use the most common short form
3. Avoid abbreviations unless they are universally recognized
4. Ensure uniqueness across all existing platform names

## Action Component Standards

### Single-Word Actions

Simple actions use a single lowercase word:

- `search` - General search functionality
- `analyze` - Data analysis operations
- `fetch` - Data retrieval operations

### Compound Actions

Actions with multiple components use underscores to separate words:

| Action | Components | Meaning |
|--------|------------|---------|
| `search_video` | search + video | Video search functionality |
| `search_user` | search + user | User profile search |
| `fetch_trending` | fetch + trending | Trending content retrieval |

资料来源：[src/tools/kuaishou/search_video_v2.ts:1-15]()

## Version Component Standards

### Versioning Strategy

The version component follows semantic versioning principles adapted for API evolution:

| Version Pattern | Meaning | Upgrade Consideration |
|----------------|---------|----------------------|
| `v1` | Initial stable release | Breaking changes unlikely |
| `v2` | Major version with potential breaking changes | Check changelog before upgrading |
| `v{n}` | Future major versions | Each increment may introduce breaking changes |

### Version Upgrade Triggers

Consider incrementing the version when:

- **Breaking API changes**: Parameter types, required fields, or return structure change
- **Behavior changes**: Same inputs produce different outputs
- **Deprecations**: Removing functionality from a tool
- **Major architectural changes**: Internal refactoring affecting external behavior

### Version Coexistence

Multiple versions of the same tool may coexist, allowing gradual migration:

- Old versions remain available for backward compatibility
- New versions receive new features and improvements
- Deprecation notices appear in documentation

## Implementation Architecture

### Tool Registration Flow

The following diagram illustrates how tools are registered and exposed through the MCP server:

```mermaid
graph TD
    A[Tool Definition File] --> B[Zod Input Schema]
    A --> C[Tool Handler Function]
    B --> D[registerTool in index.ts]
    C --> D
    D --> E[McpServer Instance]
    E --> F[STDIO Transport]
    F --> G[MCP Host Client]
    
    H[Tool Name: kuaishou_search_video_v2] --> D
    I[Tool Name: unified_search_v1] --> D
```

### Tool Registration Code Structure

Tools are registered in `src/index.ts` using the MCP SDK's `registerTool` method:

```typescript
server.registerTool(
  "kuaishou_search_video_v2",
  {
    description: "Search Kuaishou videos by keyword...",
    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: [...] };
    }
  }
);
```

资料来源：[src/index.ts:24-46]()

## Input Schema Conventions

### Zod-Based Validation

All tools use Zod schemas for input validation, ensuring type safety and automatic documentation:

```typescript
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"),
});
```

### Schema Documentation Pattern

Each parameter includes:

| Field | Purpose | Methods |
|-------|---------|---------|
| `describe()` | Human-readable description | Required for all parameters |
| `.min()` | Minimum value constraint | For strings and numbers |
| `.default()` | Default value if omitted | Optional parameters |
| `.optional()` | Marks non-required parameters | Optional parameters |

资料来源：[src/tools/kuaishou/search_video_v2.ts:4-9]()

## Unified Search Tool Specification

### `unified_search_v1`

The unified search tool provides cross-platform search capabilities with advanced syntax support.

#### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `keyword` | string | Yes | Search keyword with syntax: single `word`, AND `word1 word2`, OR `word1~word2`, NOT `word -excluded` |
| `source` | enum | No | Platform filter: `ALL`, `NEWS`, `WEIBO`, `WEIXIN`, `ZHIHU`, `DOUYIN`, `XIAOHONGSHU`, `BILIBILI`, `KUAISHOU` |
| `start` | string | Conditional | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8). Required for first page |
| `end` | string | Conditional | End time `yyyy-MM-dd HH:mm:ss` (UTC+8). Required for first page |
| `nextCursor` | string | No | Pagination cursor from previous response |

#### Search Syntax Examples

| Syntax | Example | Meaning |
|--------|---------|---------|
| Single keyword | `deepseek` | Posts containing "deepseek" |
| AND search | `deepseek chatgpt` | Posts containing both terms |
| OR search | `deepseek~chatgpt` | Posts containing either term |
| NOT search | `deepseek -chatgpt` | Posts with "deepseek" but not "chatgpt" |

资料来源：[src/tools/search/unified_search_v1.ts:1-42]()

## Platform-Specific Tool Specification

### `kuaishou_search_video_v2`

The Kuaishou video search tool provides platform-specific video search functionality.

#### Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `keyword` | string | Yes | - | Search keyword, minimum 1 character |
| `page` | number | No | 1 | Page number, must be positive integer |

#### API Endpoint

```
GET /api/kuaishou/search-video/v2?token={token}&keyword={keyword}&page={page}
```

资料来源：[src/tools/kuaishou/search_video_v2.ts:1-15]()

## Error Handling Integration

### Standardized Error Codes

All tools return errors in a consistent format that includes the MCP error code:

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

### Error Code Mapping

| MCP Code | Trigger Condition | Upstream Code | User Action |
|----------|-------------------|---------------|-------------|
| `INVALID_TOKEN` | Invalid or inactive token | - | Update `JUSTONEAPI_TOKEN` |
| `RATE_LIMITED` | Too many requests | 302 | Slow down and retry |
| `DAILY_QUOTA_EXCEEDED` | Daily limit reached | - | Wait until tomorrow |
| `INSUFFICIENT_BALANCE` | Low account balance | - | Top up account |
| `NETWORK_TIMEOUT` | Request timeout | - | Check network/retry |
| `COLLECT_FAILED` | Data collection failed | - | Retry after delay |
| `VALIDATION_ERROR` | Invalid parameters | - | Check input values |

资料来源：[src/common/errors.ts:1-60]()

### Error Handler Implementation

```typescript
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;
  };
  
  if (error.name === "AbortError") {
    return { code: "NETWORK_TIMEOUT", message: buildUserMessage("NETWORK_TIMEOUT") };
  }
  // ... additional error type handling
}
```

## Best Practices

### Creating New Tools

Follow these steps to add a new tool:

1. **Choose the name** following the `{platform}_{action}_{version}` pattern
2. **Create the tool file** in `src/tools/{platform}/`
3. **Define the Zod schema** with descriptive parameter documentation
4. **Implement the handler** using `getJson` from `common/http.ts`
5. **Register in `index.ts`** with description and input schema
6. **Add tests** for input validation and error handling

### File Naming Conventions

| Tool Type | Location | File Name Pattern |
|-----------|----------|-------------------|
| Platform-specific | `src/tools/{platform}/` | `{action}_{version}.ts` |
| Unified tools | `src/tools/search/` | `{action}_{version}.ts` |
| Utility functions | `src/common/` | `{purpose}.ts` |

### Documentation Requirements

Each tool must document:

- All parameters with types and descriptions
- Required vs optional parameters
- Default values where applicable
- Error codes that may be returned
- Example usage scenarios

## Summary

The tool naming convention in justoneapi-mcp provides a clear, consistent, and scalable approach to defining MCP tools. By following the `{platform}_{action}_{version}` pattern, developers can quickly understand any tool's purpose and scope. The Zod-based schema validation ensures type safety, while standardized error handling provides consistent feedback across all operations.

Key takeaways:

- Use underscores to separate all components
- Always include the version suffix (`v1`, `v2`, etc.)
- Use compound action names with underscores when needed
- Follow the established file structure for organization
- Leverage Zod schemas for validation and documentation

---

<a id='configuration-reference'></a>

## Configuration Reference

### 相关页面

相关主题：[Authentication](#authentication), [HTTP Client Implementation](#http-client)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)
- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)
- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)
- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)
- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)
- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)
</details>

# Configuration Reference

## Overview

The justoneapi-mcp server provides a centralized configuration system that manages all runtime settings through environment variables. The configuration module serves as the single source of truth for API credentials, connection parameters, and debugging options.

Configuration is loaded from environment variables at startup and validated before the MCP server begins accepting requests. The system follows a "fail-fast" design pattern, terminating immediately if required parameters are missing.

资料来源：[src/index.ts:58-64]()

## Environment Variables

### Required Variables

| Variable | Type | Required | Description |
|----------|------|----------|-------------|
| `JUSTONEAPI_TOKEN` | string | **Yes** | Your JustOneAPI authentication token. Used for all API requests. |

The server validates the token presence on startup. If the token is missing or empty, the server exits with an error message directing users to set the environment variable.

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

### Optional Variables

| Variable | Type | Default | Description |
|----------|------|---------|-------------|
| `JUSTONEAPI_BASE_URL` | string | `https://api.justoneapi.com` | Base API endpoint for all requests |
| `JUSTONEAPI_TIMEOUT_MS` | number | `20000` | Request timeout in milliseconds |
| `JUSTONEAPI_RETRY` | number | `1` | Number of retries after initial request failure |
| `JUSTONEAPI_DEBUG` | boolean | `false` | Enable debug logging to stderr |

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

## Configuration Module Architecture

### Module Structure

The configuration system consists of the following exported functions and objects:

```typescript
// Implemented in src/common/config.ts
export const config: Config;        // Runtime configuration object
export function requireToken(): string;    // Validates and returns token
export function toSafeUrlForLog(url: string): string;  // Sanitizes URLs for logging
```

### Configuration Object

The internal `Config` interface defines the shape of the runtime configuration:

```typescript
interface Config {
  token: string;
  baseUrl: string;
  timeoutMs: number;
  retry: number;
  debug: boolean;
}
```

## Token Management

### Token Validation

The `requireToken()` function performs strict validation on the token:

1. Reads `JUSTONEAPI_TOKEN` from environment
2. Trims whitespace from the value
3. Checks if the token is empty
4. Returns the validated token string

If validation fails, an error is thrown immediately, preventing server startup.

资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)

### Token Usage in HTTP Layer

The token is used in HTTP requests by encoding it for URL safety:

```typescript
const token = encodeURIComponent(requireToken());
```

This encoded token is appended to all API requests, including:

- Unified search: `/api/search/v1?token=${token}&keyword=${keyword}`
- Kuaishou video search: `/api/kuaishou/search-video/v2?token=${token}&keyword=${keyword}`

资料来源：[src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)

## HTTP Layer Integration

### Request Flow

```mermaid
graph TD
    A[API Tool Called] --> B[getJson Function]
    B --> C[requireToken Validation]
    C --> D[Build URL with Config]
    D --> E[Create AbortController]
    E --> F[Execute Fetch Request]
    F --> G{Success?}
    G -->|Yes| H[Parse JSON Response]
    G -->|No| I{Check Retryable Error}
    I -->|Yes| J[Wait 250ms × Attempt]
    J --> E
    I -->|No| K[Throw Error]
    H --> L[Return UpstreamResponse]
    K --> M[Error Handler]
```

### Configuration Parameters Used

The HTTP module consumes configuration for request handling:

| Parameter | Usage | Purpose |
|-----------|-------|---------|
| `config.baseUrl` | URL construction | Prepend to all API paths |
| `config.timeoutMs` | Request timeout | Set AbortController timer |
| `config.retry` | Retry logic | Calculate total attempt count |
| `config.debug` | Logging | Print request details to stderr |

资料来源：[src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)

### Retry Mechanism

The retry logic uses the `JUSTONEAPI_RETRY` configuration value:

```typescript
const attempts = 1 + Math.max(0, Number.isFinite(config.retry) ? config.retry : 0);
```

Retry occurs only for specific error types:

| Error Type | Retryable |
|------------|-----------|
| `AbortError` (timeout) | ✅ Yes |
| HTTP 5xx status | ✅ Yes |
| `ECONNRESET` | ✅ Yes |
| `ECONNREFUSED` | ✅ Yes |
| `ENOTFOUND` | ✅ Yes |
| HTTP 4xx status | ❌ No |
| Business code ≠ 0 | ❌ No |

资料来源：[src/common/http.ts:31-39]()

### Timeout Configuration

The timeout is applied using AbortController:

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

With the default of 20000ms (20 seconds), requests exceeding this duration are cancelled and may be retried based on retry configuration.

资料来源：[src/common/http.ts:44-45]()

## Debug Logging

When `JUSTONEAPI_DEBUG` is set to `true`, detailed request information is logged to stderr:

```typescript
if (config.debug) {
  console.error(`[justoneapi] GET ${toSafeUrlForLog(url)} (attempt ${attempt}/${attempts})`);
}
```

### URL Sanitization

The `toSafeUrlForLog()` function ensures tokens are never exposed in logs by sanitizing URLs before output.

资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)

## Error Handling Integration

Configuration errors are mapped to MCP error codes:

| Upstream Code | MCP Error Code | User Message |
|---------------|----------------|--------------|
| - | `INVALID_TOKEN` | Token is invalid or inactive |
| - | `NETWORK_TIMEOUT` | Request timed out |
| - | `NETWORK_ERROR` | Network connection failed |
| - | `INTERNAL_ERROR` | Server error |

资料来源：[src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)

## MCP Server Configuration

### Claude Desktop Configuration

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

### Configuration File Locations

| Operating System | Config File Path |
|-----------------|------------------|
| 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](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)

## Dependencies

The configuration system depends on the following packages:

| Package | Version | Purpose |
|---------|---------|---------|
| `zod` | ^4.3.4 | Input validation schemas |
| `dotenv` | ^17.2.3 | Environment variable loading |
| `@modelcontextprotocol/sdk` | ^1.25.1 | MCP protocol implementation |

资料来源：[package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)

## Startup Validation

The server performs validation at startup in `src/index.ts`:

```typescript
async function main() {
  // Validate configuration on startup
  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);
  }
  // ... server initialization
}
```

This ensures users receive immediate feedback about missing configuration before the server attempts any network operations.

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

## Summary

The configuration system provides:

- **Centralized management** via environment variables
- **Fail-fast validation** on server startup
- **Safe logging** with token sanitization
- **Configurable timeouts** and retry behavior
- **Debug capabilities** for troubleshooting

All configuration flows through a single module (`src/common/config.ts`) ensuring consistent behavior across the entire application.

---

<a id='mcp-integration'></a>

## MCP Host Integration

### 相关页面

相关主题：[Getting Started with JustOneAPI MCP](#getting-started)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/README.md)
- [TOOLS.md](https://github.com/justoneapi/justoneapi-mcp/blob/main/TOOLS.md)
- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)
- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)
- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)
- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)
- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)
- [package.json](https://github.com/justoneapi/justoneapi-mcp/blob/main/package.json)
</details>

# MCP Host Integration

## Overview

MCP Host Integration refers to the process of connecting the **justoneapi-mcp** server to an MCP (Model Context Protocol) host application, enabling AI assistants like Claude Desktop, Cursor, or other MCP-compatible hosts to access Chinese social media search capabilities.

The integration follows the MCP specification, using JSON-RPC over stdio for communication between the host and server. This architecture allows any MCP-compatible host to discover and invoke the tools provided by justoneapi-mcp without custom integrations.

资料来源：[README.md:1-50]()

## Architecture

### System Components

The MCP Host Integration consists of three primary layers:

```mermaid
graph TD
    A["MCP Host<br/>(Claude Desktop, Cursor)"] --> B["justoneapi-mcp Server"]
    B --> C["JustOneAPI Backend"]
    B --> D["Zod Validation Layer"]
    
    A --> E["StdioServerTransport"]
    E --> B
    
    style A fill:#e1f5fe
    style B fill:#fff3e0
    style C fill:#e8f5e9
```

| Component | Description | Technology |
|-----------|-------------|------------|
| MCP Host | Client application providing AI capabilities | Claude Desktop, Cursor, etc. |
| Transport | Communication channel | stdio (Standard Input/Output) |
| MCP Server | Tool registry and request handler | @modelcontextprotocol/sdk |
| Validation | Input schema validation | Zod v4 |
| API Client | Upstream API communication | Native fetch with retry logic |

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

### Request Flow

```mermaid
sequenceDiagram
    participant Host as MCP Host
    participant Server as justoneapi-mcp
    participant API as JustOneAPI
    
    Host->>Server: Tool invocation (JSON-RPC)
    Server->>Server: Validate with Zod schema
    Server->>API: HTTP request with token
    API->>API: Process search request
    API-->>Server: Raw JSON response
    Server-->>Host: JSON-RPC response
```

## Supported MCP Hosts

The justoneapi-mcp server is compatible with any application implementing the MCP specification:

| Host | Platform | Configuration Path |
|------|----------|---------------------|
| Claude Desktop | macOS, Windows, Linux | Platform-specific config |
| Cursor | macOS, Windows, Linux | MCP settings |
| Other MCP hosts | Any | Host-specific |

资料来源：[README.md:50-80]()

## Installation and Configuration

### Quick Start with npx

The recommended installation method uses `npx` for zero-configuration deployment:

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

资料来源：[README.md:60-75]()

### Configuration Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `JUSTONEAPI_TOKEN` | Yes | - | Your JustOneAPI authentication token |
| `JUSTONEAPI_BASE_URL` | No | `https://api.justoneapi.com` | API endpoint |
| `JUSTONEAPI_TIMEOUT_MS` | No | `20000` | Request timeout in milliseconds |
| `JUSTONEAPI_RETRY` | No | `1` | Number of retries after initial attempt |
| `JUSTONEAPI_DEBUG` | No | `false` | Enable debug logging to stderr |

资料来源：[README.md:130-145]()

### Configuration File Locations

| Operating System | Configuration Path |
|------------------|-------------------|
| 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:55-70]()

## Tool Discovery

### Discovery Mechanism

When the MCP host starts, the justoneapi-mcp server automatically registers all available tools. The host queries the server's capabilities and receives a manifest of all callable tools with their input schemas.

```mermaid
graph LR
    A[Host Startup] --> B[Initialize Stdio Transport]
    B --> C[Register Tools via SDK]
    C --> D[Handle list_tools Request]
    D --> E[Return Tool Manifest]
    
    F[User Request] --> G[Validate Input with Zod]
    G --> H[Execute Tool Handler]
    H --> I[Return JSON Response]
```

### Available Tools

| Tool Name | Version | Description | Parameters |
|-----------|---------|-------------|------------|
| `unified_search_v1` | v1 | Multi-platform search | keyword, source, start, end, nextCursor |
| `kuaishou_search_video_v2` | v2 | Kuaishou video search | keyword, nextCursor |

资料来源：[TOOLS.md:15-50]()

### Discovery Command

To discover available tools in Claude Desktop:

```
Please list all available tools from justoneapi-mcp
```

资料来源：[README.md:35-45]()

## Tool Input Validation

### Schema Validation Flow

All tool inputs pass through Zod validation before execution:

```mermaid
graph TD
    A[User Input] --> B[Zod Schema Validation]
    B -->|Valid| C[Execute Tool Handler]
    B -->|Invalid| D[Return VALIDATION_ERROR]
    C --> E[API Request]
    E --> F[JSON Response]
    
    style D fill:#ffcdd2
    style F fill:#c8e6c9
```

### Example: unified_search_v1 Schema

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `keyword` | string | Yes | Search keyword with syntax support |
| `source` | enum | No | Platform filter (default: ALL) |
| `start` | string | First page* | Start time `yyyy-MM-dd HH:mm:ss` (UTC+8) |
| `end` | string | First page* | End time `yyyy-MM-dd HH:mm:ss` (UTC+8) |
| `nextCursor` | string | Pagination | Cursor from previous response |

*Required for first page unless using `nextCursor`

资料来源：[src/tools/search/unified_search_v1.ts:10-45]()

### Search Syntax Support

| Operator | Example | Behavior |
|----------|---------|----------|
| Single keyword | `deepseek` | Search for exact term |
| AND | `deepseek chatgpt` | Both terms must appear |
| OR | `deepseek~chatgpt` | Either term can appear |
| NOT | `deepseek -chatgpt` | Exclude term |

资料来源：[README.md:95-110]()

## Error Handling Integration

### Error Mapping

The server normalizes upstream errors into stable MCP error codes:

| Error Code | Upstream Condition | User Action |
|------------|-------------------|-------------|
| `INVALID_TOKEN` | Invalid/inactive token | Update JUSTONEAPI_TOKEN |
| `COLLECT_FAILED` | Data collection failed | Retry after delay |
| `RATE_LIMITED` | Too many requests | Slow down and retry |
| `DAILY_QUOTA_EXCEEDED` | Daily limit reached | Wait until tomorrow |
| `INSUFFICIENT_BALANCE` | Low account balance | Top up account |
| `PERMISSION_DENIED` | No access to resource | Contact support |
| `VALIDATION_ERROR` | Invalid parameters | Check input values |
| `INTERNAL_ERROR` | Server error | Retry later |
| `NETWORK_TIMEOUT` | Request timed out | Check network/retry |
| `NETWORK_ERROR` | Connection failed | Check internet |
| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |

资料来源：[src/common/errors.ts:50-80]()

### Error Response Format

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

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

资料来源：[README.md:115-125]()

### Retry Logic

The HTTP client implements automatic retry for transient failures:

| Retry Trigger | Backoff Strategy |
|--------------|------------------|
| AbortError (timeout) | 250ms × attempt |
| HTTP 5xx | 250ms × attempt |
| ECONNRESET | 250ms × attempt |
| ECONNREFUSED | 250ms × attempt |
| ENOTFOUND | 250ms × attempt |

资料来源：[src/common/http.ts:15-30]()

## Session and Pagination

### Cursor-Based Pagination

Search results use `nextCursor` for pagination to maintain state across requests:

```mermaid
graph LR
    A[First Request] -->|start + end| B[Page 1 Response]
    B -->|nextCursor| C[Second Request]
    C -->|nextCursor| D[Page 2 Response]
    D -->|nextCursor| E[Continue...]
    
    style A fill:#e3f2fd
    style D fill:#e8f5e9
```

### Continuing Results

When results have more pages, simply ask:
- "Show me the next page of results"
- "Get more results from the previous search"
- "Continue with the next page"

The MCP host automatically extracts `nextCursor` and fetches subsequent pages without requiring `start`, `end`, or `source` parameters again.

资料来源：[README.md:78-92]()

## Dependencies

### Runtime Dependencies

| Package | Version | Purpose |
|---------|---------|---------|
| @modelcontextprotocol/sdk | ^1.25.1 | MCP server implementation |
| zod | ^4.3.4 | Schema validation |
| dotenv | ^17.2.3 | Environment configuration |

### Development Dependencies

| Package | Version | Purpose |
|---------|---------|---------|
| typescript | ^5.9.3 | Type safety |
| eslint | ^9.39.2 | Code linting |
| prettier | ^3.7.4 | Code formatting |

资料来源：[package.json:15-35]()

## Design Philosophy

### Transport, Not Transformation

The justoneapi-mcp server adheres to a "Transport, not transformation" principle:

- **Maximum data fidelity** - Returns unmodified upstream responses
- **No field parsing** - Raw JSON from APIs
- **No data restructuring** - Preserves original schema
- **Long-term compatibility** - Schema stability over convenience

This ensures that:
1. No data is lost in translation
2. Users receive complete API responses
3. Breaking changes in upstream APIs are visible immediately
4. Advanced users can access any field from the response

资料来源：[README.md:155-165]()

## Advanced Configuration Example

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

资料来源：[README.md:145-155]()

## Token Security

The server masks tokens in log output for security:

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

Safe URL logging replaces the token parameter with masked value, ensuring credentials are never exposed in logs or error messages.

资料来源：[src/common/config.ts:30-45]()

---

<a id='error-handling'></a>

## Error Handling

### 相关页面

相关主题：[HTTP Client Implementation](#http-client), [Unified Search Tool](#unified-search-tool), [Configuration Reference](#configuration-reference)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)
- [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)
- [src/index.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)
- [src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)
- [src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)
</details>

# Error Handling

## Overview

The justoneapi-mcp project implements a comprehensive error handling system designed to provide stability, transparency, and raw data fidelity. The error handling layer acts as a bridge between upstream API responses and MCP (Model Context Protocol) tool invocations, normalizing diverse error conditions into stable, actionable MCP error codes.

**Key Design Principles:**

- Transport, not transformation — the system prioritizes maximum data fidelity
- Fail fast with clear validation (token requirement checked early)
- Retry logic for transient failures
- Safe logging that never exposes sensitive credentials

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

---

## Error Code System

### Core Error Codes

The system defines a comprehensive set of standardized error codes that map upstream errors to user-friendly MCP responses.

| Error Code | Description | Recommended Action |
|------------|-------------|-------------------|
| `INVALID_TOKEN` | Token is invalid or inactive | Update your `JUSTONEAPI_TOKEN` |
| `COLLECT_FAILED` | Data collection failed | Retry after a short delay |
| `RATE_LIMITED` | Too many requests | Slow down and retry later |
| `DAILY_QUOTA_EXCEEDED` | Daily usage limit reached | Wait until tomorrow or upgrade plan |
| `INSUFFICIENT_BALANCE` | Account balance too low | Top up your account |
| `PERMISSION_DENIED` | No access to this resource | Contact support |
| `VALIDATION_ERROR` | Invalid request parameters | Check input values |
| `INTERNAL_ERROR` | Server error | Retry later |
| `NETWORK_TIMEOUT` | Request timed out | Check network or retry |
| `NETWORK_ERROR` | Network connection failed | Check internet connection |
| `UPSTREAM_ERROR` | Unspecified upstream error | Retry or contact support |

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

### Upstream Code Mapping

The `mapUpstreamCode` function in `errors.ts` translates numeric upstream API codes into MCP error codes.

```typescript
function mapUpstreamCode(upstreamCode: number): JOAErrorCode {
  switch (upstreamCode) {
    case 302:
      return "RATE_LIMITED";
    case 401:
      return "INVALID_TOKEN";
    // ... other mappings
    default:
      return "UPSTREAM_ERROR";
  }
}
```

资料来源：[src/common/errors.ts:1-50](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)

---

## Architecture

### Error Flow Diagram

```mermaid
graph TD
    A[API Request] --> B{HTTP Response OK?}
    B -->|No| C[HTTP Level Error]
    B -->|Yes| D{JSON Parse Success?}
    D -->|No| E[Parse Error]
    D -->|Yes| F{Business Code = 0?}
    F -->|No| G[Business Level Error]
    F -->|Yes| H[Success Response]
    
    C --> I[Create ApiError with httpStatus]
    E --> J[Create ApiError with payload=text]
    G --> K[Create ApiError with upstreamCode]
    
    I --> L[toMcpErrorPayload]
    J --> L
    K --> L
    
    L --> M[Return MCP Error Format]
    
    H --> N[Return JSON Data]
```

### Component Structure

| Component | File | Responsibility |
|-----------|------|-----------------|
| Error Type Definitions | `src/common/errors.ts` | Error codes, mapping functions |
| HTTP Client | `src/common/http.ts` | Request execution, retry logic |
| Error Processing | `src/common/errors.ts` | Payload conversion, message building |
| Tool Integration | `src/index.ts` | MCP error formatting for tool responses |

资料来源：[src/common/errors.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts), [src/common/http.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)

---

## Error Detection and Classification

### Detection Sources

The error handling system identifies errors from multiple sources:

1. **Timeout Errors** — AbortError from AbortController
2. **HTTP Status Errors** — Non-2xx responses
3. **JSON Parse Failures** — Invalid JSON responses
4. **Business Logic Errors** — Upstream API returns code != 0
5. **Network Failures** — ECONNREFUSED, ENOTFOUND, ECONNRESET

```typescript
// Timeout from AbortController
if (error.name === "AbortError") {
  return { code: "NETWORK_TIMEOUT", message: buildUserMessage("NETWORK_TIMEOUT") };
}

// Network-level failures
if (error.cause || error.code === "ECONNREFUSED" || error.code === "ENOTFOUND") {
  return { code: "NETWORK_ERROR", message: error.message ?? buildUserMessage("NETWORK_ERROR") };
}
```

资料来源：[src/common/errors.ts:52-73](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)

### Error Payload Interface

```typescript
interface ApiError extends Error {
  httpStatus?: number;
  upstreamCode?: number;
  payload?: unknown;
  code?: string;
  cause?: unknown;
}
```

资料来源：[src/common/http.ts:15-21](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)

---

## HTTP Client Error Handling

### Retry Logic

The `getJson` function implements intelligent retry logic with exponential backoff.

```mermaid
graph LR
    A[Request] --> B{Attempt <= Max?}
    B -->|Yes| C[Execute Fetch]
    C --> D{Success?}
    D -->|Yes| E[Return JSON]
    D -->|No| F{Retryable?}
    F -->|Yes| G[Wait 250ms * attempt]
    F -->|No| H[Throw Error]
    G --> B
    H --> I[toMcpErrorPayload]
```

### Retryable Conditions

| Condition | Retryable | Reason |
|-----------|-----------|--------|
| AbortError (timeout) | ✅ Yes | Transient timeout |
| HTTP 5xx | ✅ Yes | Server-side issue |
| ECONNRESET | ✅ Yes | Connection reset |
| ECONNREFUSED | ✅ Yes | Server unavailable |
| ENOTFOUND | ✅ Yes | DNS/network issue |
| HTTP 4xx | ❌ No | Client error |
| Business code != 0 | ❌ No | Data issue |

```typescript
const retryable =
  error.name === "AbortError" ||
  (typeof httpStatus === "number" && httpStatus >= 500) ||
  error.code === "ECONNRESET" ||
  error.code === "ECONNREFUSED" ||
  error.code === "ENOTFOUND";
```

资料来源：[src/common/http.ts:40-48](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/http.ts)

### Timeout Configuration

| Configuration | Default | Description |
|---------------|---------|-------------|
| `JUSTONEAPI_TIMEOUT_MS` | 20000 | Request timeout in milliseconds |

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

---

## Error Processing Flow

### The `toMcpErrorPayload` Function

This function transforms various error types into a standardized MCP error format:

```typescript
export function toMcpErrorPayload(e: unknown): {
  code: JOAErrorCode;
  message: string;
  upstreamCode?: number;
  httpStatus?: number;
}
```

**Processing Priority:**

1. AbortError → `NETWORK_TIMEOUT`
2. Upstream business code (if present) → Mapped MCP code
3. HTTP status (if present) → `UPSTREAM_ERROR`
4. Network errors (cause present or specific codes) → `NETWORK_ERROR`
5. Default fallback → `UPSTREAM_ERROR`

资料来源：[src/common/errors.ts:76-101](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)

### User Message Building

The `buildUserMessage` function generates human-readable messages for each error code:

```typescript
function buildUserMessage(code: JOAErrorCode, base?: string | null): string {
  switch (code) {
    case "NETWORK_TIMEOUT":
      return base ?? "Request timed out. Check network or increase timeout.";
    case "INVALID_TOKEN":
      return base ?? "Invalid or inactive token. Check JUSTONEAPI_TOKEN.";
    // ... additional cases
    default:
      return base ?? "Upstream error. Please retry later.";
  }
}
```

资料来源：[src/common/errors.ts:25-74](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/errors.ts)

---

## Tool-Level Error Handling

### MCP Tool Integration

All tools registered with the MCP server wrap their execution in try-catch blocks to ensure consistent error formatting.

```typescript
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](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/index.ts)

### Error Response Format

MCP tool errors are formatted as:

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

**Example Responses:**

| Scenario | Response Format |
|----------|-----------------|
| Rate Limited | `ERROR[RATE_LIMITED] (upstream=302): Rate limit exceeded. Please slow down and retry later.` |
| Invalid Token | `ERROR[INVALID_TOKEN] (upstream=401): Invalid or inactive token. Check JUSTONEAPI_TOKEN.` |
| Network Timeout | `ERROR[NETWORK_TIMEOUT] (upstream=N/A): Request timed out. Check network or increase timeout.` |

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

---

## Validation Errors

### Early Validation

The system performs early validation to fail fast with clear error messages:

**Token Validation:**

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

资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)

**Search Parameter Validation:**

```typescript
// First page: require start and end times
if (!input.start || !input.end) {
  throw new Error(
    "start and end times are required for the first page (unless using nextCursor for pagination)"
  );
}
```

资料来源：[src/tools/search/unified_search_v1.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/tools/search/unified_search_v1.ts)

---

## Debugging Error Handling

### Debug Mode

Enable debug logging to trace error handling flow:

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

### Safe URL Logging

The system includes `toSafeUrlForLog` to prevent token leakage in logs:

```typescript
export function toSafeUrlForLog(fullUrl: string): string {
  if (u.searchParams.has("token")) {
    u.searchParams.set("token", maskToken(u.searchParams.get("token") ?? ""));
  }
  return u.toString();
}
```

资料来源：[src/common/config.ts](https://github.com/justoneapi/justoneapi-mcp/blob/main/src/common/config.ts)

---

## Configuration Options

| Variable | Default | Description |
|----------|---------|-------------|
| `JUSTONEAPI_TOKEN` | *(required)* | Your JustOneAPI token |
| `JUSTONEAPI_BASE_URL` | `https://api.justoneapi.com` | API endpoint |
| `JUSTONEAPI_TIMEOUT_MS` | `20000` | Request timeout (milliseconds) |
| `JUSTONEAPI_RETRY` | `1` | Number of retries after first attempt |
| `JUSTONEAPI_DEBUG` | `false` | Enable debug logging to stderr |

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

---

## Best Practices

1. **Handle Rate Limits** — Implement exponential backoff when receiving `RATE_LIMITED`
2. **Check Token Validity** — Ensure `JUSTONEAPI_TOKEN` is active before heavy usage
3. **Monitor Quotas** — Track `DAILY_QUOTA_EXCEEDED` errors to avoid service interruption
4. **Enable Debug Mode** — Use `JUSTONEAPI_DEBUG=true` when troubleshooting
5. **Use Pagination** — Leverage `nextCursor` for large result sets to avoid timeout issues

---

---

## Doramagic 踩坑日志

项目：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

<!-- canonical_name: justoneapi/justoneapi-mcp; human_manual_source: deepwiki_human_wiki -->
