Sorftime Server
FreeNot checkedRemote MCP server for read-only Sorftime Enterprise API access, enabling product, category, and keyword data queries with per-user JWT authentication and audit
About
Remote MCP server for read-only Sorftime Enterprise API access, enabling product, category, and keyword data queries with per-user JWT authentication and audit logging.
README
面向团队共享的 Sorftime 数据接入项目。它把同一个确定性 API 核心同时提供给受治理的 MCP Server 和完整 CLI,并用 Sorftime Research Skill 指导 AI 选择安全工具、处理澄清、控制成本和解释结果。
- MCP Server:同事和 AI 助手的统一入口;Token 集中保管,按身份审计和限流;首版仅开放免费只读能力。
- Sorftime Research Skill:负责自然语言路由、证据边界和回答规范,不持有 Token、不执行 HTTP。
- CLI:覆盖文档实际列出的全部 52 个接口,用于管理员/开发者批处理、调试、排障和应急操作。
flowchart LR
U["同事"] --> H["Codex / Claude / MCP Host"]
H --> K["Sorftime Research Skill"]
K --> M["Governed MCP Server"]
M --> C["Shared Sorftime Core"]
C --> A["Sorftime API"]
O["管理员 / 开发者"] --> L["Full CLI"]
L --> C
当前共享策略
普通用户只看到 4 个任务型工具:
| 工具 | 用途 |
|---|---|
sorftime_capabilities |
发现当前策略、站点和管理员能力 |
sorftime_list_monitors |
列出既有关键词、榜单和 ASIN 订阅监控 |
sorftime_get_monitoring_results |
读取明确任务/批次/订阅标识对应的既有结果 |
sorftime_check_quota |
查看共享账户全局 Coin 与 Request 状态 |
首版不开放付费查询、Coin 扣费调用、实时/AI/采集任务创建、监控增删改或 MCP raw_call。管理员仍可在独立运维流程中使用 CLI;Skill 不会替终端用户绕过 MCP 调 CLI。
可选管理员 MCP 工具也保持免费只读,并且只有在 MCP_ENABLE_ADMIN_TOOLS=true 且身份角色为 admin 时才会出现在工具列表中。
文档入口
| 内容 | 文档 |
|---|---|
| 使用、安装、MCP/Skill/CLI 入口 | 本 README |
| 系统分层、身份、策略和请求链路 | 架构设计 |
| MCP 与 Skill 的协作协议 | MCP × Skill 联动 |
| 身份网关、Secret、容器和上线清单 | 部署与生产检查 |
| Codex/AI 开发规则(不是用户文档) | AGENTS.md |
| Claude Code 项目路由 | CLAUDE.md |
MCP 快速开始
要求 Node.js 20+ 与 pnpm 11:
corepack enable
pnpm install --frozen-lockfile
cp .env.example .env
在 .env 中配置服务端 SORFTIME_ACCOUNT_SK。不要把 Token 放进客户端配置或分发给同事。
本地 Streamable HTTP:
pnpm dev:mcp:http
# MCP: http://127.0.0.1:3000/mcp
# health: http://127.0.0.1:3000/healthz
# ready: http://127.0.0.1:3000/readyz
本地 stdio:
pnpm build
pnpm start:mcp:stdio
通用 stdio Host 配置:
{
"mcpServers": {
"sorftime": {
"command": "node",
"args": ["/absolute/path/to/sorftime-mcp/dist/mcp/stdio.js"],
"env": {
"SORFTIME_ACCOUNT_SK_FILE": "/secure/path/sorftime-account-sk",
"MCP_STDIO_SUBJECT": "local-operator",
"MCP_STDIO_TENANT": "local",
"MCP_STDIO_ROLE": "reader"
}
}
}
}
stdio 只适合本机/单身份运行;正式团队共享建议使用公司 OAuth/OIDC 网关和 trusted_headers 模式。详细生产要求见 部署文档。
安装 Skill:
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
mkdir -p "$CODEX_HOME/skills"
cp -R skills/sorftime-research "$CODEX_HOME/skills/sorftime-research"
重新加载 Host 并连接 MCP 后,可显式调用 $sorftime-research。
CLI 要求与安装
- Node.js 20 or later
- pnpm 11 (the repository pins
[email protected])
Build and install from this repository:
corepack enable
pnpm install --frozen-lockfile
pnpm build
npm install -g .
sorftime --version
For local development, no global install is required:
pnpm exec tsx src/cli.ts --help
pnpm typecheck
pnpm lint
pnpm test
pnpm build
pnpm check runs type checking, linting, tests, and the production build in sequence.
CLI 认证
The CLI needs a Sorftime credential for API calls. Never put the real value in source code, a committed .env file, command arguments, screenshots, or issue reports.
Interactive login uses a hidden prompt:
sorftime auth login
sorftime auth status
Login stores the credential in credentials.json in the CLI config directory with mode 0600; the directory is created with mode 0700. This avoids placing the credential in process arguments. Existing credentials from older releases in macOS Keychain remain readable and can be removed with auth logout.
For scripts, pass the credential through standard input rather than a command-line argument:
printf '%s' "$SORFTIME_ACCOUNT_SK" | sorftime auth login --token-stdin
You may also use an environment-only credential without saving it:
read -rsp 'Sorftime credential: ' SORFTIME_ACCOUNT_SK; echo
export SORFTIME_ACCOUNT_SK
sorftime auth status
Remove saved credentials with:
sorftime auth logout
Credential lookup order is:
SORFTIME_ACCOUNT_SK- an existing macOS Keychain item from an older release
- the mode-
0600credential file
Set SORFTIME_CREDENTIAL_STORE=file to disable lookup of an older Keychain item. auth status reports only whether a credential is available and its source; it never prints the value.
CLI 快速开始
List supported marketplaces and all implemented endpoints:
sorftime domains
sorftime endpoints
sorftime endpoints --group product
sorftime endpoints --json > endpoints.json
Run a typed command:
sorftime --domain us --output json product get \
--asin B000000001 B000000002 \
--trend 2
Typed flags use kebab-case, while the CLI sends the API's exact field spelling and capitalization. For example, --node-id becomes NodeId, and the documented --query-start becomes QueryStart.
Each command has endpoint-specific help, including required parameters, allowed values, and documented cost:
sorftime product get --help
sorftime monitor keyword-update --help
Commands and endpoint coverage
Utility commands:
| Command | Purpose |
|---|---|
auth login/status/logout |
Manage and inspect credential availability |
config list/path/get/set/unset |
Manage non-secret defaults |
domains |
List 14 marketplace IDs, codes, aliases, and history support |
endpoints [--group GROUP] [--json] |
List the complete 52-endpoint catalog and costs |
api call <endpoint> |
Call a documented or future endpoint with a raw JSON object |
Typed API commands are organized into six groups:
| Group | Count | Commands |
|---|---|---|
category |
4 | tree, best-sellers, products, trend |
product |
12 | get, search, sales-volume, variation-history, realtime-start, realtime-status, reviews-collect, reviews-status, reviews-list, similar-start, similar-status, similar-results |
keyword |
12 | list, search-results, get, search-trend, by-category, by-asin, product-ranking, asin-ranking, extend, favorite-add, favorite-change, favorite-list |
monitor |
17 | keyword-create, keyword-list, keyword-update, keyword-runs, keyword-run-data, best-seller-create, best-seller-list, best-seller-delete, best-seller-data, seller-create, seller-list, seller-update, seller-runs, seller-run-data, asin-update, asin-list, asin-data |
agent |
4 | product, category, status, result |
account |
3 | coins, coin-stream, request-stream |
sorftime endpoints --json is the authoritative machine-readable inventory. It includes the exact API endpoint name, group, CLI command, cost text, parameters, special timeout, pagination support, retry risk, and whether the source documentation omitted the body schema.
Typed and raw JSON input
Typed flags
Values are validated and converted according to the endpoint catalog: integers, numeric ranges, enum choices, dates, months, arrays, JSON objects, and image inputs.
sorftime --domain de category trend \
--node-id 123456 \
--trend-index 0
sorftime keyword list \
--pattern '{"RankCondition":[1,1000]}' \
--page-index 1 \
--page-size 20
For a JSON-valued typed option, prefix a path with @ to read the value from a file:
sorftime keyword list --pattern @./keyword-pattern.json
Image search accepts an existing data URI or @path; local .jpg, .jpeg, .png, .webp, and .gif files receive the corresponding MIME type and are Base64-encoded into the JSON request:
sorftime --domain us product similar-start --image @./product.jpg
Verbose diagnostics redact image data. Local image files are capped at 10 MiB as a memory-safety guard.
Raw request bodies
Every typed endpoint command, plus api call, supports one of these mutually exclusive body sources:
sorftime product search \
--data '{"Page":1,"Query":1,"QueryType":"3","Pattern":"example-brand"}'
sorftime keyword favorite-change --data-file ./favorite-change.json
printf '%s\n' '{"Keyword":"power bank"}' | \
sorftime keyword get --stdin
sorftime --domain us api call ProductQuery --data-file ./request.json
Raw input must be a JSON object. --data-file and --stdin are limited to 25 MiB. Typed flags may be combined with a raw body; typed values overwrite fields with the same exact API key.
api call accepts case-insensitive endpoint names and unambiguous CLI command names. If a command name exists in more than one group (such as get), use the exact API endpoint name. An unknown endpoint name must start with a letter and contain only letters and digits.
Configuration and precedence
Store only non-secret defaults in the config file:
sorftime config set domain us
sorftime config set timeout 120
sorftime config set output json
sorftime config list
sorftime config path
sorftime config get domain
sorftime config unset output
Supported config keys are domain, base-url, timeout, and output. Attempts to store a credential through config set are rejected.
| Setting | Highest to lowest precedence | Fallback |
|---|---|---|
| Marketplace | --domain → SORFTIME_DOMAIN → config domain |
us |
| Base URL | --base-url → SORFTIME_BASE_URL → config base-url |
https://standardapi.sorftime.com/api/ |
| Timeout | --timeout → SORFTIME_TIMEOUT → config timeout → endpoint default |
60 seconds |
| Retries | --retries → SORFTIME_RETRIES |
0 |
| Output | --output → SORFTIME_OUTPUT → config output |
table on a TTY, otherwise json |
CategoryTree has a 300-second endpoint default and image search has a 120-second default, unless a higher-precedence timeout overrides it. Valid timeouts are 1–3600 seconds; retry count is 0–5.
The config directory is selected in this order:
SORFTIME_CONFIG_DIR$XDG_CONFIG_HOME/sorftime~/.config/sorftime
The canonical API base URL is already configured. Override it only for a trusted proxy or local test server; see Security.
Marketplaces and history guardrails
--domain accepts the numeric ID, two-letter code, or a listed alias. Use sorftime domains for the complete mapping.
India, UAE, Australia, Brazil, and Saudi Arabia are documented as not supporting history backfill. For those marketplaces the CLI blocks historical fields on CategoryRequest, ProductRequest, AsinSalesVolume, KeywordProductRanking, and ASINKeywordRanking.
--force bypasses only this client-side marketplace history guard. It does not bypass server authorization, required parameters, cost, or quota, and it is not a confirmation or dry-run mechanism.
Output
Select a format globally with --output/-o:
| Format | Behavior |
|---|---|
json |
Pretty JSON; add --compact for one line |
jsonl |
One JSON value per array item, or one line for a scalar/object |
yaml |
YAML serialization |
csv |
Rows from an array/object; nested values remain JSON inside cells |
table |
Human-readable columns, truncated to 200 rows and 40 characters per cell |
raw |
Strings without JSON quoting; other values as compact JSON |
Examples:
# Extract Data/data case-insensitively, then select the first item.
sorftime --output json --data-only --select 0 product get --asin B000000001
# Select an exact dot-separated path; numeric segments index arrays.
sorftime --output yaml --select Data.Items product search \
--query 1 --query-type 3 --pattern example-brand
# Write through a temporary file and atomically rename it into place.
sorftime --output json --output-file ./category-tree.json category tree
# A path of "-" writes to stdout.
sorftime --output csv --data-only --output-file - keyword list
--select is case-sensitive and runs after --data-only. A missing path is a validation error. Use JSON or an output file for large responses; table display is intentionally abbreviated.
Documented list endpoints support bounded automatic pagination:
sorftime --all-pages --max-pages 50 --page-delay 250 \
--output json --data-only keyword list --page-size 200
--all-pages starts at the supplied Page/PageIndex (or 1), stops after a short page, and adds _pagination metadata when retaining the response envelope. --max-pages defaults to 100 and --page-delay is milliseconds. Endpoints whose result-array or page-size behavior is not documented reject --all-pages instead of guessing. Exact raw output cannot be combined with pagination.
Successful API data goes to stdout. Errors and --verbose diagnostics go to stderr, making stdout safe to pipe when the selected output format is machine-readable.
Errors and exit status
The client accepts both Code and code, treats business code 0 as success, and keeps the server's original successful payload for output. Known business errors receive a readable message.
| Exit | Meaning |
|---|---|
0 |
Success, help, or version output |
1 |
Unexpected error or command-line parser error |
2 |
CLI validation or invalid local configuration |
3 |
Missing credential; also used by unauthenticated auth status |
4 |
Network, timeout, cancellation, or non-2xx HTTP response |
5 |
Sorftime business error (Code/code is non-zero) |
130 |
Interrupted with Ctrl-C/SIGINT |
HTTP errors and Sorftime business errors are separate: for example, an HTTP 401 is exit 4, while an HTTP-success response containing business Code: 401 is exit 5.
Retries, quota, and side effects
Retries default to zero because every Sorftime endpoint is invoked with POST, including reads. --retries N retries transport failures, HTTP 408/429/5xx responses, and Sorftime's per-minute throttle code 501 with exponential backoff. A valid HTTP Retry-After header is honored up to 30 seconds. Other business errors and other HTTP 4xx responses are not retried.
sorftime --retries 2 account coins
Only enable retries when duplicate processing is acceptable. If the server completed a request but the response was lost, retrying may consume quota again, start a second task, repeat an update, or repeat a delete. The CLI displays documented cost in command help and endpoints, but it does not currently estimate the final bill, prompt for confirmation, or provide a dry-run mode. Mutating and paid commands execute immediately.
For known task-creating and mutating endpoints, --retries is rejected unless you also pass --retry-unsafe. That second flag is an explicit acknowledgment that duplicate state changes or charges are possible.
Particularly important costs and side effects include:
- historical category requests, long product trends, and batch ASIN lookups;
- review collection and monitoring, which can consume coin points;
- realtime crawls, image search, and AI analysis;
- favorite, subscription, task update, pause/start, and delete commands.
Known source-document limitations
The CLI deliberately avoids inventing undocumented API behavior:
- The source summary says 50 endpoints, but its numbered body contains 52. This CLI implements all 52; the difference is two additional monitoring endpoints.
- Many source URLs misspell the host as
sortime. The CLI uses the working canonicalstandardapi.sorftime.combase. ChangeFavoriteKeyword,GetFavoriteKeyword,ProductSellerTasks, andProductSellerTaskUpdatehave no documented body schema and therefore expose no guessed typed body flags. Use--data,--data-file, or--stdinwhen a body is required;GetFavoriteKeywordalso has unknown documented cost.ProductQuerydocuments multi-condition mode without defining its object structure. Use raw JSON for that mode.KeywordQuery.Patternis only partially documented. It is exposed as a JSON value rather than a guessed schema.- Response envelopes vary in capitalization and most endpoint response schemas are absent. The client performs tolerant envelope checks, preserves unknown fields, and offers
--output raw/JSON output. - Pagination metadata is mostly undocumented. Automatic pagination is therefore limited to endpoints with a documented page size and stops on short pages; use
--max-pagesas a hard safety cap. - Asynchronous APIs use different status lookup keys and incomplete status schemas. Use each family's explicit start, status, and result commands; there is no generic wait/poll command.
- File export/download behavior is not documented. Image search accepts local input, but returned image URLs and AI HTML/Markdown are not downloaded automatically.
Consult sorftime <group> <command> --help and sorftime endpoints --json for what the CLI can validate locally. Server behavior and billing remain authoritative.
Security
- MCP 的 Sorftime Token 只存在于服务端环境或挂载的 Secret 文件;普通用户和 Skill 永远不接触它。
- HTTP 身份来自逐用户 API Key 或受信公司网关注入的身份头。Session 会绑定身份,工具参数不能伪造用户、租户或角色。
- MCP 审计只记录身份、工具、固定端点、站点、输入指纹、决策和耗时,不记录完整关键词/ASIN 列表、请求体、Token 或上游结果。
- 当前限流、Session 和 billing circuit 是单进程状态;多副本部署前必须增加共享存储或明确使用粘性路由和单副本策略。
- Prefer
sorftime auth loginor an injected environment secret. Never include a real credential in shell arguments, committed files, logs, test fixtures, or support bundles. --verbosenever prints the credential and replaces image payloads with a length marker. Raw request fields other than image data are printed, so do not place unrelated secrets in a request body when verbose mode is enabled.- Custom
--base-url,SORFTIME_BASE_URL, and configbase-urlvalues receive the credential. Use only endpoints you control and trust. The CLI requires HTTPS, except that plain HTTP is allowed forlocalhost,127.0.0.1, and::1testing. - Avoid enabling retries for paid or mutating calls unless duplicate execution is safe.
- Keep output files private: product, keyword, review, seller, usage, and AI results may contain commercially sensitive data.
- Credential and config files are written atomically with restrictive permissions, but environment variables may still be visible to same-user processes or CI logs depending on the operating system and runner.
项目结构
.
├── src/core/ # CLI 与 MCP 共用 API core / governance
├── src/mcp/ # 工具、策略、身份、审计、限流与 transport
├── src/cli.ts + src/runner.ts # 完整运维 CLI
├── skills/sorftime-research/ # AI 路由与解释 Skill
├── docs/ # 架构、联动和部署文档
├── test/ # CLI/Core/MCP/HTTP/Skill 合约测试
├── AGENTS.md # AI 编码代理权威项目说明
└── README.md # 人类使用者和运维人员文档
License
MIT. See LICENSE.
Installing Sorftime Server
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/ccchenhuohuo/sorftime-mcpFAQ
Is Sorftime Server MCP free?
Yes, Sorftime Server MCP is free — one-click install via Unyly at no cost.
Does Sorftime Server need an API key?
No, Sorftime Server runs without API keys or environment variables.
Is Sorftime Server hosted or self-hosted?
A hosted option is available: Unyly runs the server in the cloud, no local setup required.
How do I install Sorftime Server in Claude Desktop, Claude Code or Cursor?
Open Sorftime Server on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectCompare Sorftime Server with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
