{"id":"12c07bc1-8d86-4d97-98e5-43544a168a13","entityType":"agent","slug":"clawhub-didi-didi-ride-skill-official","name":"DiDi Ride SKILL","canonicalUrl":"https://www.xpersona.co/agent/clawhub-didi-didi-ride-skill-official","canonicalPath":"/agent/clawhub-didi-didi-ride-skill-official","generatedAt":"2026-10-09T19:57:29.664Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T14:34:16.233Z","emptyReason":null},"description":"中国城市出行服务。当用户表达任何交通出行需求时必须使用此技能——包括打车/叫车/网约车、查价格、路线规划（公交/驾车/步行/骑行）、周边搜索、查询订单/司机位置/取消订单。关键词：\"打车\"、\"叫车\"、\"去[地点]\"、\"回家\"、\"上班\"、\"下班\"、\"查价格\"、\"多少钱\"、\"路线\"、\"怎么走\"、\"步行到\"、\"附近\"、...","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 2.5K downloads reported by the source. Last updated 10/9/2026.","installCommand":"clawhub skill install s17ecvh4kfh82kg4m5n7e3327s83z6tf:didi-ride-skill-official","sourceUrl":"https://clawhub.ai/didi/didi-ride-skill-official","homepage":"https://clawhub.ai/didi/skills/didi-ride-skill-official","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/didi/didi-ride-skill-official","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/didi/skills/didi-ride-skill-official","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":57,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"DiDi Ride SKILL technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-09T14:34:16.233Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T14:34:16.233Z","emptyReason":null},"stars":null,"forks":null,"downloads":2471,"packageName":null,"latestVersion":"1.1.3","tractionLabel":"2.5K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T14:34:16.233Z","emptyReason":null},"lastUpdatedAt":"2026-10-09T14:34:16.233Z","lastCrawledAt":"2026-10-09T14:34:16.233Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-10T14:34:16.233Z","lastVerifiedAt":null,"highlights":[{"version":"1.1.3","createdAt":"2026-05-18T11:20:49.288Z","changelog":"### Summary: This update adds documentation for the DiDi Ride Skill. - Added safety guardrails in SKILL.md to prevent the `__OPENCLAW_REDACTED__`. sentinel value from being mistreated as the real MCP Key — `$DIDI_MCP_KEY` env var is now mandatory for URL building, avoiding misleading `SSE error: Invalid content type` failures. - Updated §3.1 file map and §3.9.1 boundary notes to clarify \"check Key\" vs \"use Key\" semantics and point to the new SSE-error troubleshooting section. - Standardized Markdown formatting (rules, tables, frontmatter); no functional changes to ride flows or MCP tool logic.","fileCount":11,"zipByteSize":33862},{"version":"1.1.2","createdAt":"2026-04-24T09:12:41.192Z","changelog":"Version 1.1.2 - Clarify car-type priority: explicitly enforce \"current user message > PREFERENCE.md scenario preference > ask user\" order in SKILL.md §3.4, with exact productCategory matching (Express=1, Premier=8) and no silent fallback to similar vehicle types. - Rewrite metadata-unavailable handling (SKILL.md §3.7 / §3.8): when channel/chat_id is missing, only skip cron creation instead of abandoning the whole flow — address resolution, price estimate and order display must still complete normally. - Enforce multi-candidate address confirmation (SKILL.md §3.4 step 2): if maps_textsearch returns ≥2 similar locations, must list at least 3 options for the user to pick; never auto-select or show only one. - Require file-based preference persistence (SKILL.md §3.5): preference updates must use Edit/Write tools with a Read-back verification step; forbid verbal-only \"saved!\" replies without actually writing to assets/PREFERENCE.md. - Make caller_car_phone explicitly optional (SKILL.md §3.2.8 + PREFERENCE.md note): if not provided and PREFERENCE default is empty, omit the parameter and proceed — do not repeatedly ask the user for a phone number. - Add taxi_create_order parameter hygiene (SKILL.md §3.10): only accept estimate_trace_id, product_category, caller_car_phone; forbid passing taxi_estimate's coordinate fields (from_lat/from_lng/from_name/to_*) into create_order to keep call audit clean. - Add a \"simplification principle for reasoning models\" to §3.4: take the user's current car-type instruction at face value, do not over-explore branches or list multiple weigh-in options in a single turn. - Reorganize origin/destination handling (SKILL.md §3.2.7) into four labeled blocks (coordinate source / missing-info fallback / alias matching / confirmation rule), and strengthen the rule \"scan the full alias table\" to avoid missing user-added aliases like \"妈妈家\" / \"儿子学校\". - Split the MCP KEY section (SKILL.md §3.9) into three focused subsections: 3.9.1 status check, 3.9.2 key persistence, 3.9.3 missing/auth-failure guidance. - Declare mcporter URL direct-call mode (SKILL.md §3.2.3): forbid creating or modifying config/mcporter.json; add explicit parameter-name guidance (e.g. keywords not keyword, city not region, six-field from_*/to_* for taxi_estimate) with StatusCode=400 troubleshooting pointer. - Refine references/workflow.md Phase 3: \"real-time order allowed to send directly\" → when user specifies a car type directly send; when user does not specify and preference is empty, MUST show estimate result first for user to pick — no default selection. - Expand references/error_handling.md: add unified handling for -32xxx error codes, parameter-error root-cause diagnosis, mcporter.json validation error workaround, and taxi_create_order failure message template.","fileCount":8,"zipByteSize":23628},{"version":"1.1.1","createdAt":"2026-04-03T07:25:42.501Z","changelog":"v1.1.1: * refine skill descriptions to prevent misuse and add error handling","fileCount":8,"zipByteSize":18845},{"version":"1.1.0","createdAt":"2026-03-31T11:31:24.939Z","changelog":"didi-ride-skill 1.1.0 initial release: - Provides ride-hailing, fare queries, order tracking, driver location, route planning, and nearby searches for Chinese cities via DiDi MCP API. - Triggers for any commute or transportation demand—must activate on all such requests (e.g., \"打车\", \"去[地点]\", \"路线\", \"多少钱\", etc.). - Strict user confirmation and preference handling logic for ambiguous addresses and order cancellations. - Supports real-time and scheduled bookings with detailed cron job templates for order follow-up. - Offers comprehensive agent instructions for setup, API usage, preference memory, and troubleshooting. - Requires prior installation of mcporter tool and obtaining/configuring DIDI_MCP_KEY.","fileCount":8,"zipByteSize":18041}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17ecvh4kfh82kg4m5n7e3327s83z6tf:didi-ride-skill-official","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s17ecvh4kfh82kg4m5n7e3327s83z6tf:didi-ride-skill-official` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/didi/didi-ride-skill-official before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-didi-didi-ride-skill-official/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-didi-didi-ride-skill-official/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-didi-didi-ride-skill-official/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-didi-didi-ride-skill-official/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-didi-didi-ride-skill-official/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-didi-didi-ride-skill-official/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-09T19:57:29.661Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-didi-didi-ride-skill-official/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-didi-didi-ride-skill-official/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-didi-didi-ride-skill-official/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-didi-didi-ride-skill-official/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T14:34:16.233Z","emptyReason":null},"readme":"Skill: DiDi Ride SKILL\n\nOwner: didi\n\nSummary: 中国城市出行服务。当用户表达任何交通出行需求时必须使用此技能——包括打车/叫车/网约车、查价格、路线规划（公交/驾车/步行/骑行）、周边搜索、查询订单/司机位置/取消订单。关键词：\"打车\"、\"叫车\"、\"去[地点]\"、\"回家\"、\"上班\"、\"下班\"、\"查价格\"、\"多少钱\"、\"路线\"、\"怎么走\"、\"步行到\"、\"附近\"、...\n\nTags: latest:1.1.3\n\nVersion history:\n\nv1.1.3 | 2026-05-18T11:20:49.288Z | user\n\n### Summary:  \nThis update adds documentation for the DiDi Ride Skill.\n\n- Added safety guardrails in SKILL.md to prevent the `__OPENCLAW_REDACTED__`. sentinel value from being mistreated as the real MCP Key — `$DIDI_MCP_KEY` env var is now mandatory for URL building, avoiding misleading `SSE error: Invalid content type` failures.                                                                   \n  - Updated §3.1 file map and §3.9.1 boundary notes to clarify \"check Key\" vs \"use Key\" semantics and point to the new SSE-error troubleshooting section.\n  - Standardized Markdown formatting (rules, tables, frontmatter); no functional changes to ride flows or MCP tool logic.\n\nv1.1.2 | 2026-04-24T09:12:41.192Z | user\n\nVersion 1.1.2\n\n- Clarify car-type priority: explicitly enforce \"current user message > PREFERENCE.md scenario preference > ask user\" order in SKILL.md §3.4, with exact productCategory matching (Express=1, Premier=8) and no silent fallback to similar vehicle types.\n- Rewrite metadata-unavailable handling (SKILL.md §3.7 / §3.8): when channel/chat_id is missing, only skip cron creation instead of abandoning the whole flow — address resolution, price estimate and order display must still complete normally.\n- Enforce multi-candidate address confirmation (SKILL.md §3.4 step 2): if maps_textsearch returns ≥2 similar locations, must list at least 3 options for the user to pick; never auto-select or show only one.\n- Require file-based preference persistence (SKILL.md §3.5): preference updates must use Edit/Write tools with a Read-back verification step; forbid verbal-only \"saved!\" replies without actually writing to assets/PREFERENCE.md.\n- Make caller_car_phone explicitly optional (SKILL.md §3.2.8 + PREFERENCE.md note): if not provided and PREFERENCE default is empty, omit the parameter and proceed — do not repeatedly ask the user for a phone number.\n- Add taxi_create_order parameter hygiene (SKILL.md §3.10): only accept estimate_trace_id, product_category, caller_car_phone; forbid passing taxi_estimate's coordinate fields (from_lat/from_lng/from_name/to_*) into create_order to keep call audit clean.\n- Add a \"simplification principle for reasoning models\" to §3.4: take the user's current car-type instruction at face value, do not over-explore branches or list multiple weigh-in options in a single turn.\n- Reorganize origin/destination handling (SKILL.md §3.2.7) into four labeled blocks (coordinate source / missing-info fallback / alias matching / confirmation rule), and strengthen the rule \"scan the full alias table\" to avoid missing user-added aliases like \"妈妈家\" / \"儿子学校\".\n- Split the MCP KEY section (SKILL.md §3.9) into three focused subsections: 3.9.1 status check, 3.9.2 key persistence, 3.9.3 missing/auth-failure guidance.\n- Declare mcporter URL direct-call mode (SKILL.md §3.2.3): forbid creating or modifying config/mcporter.json; add explicit parameter-name guidance (e.g. keywords not keyword, city not region, six-field from_*/to_* for taxi_estimate) with StatusCode=400 troubleshooting pointer.\n- Refine references/workflow.md Phase 3: \"real-time order allowed to send directly\" → when user specifies a car type directly send; when user does not specify and preference is empty, MUST show estimate result first for user to pick — no default selection.\n- Expand references/error_handling.md: add unified handling for -32xxx error codes, parameter-error root-cause diagnosis, mcporter.json validation error workaround, and taxi_create_order failure message template.\n\nv1.1.1 | 2026-04-03T07:25:42.501Z | user\n\nv1.1.1:\n\n*  refine skill descriptions to prevent misuse and add error handling\n\nv1.1.0 | 2026-03-31T11:31:24.939Z | user\n\ndidi-ride-skill 1.1.0 initial release:\n\n- Provides ride-hailing, fare queries, order tracking, driver location, route planning, and nearby searches for Chinese cities via DiDi MCP API.\n- Triggers for any commute or transportation demand—must activate on all such requests (e.g., \"打车\", \"去[地点]\", \"路线\", \"多少钱\", etc.).\n- Strict user confirmation and preference handling logic for ambiguous addresses and order cancellations.\n- Supports real-time and scheduled bookings with detailed cron job templates for order follow-up.\n- Offers comprehensive agent instructions for setup, API usage, preference memory, and troubleshooting.\n- Requires prior installation of mcporter tool and obtaining/configuring DIDI_MCP_KEY.\n\nArchive index:\n\nArchive v1.1.3: 11 files, 33862 bytes\n\nFiles: assets/PREFERENCE.md (3155b), package.json (323b), README.en.md (12904b), README.md (12670b), references/api_references.md (8174b), references/error_handling.md (9901b), references/setup.md (2478b), references/workflow.md (6533b), skill-card.md (2420b), SKILL.md (21924b), _meta.json (143b)\n\nFile v1.1.3:SKILL.md\n\n---\nname: didi-ride-skill\ndescription: 中国城市出行服务。当用户表达任何交通出行需求时必须使用此技能——包括打车/叫车/网约车、查价格、路线规划（公交/驾车/步行/骑行）、周边搜索、查询订单/司机位置/取消订单。关键词：\"打车\"、\"叫车\"、\"去[地点]\"、\"回家\"、\"上班\"、\"下班\"、\"查价格\"、\"多少钱\"、\"路线\"、\"怎么走\"、\"步行到\"、\"附近\"、\"周边\"、\"司机\"、\"订单\"、\"查询订单\"。注意：即使用户未明确说\"打车\"，只要涉及从A地到B地、通勤、或交通方式选择，都应触发。不触发场景：开发打车应用、使用其他导航app、订外卖、查公交时刻表、股票/财报查询。\nhomepage: https://mcp.didichuxing.com\nmetadata:\n  { \"openclaw\": { \"emoji\": \"🚕\", \"always\": true, \"requires\": { \"bins\": [\"openclaw\", \"mcporter\"], \"env\": [\"DIDI_MCP_KEY\"] }, \"primaryEnv\": \"DIDI_MCP_KEY\", \"install\": [{ \"id\": \"node\", \"kind\": \"node\", \"package\": \"mcporter\", \"bins\": [\"mcporter\"], \"label\": \"Install mcporter (node)\" }] } }\n---\n\n# 滴滴出行服务 (DiDi Ride Skill)\n\n通过 DiDi MCP Server API 提供打车、查询订单、司机位置、预约叫车、路线规划、周边搜索能力。\n\n---\n\n## 1. 快速开始（2 分钟）\n\n### 1.1 获取 MCP KEY\n\n**方式一：用「滴滴出行App」扫码（推荐，最快）**\n\n![滴滴出行APP扫码获取MCP Key，解锁一键打车](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n> ⚠️ **Agent 注意**：用户客户端无法渲染 Markdown 图片，**禁止直接输出上方图片语法**。需向用户发送二维码时，执行 `### 3.9 MCP KEY 与配置` 中的 `openclaw message send` 命令发图。\n\n打开滴滴出行 App，扫描二维码，即可快速获取 MCP Key。\n\n**方式二：访问官网**\n\n访问 https://mcp.didichuxing.com/claw 获取您的 MCP Key。\n\n### 1.2 配置 Key\n\n**方式一：对话中输入（推荐）**\n\n直接在对话中告诉我您的 MCP Key，我会帮您配置：\n\n```\n你: 我的 MCP Key 是 xxxxxx\n```\n\n**方式二：OpenClaw 配置文件**\n\n编辑 `~/.openclaw/openclaw.json`，添加：\n\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"didi-ride-skill\": {\n        \"enabled\": true,\n        \"apiKey\": \"你的MCP_KEY\"  // apiKey 是 OpenClaw 标准字段名，存储的值就是滴滴平台的 MCP KEY\n      }\n    }\n  }\n}\n```\n\n### 1.3 开始使用\n\n配置完成后，直接对话即可：\n\n```\n你: 打车去北京西站\n你: 帮我查一下从国贸到三里屯的路线\n你: 查询订单\n```\n\n首次使用时，OpenClaw 会提示安装 mcporter 工具。\n\n---\n\n## 2. 用户指南\n\n本 Skill 支持以下操作：\n\n- **打车**：直接说\"打车去[地点]\"、\"回家\"、\"上班\"\n- **查价**：查一下从 A 到 B 多少钱\n- **查询订单**：输入「查询订单」了解当前订单状态（司机位置、行程进度等）\n- **司机位置**：司机在哪里、多久到\n- **预约出行**：\"15分钟后打个车\"、\"明天9点去机场\"\n- **路线规划**：驾车/公交/步行/骑行路线\n- **取消订单**：取消当前订单\n\n---\n\n## 3. Agent 执行指令\n\n以下内容为 AI 执行参考，用户可忽略。\n\n### 3.1 文件地图 \n\n按需读取以下文件，不要猜测未读过的内容：\n\n| 文件 | 用途 | 何时读取 |\n|------|------|----------|\n| `SKILL.md` | 触发、主流程、硬性门禁、查询订单规则、预约出行规则 | 每次触发必读 |\n| `references/workflow.md` | 分阶段详细流程与命令范式 | 需要实现细节时读 |\n| `references/api_references.md` | MCP 函数签名与参数定义 | 每次调用工具前**必须**核对 |\n| `references/error_handling.md` | create_order 失败提示、mcporter 常见错误、统一错误码、参数错误排查、apiKey 占位符泄漏 | ⚠️ 遇到任何调用失败（HTTP error / StatusCode=400 / `-32xxx` 错误码 / `Unknown MCP server` / `Missing KEY parameter` / `SSE error: Invalid content type`）必须读取此文件 |\n| `references/setup.md` | 安装 mcporter、配置 MCP KEY 的完整步骤 | 用户询问安装/配置问题时读 |\n| `assets/PREFERENCE.md` | 地址别名/车型/手机号偏好 | 用户提到别名地址（家、公司、妈妈家等）、车型、手机号，或未明确给出起终点时**必须**读取。别名匹配规则见执行前检查第 7 条 |\n\n### 3.2 执行前检查\n\n1. **检查 mcporter**：若 `mcporter` 不存在（`command not found`），停止并引导用户阅读 `references/setup.md`。没有 mcporter 就无法调用任何 MCP 工具，后续任何流程都无法执行。\n\n2. **检查 Key**：执行 `openclaw config get skills.entries.didi-ride-skill.apiKey`，若输出为空或非 `__OPENCLAW_REDACTED__`，按 `### 3.9 MCP KEY 与配置` 流程引导。Key 缺失时 mcporter 的报错信息具有误导性，不要尝试绕过。\n   - ⚠️ **若 Key 已配置（返回 `__OPENCLAW_REDACTED__`）但 mcporter 仍报 `Missing KEY parameter`**：**不是 Key 失效**，**禁止向用户索要 Key**。排查步骤见 `references/error_handling.md` 中的「mcporter Missing KEY parameter」章节。\n   - ⚠️ **`__OPENCLAW_REDACTED__` 是\"已配置\"哨兵值、不是真实 Key**：禁止从 `openclaw config get`（含 `--raw`）提取 Key 字面量；URL 中 `?key=...` 必须固定用 `$DIDI_MCP_KEY`。误把哨兵拼进 URL 会触发 `SSE error: Invalid content type`，详见 error_handling.md 同名章节。\n\n3. **mcporter.json 注意事项**：本 skill 使用 URL 直连模式，**不依赖 `config/mcporter.json`**，**禁止创建或修改该文件**。如果 mcporter 启动时报 JSON 校验错误（`invalid_type` / `Failed to parse JSON`），参见 `references/error_handling.md` 中的「mcporter.json 校验错误」章节。\n\n4. **mcporter 调用格式**（固定写法，不要变形）：\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" <tool> --args '{\"key\":\"value\"}'\n```\n\n**必读注意事项**：\n- `MCP_URL` 赋值和 `\"$MCP_URL\"` 引用**都必须用英文双引号**，否则 `$DIDI_MCP_KEY` 不会被 shell 展开。禁止用单引号或中文引号。\n- **禁止添加 `--server` 标志**（如 `--server didi-mcp`）。`--server` 会让 mcporter 去查找已注册的命名 server，找不到直接报 `Unknown MCP server`；即使找到了也会和 URL 参数冲突导致 `Missing tool name`。\n- **参数名必须核对 `references/api_references.md`**，不要凭记忆。常见致命错误：`keyword` → 应为 `keywords`；`region` → 应为 `city`；`from_lng/from_lat/to_lng/to_lat` → 应为 `from_name/from_lat/from_lng/to_name/to_lat/to_lng`（六字段，不是四字段）。\n- mcporter 对参数错误的报错信息为 `backend call failed: ... StatusCode=400`（**不会告诉你具体哪个参数错了**），遇到此错误第一反应是核对参数名，详见 `references/error_handling.md`。\n- 遇到不确定的参数名时，执行 `mcporter list \"$MCP_URL\"` 可以查看所有工具的完整签名。\n\n5. **参数值必须加引号**（字符串格式），包括经纬度和 `product_category` 等数字语义字段——API 只接受字符串，否则会报\"缺少必填参数\"。\n6. **先预估再下单**：`taxi_create_order` 依赖 `taxi_estimate` 返回的 `traceId`，没有 traceId 下单会失败。traceId 有时效性，过期（`-32021` 错误）需重新预估。\n7. **起终点处理**：\n\n   **坐标来源**：坐标必须来自 `maps_textsearch`，不要凭空猜测。**禁止用对话历史记忆补充起终点**——用户可能已换了地方。\n\n   **缺失补全**（按优先级）：① 读 `assets/PREFERENCE.md`，有地址别名**且值非空**则按场景推断（早晨→起点\"家\"、下班→起点\"公司\"；别名行存在但地址为空 = 未配置）→ ② 无可用别名则直接询问用户。\n\n   **别名匹配**：精确优先——\"家\"只匹配\"家\"，不匹配\"妈妈家\"；需明确含\"妈妈\"语义才匹配\"妈妈家\"。读取时**必须扫描整张表格**（到下一个 `##` 为止），不要只看默认的前两行——用户可能已追加\"妈妈家\"\"儿子学校\"\"健身房\"等自定义别名。\n\n   **确认规则**：推断的起终点、或 `maps_textsearch` 返回多个候选时，必须在主流程 step 2 向用户确认；用户明确指定且精确匹配的地点无需确认。\n\n8. **`taxi_create_order` 参数约束**：\n- 只接受三个字段：`estimate_trace_id`、`product_category`、`caller_car_phone`（可选）\n- `taxi_create_order` 的 `caller_car_phone` 未由用户提供时，从 `assets/PREFERENCE.md` 的「默认偏好」表读取；都没有就**不传该参数**，禁止在对话中反复向用户索要手机号——skill 级别已允许没有手机号直接发单，口头询问一次若用户未答应即视为\"用默认/不传\"。\n- 不要把 `taxi_estimate` 的坐标/名称字段（`from_lat` / `from_lng` / `from_name` / `to_lat` / `to_lng` / `to_name`）带入。\n\n### 3.3 用户确认策略\n\n| 场景 | 规则 |\n|------|------|\n| 打车（实时/预约） | 推断的地址或搜索返回多个候选时必须确认起终点（见主流程 step 2），用户明确指定且精确匹配时无需确认，确认后再预估下单 |\n| 取消订单 | 即使用户说了\"取消订单\"，仍必须先明确询问\"确认取消吗？\"，等用户回复确认后才能调用 `taxi_cancel_order`。用户的取消意图 ≠ 取消确认。 |\n\n### 3.4 主流程（最小可执行）\n\n1. 地址解析：`maps_textsearch`（必要时结合 `assets/PREFERENCE.md`，按执行前检查第 7 条处理）。\n2. 确认起终点：\n   - **单一精确匹配**（用户描述明确 + `maps_textsearch` 仅返回 1 个结果）→ 无需确认，直接使用；\n   - **多个候选**（`maps_textsearch` 返回 ≥2 个同名或近似地点）→ **必须列出至少前 3 个候选供用户选择**（如\"搜索到以下万达广场：1) 朝阳CBD店 2) 石景山店 3) 通州店，请问您要去哪个？\"），**不要自行代选或只展示一个**；\n   - **别名推断**（从 PREFERENCE.md 推断的起终点）→ 向用户确认 + 告知推断来源（如\"按偏好里「家」推断终点是望京 SOHO，对吗？\"）；\n   - 用户明确指定且文本精确匹配的地点 → 无需确认。用户纠正则按纠正内容重新解析。\n3. 价格预估：`taxi_estimate`，记录 `traceId`。\n4. 车型决策（优先级：**当前消息 > 偏好 > 询问用户**）：\n   - 用户在当前消息中明确指定车型（如\"叫快车\"\"帮我叫专车\"）→ 在 `taxi_estimate` 返回列表中**精确匹配**对应 `productCategory`（快车=1，专车=8），覆盖一切偏好设置；\n   - 用户未指定 → 使用 `assets/PREFERENCE.md` 中场景车型偏好的精确 `productCategory` 值；\n   - 偏好也未配置 → 向用户询问车型，不要自行推荐；\n   - 注意：快车（1）和特惠快车（201）是**不同服务等级**，不可因价格更优而自动替换；\n   - 可用车型以 `taxi_estimate` API 返回为准。若不包含指定/偏好的 `productCategory`，向用户说明并让其重新选择，不要默默用近似车型替代。\n   - ⚡ **简化原则（尤其对 reasoning 模型）**：用户在当前消息中说什么车型就用什么，不要进一步质疑或反复确认；偏好缺失时直接向用户问一次即可，不要在同一轮列出多个权衡选项让用户挑。规则很短，不要过度展开思考分支。\n5. 创建订单：`taxi_create_order`（使用最新 `traceId`）。\n   - 若此调用返回 `Streamable HTTP error: Unexpected content type: text/plain`，**立即停止流程**，按 `references/error_handling.md` 的「taxi_create_order 调用失败」章节向用户输出固定文案。禁止重试、禁止切换 Key、禁止跳过此步继续往下。\n6. 结果输出：给出订单号、起终点、车型、预估价，末尾提示 `💡 发送「查询订单」可了解当前订单状态`，并告知 `⏱️ 将在 5 分钟后自动为您回查订单状态`。\n7. ⚠️ 自动回查（必做）：根据 `### 3.8 发单后自动回查` 中的 cron 指令内容，创建定时任务，参数信息严格遵循章节内要求。此步不可省略。\n\n### 3.5 偏好设置更新\n\n当用户要求设置/记住/记一下/帮我记/保存地址别名、车型偏好或手机号时，**必须**通过文件编辑工具（`Edit` / `Write`）修改 `assets/PREFERENCE.md` 对应的 markdown 表格行。**严禁**仅以文字回复\"记住了/已保存\"而不调用文件编辑工具——偏好必须落盘到文件，口头承诺无效。\n\n**执行步骤**：\n1. `Read` 读取 `assets/PREFERENCE.md` 完整内容（注意表格可能已有用户追加的行）；\n2. 定位要更新的表格行（地址别名表 / 场景车型偏好表 / 默认偏好表）；\n3. 对地址别名：先调用 `maps_textsearch` 获取坐标，再更新表格行；\n4. 调用 `Edit`（替换单行）或 `Write`（整表重写）写入新值；\n5. **回读验证**：再次 `Read` 确认新值已落盘。若未成功，告知用户并重试。\n\n- **地址别名**（\"我家在…\"、\"公司在…\"、\"儿子的学校是…\"、\"妈妈家在…\"）：先调用 `maps_textsearch` 解析地址获取坐标，然后更新「地址别名」表——已有别名更新对应行，新别名追加新行。别名由用户定义，不限于\"家\"\"公司\"。\n- **场景车型**（\"上班用快车\"、\"下班用特惠和快车\"）：更新「场景车型偏好」表对应行。品类代码参考表底注释，多车型用英文逗号分隔（如 `1,201`）。\n- **叫车手机号**（\"我的手机号是…\"）：更新「默认偏好」表中的叫车手机号行。\n- **创建订单时**：若 PREFERENCE.md 中配置了叫车手机号，将其作为 `caller_car_phone` 参数传入 `taxi_create_order`，`caller_car_phone` 为可选参数，若未配置则不传。\n\n### 3.6 查询订单\n\n触发词：`查询订单` / `查询订单 <orderId>`\n\n订单号来源（优先级从高到低）：\n1. 用户消息中明确给出；\n2. 当前对话上下文中最近一次创建的订单号；\n3. 以上均无时，向用户询问。\n\n调用命令：\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" taxi_query_order --args '{\"order_id\":\"ORDER_ID\"}'\n```\n\n#### 3.6.1 状态码与输出规则\n\n| code | 含义 | 必须输出 |\n|------|------|----------|\n| 0 | 匹配中 | ⏳ 正在为您匹配司机，请稍候 |\n| 1 | 司机已接单 | **必须展示**：司机姓名、车型、车牌、电话；距上车点距离和预计到达时间 |\n| 2 | 司机已到达 | 🔔 司机已到达上车点，请前往上车 |\n| 4 | 行程进行中 | 🚗 行程已开始 |\n| 5 | 订单完成 | ✅ 行程结束，展示费用（如有） |\n| 6 | 订单已被系统取消 | ❌ 订单已被系统取消 |\n| 7 | 订单已被取消 | ❌ 订单已取消 |\n| 3/8-12 | 其他终态 | 显示对应状态描述 |\n\n### 3.7 预约出行规则\n\n当用户要求在特定时间叫车（如\"15分钟后\"、\"明天9点\"）：\n\n- 使用 cron 一次性任务（`--at`），到点由 isolated agent 独立执行完整打车流程；\n- ⚠️ `--message` 必须包含完整起终点（带城市前缀）和车型，isolated session 无历史上下文。起点或终点缺失时先从 `assets/PREFERENCE.md` 推断并向用户确认，推断不了则必须先询问用户，**不要自行推断未知信息**；\n- 到点后 agent 自行执行：地址解析 → 价格预估（获取最新 traceId）→ 创建订单；\n- 如果无法获取当前会话的 metadata（channel/chat_id），**仅跳过 cron 创建步骤**，其余流程（地址解析 → 价格预估 → 展示结果）**正常执行不受影响**。在回复中提醒用户到时手动发消息叫车。metadata 不可用 ≠ 放弃整个打车流程；\n- 如果定时任务创建失败，必须在回复中提示用户，不能默默失败。\n\n\n```bash\n# ⚠️ 占位符替换规则：所有 <XXX> 形式都是占位符，必须替换为真实值；\n#    禁止保留 <> 字面、禁止当成 shell 变量加 $（不是 $TIME / $CHAT_ID）。\n#   <FROM_NAME>    → 带城市前缀的起点全称（如\"北京市西二旗地铁站\"）\n#   <TO_NAME>      → 带城市前缀的终点全称（如\"北京市佰嘉城小区\"）\n#   <VEHICLE>      → 车型（如\"快车\"）\n#   <TIME>         → 见下方时间规则（如 \"10m\" / \"2h\" / ISO 时间）\n#   <CHANNEL_NAME> → 当前会话 metadata 中的 channel 字段（如 feishu、telegram），命令行参数不带引号；不可用 last\n#   <CHAT_ID>      → 当前会话 metadata 中的 chat_id 字段\n\nopenclaw cron add \\\n  --name \"didi-ride-skill:$(date +%s)\" \\\n  --at \"<TIME>\" \\\n  --session isolated \\\n  --message \"执行定时打车：起点「<FROM_NAME>」，终点「<TO_NAME>」，车型「<VEHICLE>」。请完整执行打车流程：地址解析 → 价格预估（获取最新 traceId）→ 创建订单。订单创建成功后，输出订单信息并提示用户可发送「查询订单」了解订单状态，同时创建 5 分钟后自动回查 cron（模板见 SKILL.md 第 3.8 节「发单后自动回查」）。\" \\\n  --announce \\\n  --channel <CHANNEL_NAME> \\\n  --to \"<CHAT_ID>\"\n```\n\n#### 3.7.1 TIME 填写规则\n\n| 场景 | 写法 | 示例 |\n|------|------|------|\n| 相对时间（X 分钟/小时后） | duration 格式 | `15m` / `2h` / `1h30m` |\n| 绝对时间（具体时刻） | 本地时区 ISO 格式 | `$(date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00')` |\n\n- 相对时间（如 `15m`）无需格式化，直接使用\n- 绝对时间使用带时区的 ISO 8601 格式：`YYYY-MM-DDTHH:MM:SS+08:00`（北京时间东八区）\n\n**系统兼容性说明：**\n- Linux (GNU date): `date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n- macOS (BSD date): `TZ=Asia/Shanghai date -j -v+1d -f '%H:%M' '09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n\n### 3.8 发单后自动回查\n\n发单成功后（实时单或预约单），根据本章节下文 \"openclaw cron add\" 命令，创建 cron 任务，务必按照本章节下文bash命令参数设置。\n- 如果无法获取当前会话的 metadata（channel/chat_id），**仅跳过 cron 创建步骤**，主流程正常完成（已出单则告知用户\"5 分钟后可发送'查询订单'了解最新状态\"）。\n- 如果定时任务创建失败（命令本身报错），必须在回复中提示用户，不能默默失败。\n\n```bash\n# ⚠️ 占位符替换规则：所有 <XXX> 形式都是占位符，必须替换为真实值，禁止保留 <> 字面或加 $ 当 shell 变量。\n#   <ORDER_ID>     → 实际订单号（taxi_create_order 返回）\n#   <CHANNEL_NAME> / <CHAT_ID> → 同 §3.7，从会话 metadata 读取或用兜底值\n\nopenclaw cron add \\\n  --name \"didi-ride-skill:check:<ORDER_ID>\" \\\n  --at \"5m\" \\\n  --session isolated \\\n  --message \"查询滴滴订单状态：订单号 <ORDER_ID>。调用 taxi_query_order 查询并输出当前状态。如果司机已接单，输出司机姓名、车型、车牌、电话及预计到达时间；如果仍在匹配中，提示用户耐心等待。\" \\\n  --announce \\\n  --channel <CHANNEL_NAME> \\\n  --to \"<CHAT_ID>\"\n```\n\n### 3.9 MCP KEY 与配置\n\n> **术语说明**：滴滴平台称此凭证为「MCP KEY」，OpenClaw 配置字段统一叫 `apiKey`，注入后的环境变量为 `DIDI_MCP_KEY`——三者是同一个值。通过 `openclaw config set` 持久化后，OpenClaw 在每次 agent run 启动时自动注入为环境变量。\n\n#### 3.9.1 检查 Key 状态\n\n```bash\n# 仅用于判断 DIDI_MCP_KEY 是否已配置；输出不是 Key 值，不可代入 URL\nopenclaw config get skills.entries.didi-ride-skill.apiKey\n```\n结果输出为空 = 未配置；输出 `__OPENCLAW_REDACTED__` = 已配置，**必须用**环境变量 `$DIDI_MCP_KEY` 拼接 URL。\n\n⚠️ `openclaw config get`（含 `--raw`）永远不返回真实 Key——任何把哨兵值拼入 URL/header/参数的请求都会失败，见 error_handling.md「SSE error / apiKey 占位符泄漏」。\n\n#### 3.9.2 持久化用户 Key\n\n⚠️ 当用户回复了 Key（如\"我的 Key 是 xxxxxx\"），**必须**执行以下命令持久化 & 在当前 Shell 生效：\n\n```bash\n#   YOUR_KEY → 实际的 MCP KEY\nopenclaw config set 'skills.entries.didi-ride-skill.apiKey' 'YOUR_KEY'\nexport DIDI_MCP_KEY='YOUR_KEY'\n```\n\n- 持久化后 OpenClaw 在所有后续 agent run（含 cron isolated session）中自动注入 `DIDI_MCP_KEY`\n- ⚠️⚠️⚠️ 命令输出 `\"Restart the gateway to apply.\"` ——**这是通用提示，必须忽略，禁止执行 restart**。`apiKey` 每次 agent run 动态读取，无需重启；强制重启会导致网关崩溃\n\n#### 3.9.3 Key 缺失或鉴权失败\n\n⚠️ Key 未配置**或** MCP 返回鉴权失败（`error.code: -32002`）时，依次执行：\n\n1. 发送二维码图片（`{CHAT_ID}` → metadata 的 chat_id，`{CHANNEL_NAME}` → metadata 的 channel）：\n\n```bash\nopenclaw message send --channel {CHANNEL_NAME} --target {CHAT_ID} --media \"https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png\" --message \"滴滴出行APP扫码获取MCP Key，解锁一键打车\"\n```\n\n2. 输出文字：\n\n> 您还没有配置 DIDI_MCP_KEY 或 Key 已失效，请访问 [滴滴MCP平台](https://mcp.didichuxing.com/claw) 获取 MCP KEY，然后配置环境变量或在 OpenClaw 配置文件中设置。\n\n### 3.10 工具清单\n\n| 领域 | 工具 |\n|------|------|\n| 地图 | `maps_textsearch`, `maps_regeocode` |\n| 路线 | `maps_direction_driving`, `maps_direction_transit`, `maps_direction_walking`, `maps_direction_bicycling` |\n| 周边 | `maps_place_around` |\n| 打车 | `taxi_estimate`（预估）, `taxi_create_order`（下单）, `taxi_query_order`（查单+司机位置）, `taxi_cancel_order`（取消） |\n\nFile v1.1.3:README.md\n\n# didi-ride-skill\n\n[English](README.en.md) | 中文\n\n【滴滴出行统一入口】处理用户所有出行相关需求，提供完整的打车服务和路线规划功能。\n\n**ClawHub**: [didi-ride-skill-official](https://clawhub.ai/didi/didi-ride-skill-official)\n\n> **服务范围**：支持滴滴出行服务覆盖的中国大陆城市。\n\n## 目录\n\n- [快速开始](#快速开始)\n- [功能介绍](#功能介绍)\n- [前置安装](#前置安装)\n- [MCP 工具](#mcp-工具)\n- [工作流程](#工作流程)\n- [使用示例](#使用示例)\n- [技术支持](#技术支持)\n\n---\n\n## 快速开始\n\n**3 步开始使用：**\n\n**Step 1 — 安装 mcporter**\n\n```bash\nnpm install -g mcporter\n```\n\n**Step 2 — 获取并配置 MCP KEY**\n\n扫描 [滴滴 MCP 平台](https://mcp.didichuxing.com/claw) 二维码获取 KEY，然后直接告诉 AI：\n\n```\n你: 我的 MCP Key 是 xxxxxx\n```\n\n**Step 3 — 开始出行**\n\n```\n你: 帮我打车去北京西站\n你: 从国贸到三里屯怎么走\n```\n\n---\n\n## 功能介绍\n\n### 打车服务\n\n| 功能 | 说明 |\n|------|------|\n| 实时叫车 | 地址解析 → 价格预估 → 车型决策（用户或偏好）→ 创建订单 |\n| 预约出行 | 创建定时任务，到点后自动发起打车请求 |\n| 查询订单 | 用户主动发送「查询订单」，单次查询当前状态 |\n| 查询司机位置 | 逆地址编码，美化输出司机位置信息 |\n| 取消订单 | 展示订单信息 → 用户确认 → 取消 |\n| 价格预估 | 获取各车型价格对比 |\n| 偏好设置 | 记住常用地址（家/公司）、车型偏好、叫车手机号 |\n\n### 路线规划\n\n| 功能 | 说明 |\n|------|------|\n| 驾车路线 | 规划小客车/轿车出行方案 |\n| 公交地铁 | 综合公交、地铁通勤方案 |\n| 步行路线 | 规划步行出行方案 |\n| 骑行路线 | 规划骑行出行方案 |\n| 周边搜索 | 搜索附近的地点、设施 |\n\n---\n\n## 前置安装\n\n### 1. 获取 MCP KEY\n\n**方式 A：扫码获取（推荐，最快）**\n\n打开滴滴出行 App，扫描下方二维码，即可快速获取 MCP KEY：\n\n![滴滴出行APP扫码获取MCP Key](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n\n**方式 B：访问官网**\n\n访问 [滴滴 MCP 平台](https://mcp.didichuxing.com/claw) 获取 MCP KEY。\n\n### 2. 安装 mcporter\n\n```bash\nnpm install -g mcporter\n```\n\n### 3. 配置 MCP KEY\n\n**方式 A：对话中输入（推荐）**\n\n直接在对话中告诉 AI 您的 MCP KEY，AI 会自动持久化配置：\n\n```\n你: 我的 MCP Key 是 xxxxxx\n```\n\n**方式 B：环境变量**\n\n```bash\nexport DIDI_MCP_KEY=\"YOUR_MCP_KEY_HERE\"\n```\n\n**方式 C：配置文件**\n\n编辑 `~/.openclaw/openclaw.json`：\n\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"didi-ride-skill\": {\n        \"apiKey\": \"YOUR_MCP_KEY_HERE\"\n      }\n    }\n  }\n}\n```\n\n### 4. 验证配置\n\n```bash\n# 检查 Key 是否已配置\necho $DIDI_MCP_KEY\n\n# 测试 API 连通性\nexport MCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"西二旗地铁站\",\"city\":\"北京市\"}'\n```\n\n---\n\n## MCP 工具\n\n### 打车相关\n\n| 工具 | 用途 |\n|------|------|\n| `maps_textsearch` | 文本地址解析，获取经纬度坐标 |\n| `taxi_estimate` | 价格预估，查询可用车型及价格 |\n| `taxi_create_order` | 创建打车订单 |\n| `taxi_query_order` | 查询订单状态和司机信息 |\n| `taxi_get_driver_location` | 获取司机实时位置 |\n| `maps_regeocode` | 逆地址编码（坐标转地址） |\n| `taxi_cancel_order` | 取消订单 |\n| `taxi_generate_ride_app_link` | 生成 App 深度链接（无 API 直发权限时的备选方案） |\n\n### 路线规划相关\n\n| 工具 | 用途 |\n|------|------|\n| `maps_direction_driving` | 驾车路线规划 |\n| `maps_direction_transit` | 公交地铁路线规划 |\n| `maps_direction_walking` | 步行路线规划 |\n| `maps_direction_bicycling` | 骑行路线规划 |\n| `maps_place_around` | 周边搜索 |\n\n---\n\n## 工作流程\n\n### 打车流程\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│                    用户发起打车请求                             │\n│               \"我要从国贸去三里屯\"                              │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 1: 地址解析 (maps_textsearch)                             │\n│  - 解析起点：国贸 → (116.458, 39.908)                           │\n│  - 解析终点：三里屯 → (116.455, 39.937)                         │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 2: 确认起终点                                             │\n│  - 推断地址或多候选结果时，向用户确认起终点                     │\n│  - 用户明确指定且精确匹配的地点无需确认                         │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 3: 价格预估 (taxi_estimate)                               │\n│  - 获取可用车型列表和价格                                       │\n│  - 展示给用户选择（如用户未明确车型）                           │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 4: 车型决策                                               │\n│  - 用户指定车型或按偏好直发                                     │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 5: 创建订单 (taxi_create_order)                           │\n│  - 使用用户选择的车型创建订单                                   │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 6: 输出订单信息 + 提示跟踪                                │\n│  - 输出订单号、起终点、车型、预估价                             │\n│  - 提示用户：发送「查询订单」可了解订单状态                     │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 7: 发单后自动回查（自动创建 cron）                        │\n│  - 创建 5 分钟后的定时回查任务                                  │\n│  - 到点自动查询订单状态并推送通知                               │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n### 订单状态说明\n\n| 状态代码 | 状态文本 | 说明 |\n|---------|---------|------|\n| 0 | 匹配中 | 正在为您匹配司机 |\n| 1 | 司机已接单 | 展示司机信息及距上车点距离/ETA |\n| 2 | 司机已到达 | 提示前往上车 |\n| 4 | 行程进行中 | 行程已开始 |\n| 5 | 订单完成 | 展示费用信息 |\n| 6 | 订单已被系统取消 | 系统自动取消 |\n| 7 | 订单已被取消 | 用户取消 |\n| 3/8-12 | 其他终态 | 显示对应状态描述 |\n\n### 用户确认机制\n\n| 操作 | 确认方式 |\n|------|----------|\n| 实时单下单 | 允许用户指定车型或按偏好直发，不必确认 |\n| 预约出行 | 直接创建 cron（托管叫车需求，到点后发起打车） |\n| 取消订单 | 展示订单信息 → 等待用户确认 |\n\n---\n\n## 使用示例\n\n### 打车服务\n\n**基础叫车**\n```\n你: 帮我叫个车从北京西站到西二旗地铁站\n\nAI: 正在解析地址...\n已找到起点：北京西站 (116.321, 39.894)\n已找到终点：西二旗地铁站 (116.297, 40.053)\n\n正在查询价格...\n\n1. 特惠快车: 约 32 元\n2. 快车: 约 34 元\n3. 专车: 约 54 元\n\n请选择车型，或说\"确认\"使用推荐车型。\n```\n\n**指定车型**\n```\n你: 叫个快车从家到公司\n\nAI: 正在为您呼叫快车...\n订单已创建！订单号: qo01uCXI6ojeiD\n```\n\n**预约出行**\n```\n你: 明天早上8点从家到公司\n\nAI: 已设置定时任务：明天 08:00\n到点后将自动发起打车请求。\n```\n\n**查询订单**\n```\n你: 查询订单 qo01uCXI6ojeiD\n\nAI: 订单号: qo01uCXI6ojeiD\n状态: 司机已接单\n车牌: 京A·XXXXX\n距离: 约 1.2 公里\n预计到达: 3 分钟\n```\n\n> 注意：当前仅支持查询进行中的订单，历史订单请在滴滴出行 App 中查看。\n\n**查询司机位置**\n```\n你: 司机现在在哪里\n\nAI: 🚗 司机位置信息\n📍 位置: 北京市朝阳区建国门外大街1号国贸附近\n📏 距您: 约 1.2 公里\n⏱️ 预计到达: 约 3 分钟\n```\n\n### 路线规划\n\n**驾车路线**\n```\n你: 规划从望京SOHO到国贸的驾车路线\n\nAI: 🚗 驾车路线规划\n📍 路线: 望京SOHO → 国贸\n📏 距离: 约 8.5 公里\n⏱️ 预计: 约 25 分钟\n```\n\n**公交地铁路线**\n```\n你: 查一下从北京西站到西二旗的公交地铁路线\n\nAI: 🚌 公交地铁路线\n📍 路线: 北京西站 → 西二旗地铁站\n⏱️ 预计: 约 55 分钟\n🔄 换乘: 地铁9号线 → 地铁13号线\n```\n\n**步行路线**\n```\n你: 从家到地铁站步行要多久\n\nAI: 🚶 步行路线\n📍 路线: 家 → 地铁站\n📏 距离: 约 800 米\n⏱️ 预计: 约 10 分钟\n```\n\n**骑行路线**\n```\n你: 骑车从望京到三里屯怎么走\n\nAI: 🚴 骑行路线\n📍 路线: 望京 → 三里屯\n📏 距离: 约 6.2 公里\n⏱️ 预计: 约 28 分钟\n```\n\n**周边搜索**\n```\n你: 附近有什么咖啡馆\n\nAI: ☕ 周边搜索结果\n📍 当前位置周边咖啡馆：\n1. 瑞幸咖啡 - 距您约 150 米\n2. 星巴克 - 距您约 320 米\n3. Manner Coffee - 距您约 580 米\n```\n\n---\n\n## 技术支持\n\n- 详细工作流程: [SKILL.md](SKILL.md)\n- API 参考文档: [api_references.md](references/api_references.md)\n- 错误处理指南: [error_handling.md](references/error_handling.md)\n\nFile v1.1.3:_meta.json\n\n{\n  \"ownerId\": \"kn7can12c6x8pp8ade0sxqkv6582sfzp\",\n  \"slug\": \"didi-ride-skill-official\",\n  \"version\": \"1.1.3\",\n  \"publishedAt\": 1779103249288\n}\n\nFile v1.1.3:references/api_references.md\n\n# API 文档\n\n## 响应格式说明\n\n所有工具均返回 `content[].text`（自然语言文本）。部分工具（网约车类）额外返回 `structuredContent`（结构化数据）。\n\n- 如果响应中存在 `structuredContent`，优先使用其中的字段做逻辑判断和字段提取\n- 如果没有 `structuredContent`，则解析 `content[].text` 获取所需信息\n\n## 函数签名\n\n```\n/**\n   * 根据用户输入的起点终点坐标，规划骑行通勤方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_bicycling(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户起终点经纬度坐标规划以小客车、轿车通勤出行的方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_driving(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户起终点坐标，规划综合公交、地铁的通勤方案\n   *\n   * @param city 查询城市（**必须使用完整格式，如\"北京市\"而非\"北京\"**）\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_transit(city: string, destination: string, origin: string);\n\n  /**\n   * 根据用户输入的起点终点坐标，规划步行通勤方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_walking(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户传入关键词和位置坐标，搜索出周边的POI地点信息\n   *\n   * @param keywords 搜索关键词\n   * @param location 位置坐标，格式为：经度,纬度\n   * @param max_distance? 搜索半径，单位：米\n   */\n  function maps_place_around(keywords: string, location: string, max_distance?: string);\n\n  /**\n   * 将经纬度坐标转换为地址信息\n   *\n   * @param location 位置坐标，格式为：经度,纬度\n   */\n  function maps_regeocode(location: string);\n\n  /**\n   * 根据用户传入关键词和城市，搜索出相关的POI地点信息\n   *\n   * @param city 查询城市（**必须使用完整格式，如\"北京市\"而非\"北京\"**）\n   * @param keywords 搜索关键词\n   * @param location? 位置坐标，格式为：经度,纬度\n   */\n  function maps_textsearch(city: string, keywords: string, location?: string);\n\n  /**\n   * 取消打车订单\n   *\n   * @param order_id 订单ID，从订单创建或查询结果中获取\n   * @param reason? 取消原因，可选参数。例如：不需要了、等待时间太长、临时有事等\n   */\n  function taxi_cancel_order(order_id: string, reason?: string);\n\n  /**\n   * 直接通过API创建打车订单，无需打开任何应用程序界面，系统自动完成整个发单流程\n   *\n   * @param caller_car_phone? 叫车人手机号，如果有就要传递，没有就不传\n   * @param estimate_trace_id 预估流程ID，从预估结果中获取\n   * @param product_category 车型品类标识，从预估结果中获取，传入多个车型时，用英文逗号分割，不要带空格\n   * @returns structuredContent.orderId   订单ID，后续查询/取消订单使用\n   * @returns structuredContent.status    订单初始状态（created）\n   */\n  function taxi_create_order(caller_car_phone?: string, estimate_trace_id: string, product_category: string);\n\n  /**\n   * 查看当前可用的网约车车型，请先获取对应地点的经纬度信息，如果有maps_textsearch的tool，优先使用maps_textsearch进行经纬度的获取。\n   *\n   * @param from_lat 出发纬度，必须从地图相关的工具获取，不能假设\n   * @param from_lng 出发经度，必须从地图相关的工具获取，不能假设\n   * @param from_name 出发地名称\n   * @param to_lat 目的纬度，必须从地图相关的工具获取，不能假设\n   * @param to_lng 目的经度，必须从地图相关的工具获取，不能假设\n   * @param to_name 目的地名称\n   * @returns structuredContent.traceId          预估流程ID，创建订单时必须传入\n   * @returns structuredContent.items[]          可用车型列表\n   * @returns structuredContent.items[].productName     车型名称\n   * @returns structuredContent.items[].productCategory 车型品类代码，创建订单时传入\n   * @returns structuredContent.items[].priceText       预估价格（元）\n   */\n  function taxi_estimate(from_lat: string, from_lng: string, from_name: string, to_lat: string, to_lng: string, to_name: string);\n\n  /**\n   * 根据起点、终点和车型生成打开移动应用或小程序的深度链接，用户点击后将跳转到相应的打车应用完成发单操作\n   *\n   * @param from_lat 出发纬度，必须从地图相关的工具获取，不能假设\n   * @param from_lng 出发经度，必须从地图相关的工具获取，不能假设\n   * @param product_category? 车型品类标识列表，从预估结果中获取，支持多个车型，仅当用户明确指定某个或某些品类时才传递此参数，格式为英文逗号,分割\n   * @param to_lat 目的地纬度，必须从地图相关的工具获取，不能假设\n   * @param to_lng 目的经度，必须从地图相关的工具获取，不能假设\n   */\n  function taxi_generate_ride_app_link(from_lat: string, from_lng: string, product_category?: string, to_lat: string, to_lng: string);\n\n  /**\n   * 获取打车订单对应司机的实时位置经纬度\n   *\n   * @param order_id 打车订单ID\n   */\n  function taxi_get_driver_location(order_id: string);\n\n  /**\n   * 查询打车订单的状态和信息，如司机联系方式、车牌号、预估到达时间\n   *\n   * ⚠️ 重要：此函数单次调用仅返回当前状态。\n   * 单次调用返回当前状态，详见 SKILL.md `### 3.6 查询订单`。\n   *\n   * @param order_id? 订单ID，从创建订单结果中获取，如果有就要传递，如果没有，会查询当前账号下未完成的订单\n   * @returns structuredContent.statusCode  订单状态码（见下表）\n   * @returns structuredContent.statusText  状态文本描述\n   * @returns structuredContent.driver      司机信息（name/phone/carModel/carPlate），接单后可用\n   * @returns structuredContent.map.distanceKm  距离（公里），行程中可用\n   * @returns structuredContent.map.eta         预计剩余时间（分钟），行程中可用\n   * @returns structuredContent.map.phase       当前阶段：to_pickup（前往上车点）| to_dropoff（前往终点）\n   *\n   * 订单状态码：\n   *   0  匹配中（非终态）\n   *   1  司机已接单（非终态）\n   *   2  司机已到达（非终态，里程碑通知）\n   *   3  未知状态（终态）\n   *   4  行程开始（非终态，里程碑通知）\n   *   5  订单完成（终态）✅\n   *   6  订单已被系统取消（终态）✅\n   *   7  订单已被取消（终态）✅\n   *   8  未知状态（终态）✅\n   *   9  未知状态（终态）✅\n   *   10 未知状态（终态）✅\n   *   11 客服关闭订单（终态）✅\n   *   12 未能完成服务（终态）✅\n   */\n  function taxi_query_order(order_id?: string);\n```\n\nExamples:\n\n```bash\n# 设置 MCP_URL 变量\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\n\n# 地址解析（city 建议使用完整行政区名称）\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"望京SOHO\",\"city\":\"北京市\"}'\n\n# 价格预估（注意：所有参数值必须加引号，使用字符串格式）\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lat\":\"39.9\",\"from_lng\":\"116.4\",\"from_name\":\"望京SOHO\",\"to_lat\":\"39.9\",\"to_lng\":\"116.4\",\"to_name\":\"国贸\"}'\n```\n\nFile v1.1.3:references/error_handling.md\n\n# 错误处理指南\n\n本文档说明 didi-ride-skill skill 使用过程中可能遇到的错误及解决方案。\n\n> `<skill-dir>` 代表 didi-ride-skill 技能的安装根目录（即 SKILL.md 所在目录），可通过 `openclaw skills info didi-ride-skill` 获取。\n\n## 目录\n\n- [错误处理指南](#错误处理指南)\n  - [目录](#目录)\n  - [mcporter Missing KEY parameter](#mcporter-missing-key-parameter)\n  - [SSE error / apiKey 占位符泄漏](#sse-error--apikey-占位符泄漏)\n  - [mcporter.json 校验错误](#mcporterjson-校验错误invalid_type--failed-to-parse-json)\n  - [taxi_create_order 调用失败](#taxi_create_order-调用失败)\n  - [Unknown MCP server 错误](#unknown-mcp-server-错误)\n  - [统一错误码表](#统一错误码表)\n  - [参数错误排查](#参数错误排查statuscode400--backend-call-failed)\n  - [常见问题 (FAQ)](#常见问题-faq)\n  - [获取帮助](#获取帮助)\n\n***\n\n## mcporter Missing KEY parameter\n\nmcporter 报 `Missing KEY parameter` 时，**不代表 MCP Key 已失效**，禁止直接向用户索要 Key。\n\n可能原因（按概率排序逐一排查）：\n\n1. **`$DIDI_MCP_KEY` 环境变量未展开**：`MCP_URL` 赋值时用了单引号（`'$DIDI_MCP_KEY'`）而非双引号，导致变量字面量传入。确认调用命令中 `MCP_URL` 使用双引号包裹，然后重试。\n2. **当前 shell 未注入环境变量**：openclaw 在每次 agent run 启动时自动注入 `DIDI_MCP_KEY`，但手动在终端直接运行 mcporter 时该变量不存在。执行 `echo $DIDI_MCP_KEY` 验证——若为空，在终端手动 `export DIDI_MCP_KEY=<key>` 后重试，或改在 openclaw agent 环境中调用。\n3. **mcporter.json 配置异常**：若当前目录下 `config/mcporter.json` 或 `~/.mcporter/mcporter.json` 存在且格式异常，mcporter 会在启动阶段直接崩溃（报 `invalid_type` 或 `Failed to parse JSON`），所有命令不可用。**不要删除该文件**（可能包含用户其他应用的配置），改用 `--config` 绕过——见 SKILL.md §3.2 第 3 条。\n4. **Key 本身确实无效**：若以上均排除，执行 `openclaw config get skills.entries.didi-ride-skill.apiKey` 确认 Key 已配置，若返回空则按 `### 3.9 MCP KEY 与配置` 流程重新配置。\n\n***\n\n## SSE error / apiKey 占位符泄漏\n\nmcporter 报 `SseError: SSE error: Invalid content type, expected \"text/event-stream\"` 时，最常见根因是把 OpenClaw 的哨兵值 `__OPENCLAW_REDACTED__` 当成真实 Key 拼进了 MCP URL。\n\n**症状**：\n\n- 拼出来的 URL 实际是 `https://mcp-dev.didichuxing.com/mcp-servers?key=__OPENCLAW_REDACTED__`\n- 服务端把它当成无效 Key 拒绝，返回 HTML / 纯文本错误页（不是 SSE 流）\n- mcporter 收到非 `text/event-stream` 响应直接抛 `SseError`\n\n**为什么会拼错**：误以为 `openclaw config get skills.entries.didi-ride-skill.apiKey` 配上 `--raw` / `awk` / `sed` 之类的手段能拿到真实 Key 字面量。实际上：\n\n> `openclaw config get`（含 `--raw`）**永远不会**返回真实 Key 字面量。`__OPENCLAW_REDACTED__` 是\"已配置\"的哨兵值，不是 Key 本身。真实 Key 由 OpenClaw 在每次 agent run 启动时注入到环境变量 `DIDI_MCP_KEY`，调用方只能通过 `$DIDI_MCP_KEY` 使用。\n\n**修复步骤**：\n\n1. 自检环境变量是否注入：\n\n   ```bash\n   printenv DIDI_MCP_KEY >/dev/null && echo env_ok || echo env_missing\n   ```\n\n2. 若 `env_ok`：把 URL 拼接改回 SKILL.md §3.2 第 4 条的固定写法，不要再尝试从 config 提取 Key：\n\n   ```bash\n   MCP_URL=\"https://mcp-dev.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\n   mcporter call \"$MCP_URL\" <tool> --args '...'\n   ```\n\n3. 若 `env_missing`：当前不在 openclaw agent run 上下文里（例如手动终端调用），按 SKILL.md §3.9 引导用户重新配置；或临时 `export DIDI_MCP_KEY=<key>` 后重试。\n\n**禁止**：\n\n- 禁止用 `openclaw config get ... --raw` / `awk` / `sed` / `jq` 等任何手段尝试从配置提取 Key 字面量\n- 禁止把 `__OPENCLAW_REDACTED__` 出现在任何 URL / header / 参数中\n- 禁止在见到本错误时向用户索要新的 Key——Key 可能完全有效，只是用错了\n\n***\n\n## mcporter.json 校验错误（`invalid_type` / `Failed to parse JSON`）\n\nmcporter 启动时报 `invalid_type, expected record` 或 `Failed to parse JSON` 等校验错误时，说明当前目录的 `config/mcporter.json` 或 `~/.mcporter/mcporter.json` 存在且内容异常（格式不正确、空文件、或 AI 之前错误创建的）。\n\n**格式错误的 mcporter.json 会阻止 mcporter 所有命令执行**，包括 URL 直连模式。\n\n**解决方法**（不要删除用户的 mcporter.json，可能包含其他应用配置）：\n\n```bash\n# 创建一个空的合法配置用于绕过\necho '{\"mcpServers\":{}}' > /tmp/.mcporter-empty.json\n# 后续所有 mcporter 命令加 --config 参数\nmcporter --config /tmp/.mcporter-empty.json call \"$MCP_URL\" <tool> --args '...'\n```\n\n本 skill 使用 URL 直连模式，不依赖 mcporter.json。**禁止创建或修改 `config/mcporter.json`**。\n\n***\n\n## taxi_create_order 调用失败\n\n调用 `taxi_create_order` 时若返回 `Streamable HTTP error: Unexpected content type: text/plain; charset=utf-8`，按以下方式处理。\n\n1. **停止当前打车流程**（不要继续重试或切换 tool，也不要向用户索要新的 Key）；\n2. 向用户输出以下**固定文案**（原样复制，不要改写）：\n\n   > 未开通DiDi MCP 免密支付的用户，需要到 DiDi MCP 官网开通免密支付，审核完成后，即可调用全部的打车接口能力\n\n> ⚠️ 见到该字面量直接进入本章节处理，输出固定文案并停止流程，不要自行扩展解释。\n\n***\n\n## Unknown MCP server 错误\n\nmcporter 报 `Unknown MCP server 'xxx'` 时，根据 `xxx` 的值判断：\n\n- **`xxx` 是工具名**（如 `Unknown MCP server 'maps_textsearch'`）：说明命令格式不对。第一个位置参数必须是完整 URL（`\"$MCP_URL\"`），第二个位置参数才是 tool name。检查是否遗漏了 URL、或 URL 变量未定义。\n- **`xxx` 是自定义名称**（如 `Unknown MCP server 'didi-mcp'`）：说明使用了 `--server` 标志。**本 skill 禁止使用 `--server` 标志**——它需要已注册的命名 server，而 didi-ride-skill 始终使用 URL 直连模式。去掉 `--server xxx` 参数后重试。\n\n***\n\n## 统一错误码表\n\n所有 MCP 工具返回的统一错误码对照：\n\n| 错误码 | 说明 | 解决方案 |\n|--------|------|----------|\n| `-32001` | 命中限流 | 请等待一段时间后重试（配额限制按时间窗口重置） |\n| `-32002` | 鉴权失败（`auth failed`） | Key 存在但无效或已过期，执行 `### 3.9 MCP KEY 与配置` 的引导流程（含发送二维码） |\n| `-32010` | 参数验证失败 | 检查参数格式，确保所有值为字符串 |\n| `-32011` | 订单不存在 | 确认订单ID正确 |\n| `-32021` | 预估结果过期 | 重新调用价格预估获取新的 traceId |\n| `-32030` | 不支持订单类型 | 该类型订单不支持此操作 |\n| `-32031` | 订单未支付 | 订单未进入支付状态 |\n| `-32040` | 订单已经取消过了 | 订单已被取消，无需重复操作 |\n| `-32041` | 订单无法被取消 | 司机已接单或订单已完成，无法通过 API 取消 |\n| `-32050` | 内部错误 | 稍后重试，如持续失败请联系客服 |\n| `-32060` | 支付失败 | 检查支付账户状态或更换支付方式 |\n\n***\n\n## 参数错误排查（`StatusCode=400` / `backend call failed`）\n\nmcporter 返回 `backend call failed: ... StatusCode=400` 时，**根因几乎都是参数问题**（mcporter 不会展示 MCP Server 返回的具体错误原因，只给出 StatusCode）。按以下顺序逐项排查：\n\n1. **参数名拼写**——最常见根因。典型错误对照：\n\n   | 错误写法 | 正确写法 | 所属工具 |\n   |----------|----------|----------|\n   | `keyword` | `keywords`（复数） | `maps_textsearch`、`maps_place_around` |\n   | `region` / `province` | `city` | `maps_textsearch`、`maps_direction_transit` |\n   | `origin` / `destination` | `from_lat`/`from_lng`/`from_name` 与 `to_lat`/`to_lng`/`to_name`（六字段） | `taxi_estimate`、`taxi_generate_ride_app_link` |\n   | `order` / `orderId` | `order_id`（snake_case） | `taxi_query_order`、`taxi_cancel_order`、`taxi_get_driver_location` |\n   | `traceId` | `estimate_trace_id` | `taxi_create_order` |\n\n2. **必填参数缺失**——例如 `maps_textsearch` 的 `city` 必填（即使已提供坐标也不能省）。\n\n3. **类型错误**——`--args` JSON 对象内**所有参数值必须是字符串**：\n   - 经纬度 `\"39.908858\"` ✅，不是 `39.908858` ❌\n   - `product_category` 填 `\"1\"` ✅，不是 `1` ❌\n\n4. **城市名完整格式**——`\"北京市\"` ✅，`\"北京\"` ❌。\n\n5. **自检手段**——如果以上都核对过仍失败，执行 `mcporter list \"$MCP_URL\"` 查看工具的完整函数签名，逐字段比对。\n\n> ⚠️ **不要因为看到 `StatusCode=400` 就怀疑 mcporter 工具坏了**。这个报错 99% 是参数问题，不是 mcporter 或网络问题。\n\n***\n\n## 常见问题 (FAQ)\n\n**Q: 为什么说\"我要上班\"没反应？**\nA: 需要先配置 `assets/PREFERENCE.md` 中的家和公司地址，以及上班场景的车型偏好。\n\n**Q: 预估价格和实际价格不一致？**\nA: 预估价格为参考值，实际费用以行程完成后为准。\n\n**Q: 如何查看历史订单？**\nA: 当前 API 仅支持查询 MCP 渠道未完成订单，历史订单请在滴滴 App 中查看。\n\n**Q: 支持哪些城市？**\nA: 支持滴滴服务覆盖的所有中国大陆城市。\n\n***\n\n## 获取帮助\n\n如果以上方案无法解决问题，请：\n\n1. 检查 [workflow.md](./workflow.md) 确认操作流程\n2. 访问 <https://mcp.didichuxing.com> 获取最新文档\n\nFile v1.1.3:references/setup.md\n\n# DiDi MCP Server 安装配置指南\n\n本文档说明如何安装和配置 DiDi MCP Server，以便使用 didi-ride-skill skill。\n\n## 1. 安装 mcporter\n\nmcporter 是用于调用 MCP Server 的命令行工具。\n\n```bash\nnpm install -g mcporter\n```\n\n验证安装：\n```bash\nmcporter --version\n```\n\n## 2. 获取 MCP KEY\n\n访问 https://mcp.didichuxing.com/claw 获取您的 MCP KEY，或扫描下方二维码直达官网注册页面。\n\n![滴滴出行APP扫码获取MCP Key，解锁一键打车](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n\n\n## 3. 配置 MCP KEY\n\n**推荐方式：通过 OpenClaw 持久化（所有 isolated session 自动生效）**\n\n```bash\nopenclaw config set 'skills.entries.didi-ride-skill.apiKey' 'YOUR_MCP_KEY'\n```\n\n**备用方式：环境变量（仅当前 shell 会话有效）**\n\n```bash\nexport DIDI_MCP_KEY=\"YOUR_MCP_KEY\"\n```\n\n## 4. 验证连接\n\n> 本 skill 使用 mcporter 的 **URL 直连模式**，不依赖 `config/mcporter.json` 配置文件。如果 mcporter 启动时报 JSON 校验错误（`invalid_type` 或 `Failed to parse JSON`），说明存在格式异常的 `config/mcporter.json`。不要删除它（可能包含其他应用配置），改用 `--config` 绕过——详见 SKILL.md §3.2 第 3 条。\n\n**Step 1 — 查看所有工具签名（同时验证 Key 和连通性）：**\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter list \"$MCP_URL\"\n```\n\n预期输出完整的工具列表（`maps_textsearch`、`taxi_estimate` 等 13 个工具及参数签名）。如果返回鉴权错误，说明 Key 无效。\n\n**Step 2 — 测试地址解析功能：**\n\n```bash\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"西二旗地铁站\",\"city\":\"北京市\"}'\n```\n\n**Step 3 — 测试价格预估功能：**\n\n```bash\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lng\":\"116.322\",\"from_lat\":\"39.893\",\"from_name\":\"北京西站\",\"to_lng\":\"116.482\",\"to_lat\":\"40.004\",\"to_name\":\"首都机场\"}'\n```\n\n## 5. OpenClaw 配置\n\n如果使用 OpenClaw，还需要以下配置：\n\n- 确保已安装 `openclaw` CLI\n- 验证 mcporter 已安装：`which mcporter`\n- 若未找到，执行 `npm install -g mcporter` 后重新验证\n\n## 常见问题\n\n**Q: MCP KEY 无效**\nA: 请检查 MCP KEY 是否正确，以及是否已启用相应权限\n\n**Q: 调用超时**\nA: 检查网络连接，稍后重试\n\n**Q: 地理位置限制**\nA: 部分功能仅支持中国大陆地区\n\nFile v1.1.3:references/workflow.md\n\n# 滴滴打车详细工作流程\n\n## 全局执行约束\n\n1. 参数优先级：`用户 query` > `assets/PREFERENCE.md` > 默认值。\n2. 每次调用前先核对 [api_references.md](./api_references.md) 参数名。\n3. 所有 `--args` 值必须为字符串。\n4. `taxi_create_order` 必须使用最近一次预估返回的 `traceId`。\n5. 起终点缺失时按优先级补全：① 读 assets/PREFERENCE.md，有地址别名且值非空则推断；② 无可用别名时询问用户当前位置，不得用历史记忆补齐。\n6. 用户拒绝提供当前位置时固定回复：不提供当前位置信息则无法满足您的需求。\n7. mcporter 使用 URL 直连模式，**禁止添加 `--server` 标志**，**禁止创建或修改 `config/mcporter.json`**。遇到 `StatusCode=400` 先核对参数名（见 SKILL.md §3.2 第 4 条），遇到 JSON 校验错误用 `--config` 绕过（见 SKILL.md §3.2 第 3 条）。\n\n## Phase 1：地址解析\n\n调用：`maps_textsearch`\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"北京西站\",\"city\":\"北京市\"}'\n```\n调用时需要注意:\n\n- city **必须使用完整格式，如\"北京市\"而非\"北京\"**\n- keywords 和 city 参数值是否为字符串格式（加引号）\n\n解析规则：\n\n- 用户给完整起终点：直接进入预估。\n- \"我要上班/下班了\"：允许按家↔公司偏好直接解析。\n- \"回家/去公司\"但缺起点：先问当前位置。\n\n## Phase 2：价格预估\n\n调用：`taxi_estimate`\n\n```bash\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lat\":\"39.894\",\"from_lng\":\"116.321\",\"from_name\":\"北京西站\",\"to_lat\":\"40.053\",\"to_lng\":\"116.297\",\"to_name\":\"西二旗\"}'\n```\n\n执行要点：\n\n- 记录 `traceId`，后续发单必须使用该值。\n- 若重新预估，覆盖旧 `traceId`，只认最新一份。\n\n## Phase 3：创建订单\n\n调用：`taxi_create_order`\n\n```bash\nmcporter call \"$MCP_URL\" taxi_create_order --args '{\"estimate_trace_id\":\"TRACE_ID\",\"product_category\":\"1\"}'\n```\n\n创建策略：\n\n- 用户已明确车型（当前消息含\"叫快车\"\"叫专车\"等）时允许直发，不必二次确认车型；用户未指定车型且偏好为空时，**必须先展示预估结果让用户选择车型**，禁止默认选择。\n- 用户明确车型时按用户选择发单。\n- 用户未明确车型时，可按偏好车型直发；偏好也未配置时，须向用户询问车型，不要自行推荐。\n- 若缺少 `estimate_trace_id` 或 `product_category`，禁止发单。\n- 若返回 `Streamable HTTP error: Unexpected content type: text/plain`，立即停止流程，按 `error_handling.md` 的「taxi_create_order 调用失败」章节输出固定文案（不要重试、不要切换 Key、不要继续后续步骤）。\n\n成功输出模板：\n\n```text\n✅ 订单已创建！\n\n🚖 订单号: [orderId]\n📍 [起点] → [终点]\n🚗 车型: [车型名称]\n💰 预估: 约 [价格] 元\n📱 手机尾号: [phoneNumberSuffix]\n\n⏳ 正在为您匹配司机...\n💡 发送「查询订单」可了解当前订单状态\n⏱️ 将在 5 分钟后自动为您回查订单状态\n```\n\n## Phase 4：查询订单\n\n触发词：`查询订单` / `查询订单 <orderId>`\n\n调用：`taxi_query_order`\n\n```bash\n# MCP_URL 沿用 Phase 1 已定义的变量\nmcporter call \"$MCP_URL\" taxi_query_order --args '{\"order_id\":\"ORDER_ID\"}'\n```\n\n### 状态码与输出格式\n\n| code | 含义 | 输出建议 |\n|------|------|----------|\n| 0 | 匹配中 | ⏳ 正在为您匹配司机，请稍候 |\n| 1 | 司机已接单 | 展示司机信息（姓名、车型、车牌、电话）及距上车点距离/ETA |\n| 2 | 司机已到达 | 🔔 司机已到达上车点，请前往上车 |\n| 4 | 行程进行中 | 🚗 行程已开始，祝您旅途愉快 |\n| 5 | 订单完成 | ✅ 行程结束，展示费用（如有） |\n| 6 | 订单已被系统取消 | ❌ 订单已被系统取消 |\n| 7 | 订单已被取消 | ❌ 订单已取消 |\n| 3/8-12 | 其他终态 | 显示对应状态描述 |\n\n## Phase 5：取消订单\n\n调用顺序：\n\n1. 向用户确认是否取消（即使用户说了\"取消订单\"，仍需明确询问\"确认取消吗？\"，用户的取消意图 ≠ 取消确认）；\n2. 用户确认后调用 `taxi_cancel_order`；\n3. 调用 `taxi_query_order` 确认取消结果。\n\n## Phase 6：预约出行（cron 托管）\n\n说明：MCP API 是实时发单，预约由 OpenClaw cron 托管叫车需求，到点由 isolated agent 独立执行完整打车流程。\n\n```bash\n# ⚠️ 替换占位符：\n#   FROM_NAME    → 带城市前缀的起点全称（如\"北京市西二旗地铁站\"）\n#   TO_NAME      → 带城市前缀的终点全称（如\"北京市佰嘉城小区\"）\n#   VEHICLE      → 车型（如\"快车\"）\n#   TIME         → 见下方时间规则\n#   CHANNEL_NAME → 当前会话 metadata 中的 channel 字段（如 feishu、telegram），CHANNEL_NAME 不需要带引号，例如: feishu ✅, \"feishu\" ❌。不允许使用 last 作为参数值。\n#   CHAT_ID      → 当前会话 metadata 中的 chat_id 字段\n\nopenclaw cron add \\\n  --name \"didi-ride-skill:$(date +%s)\" \\\n  --at \"TIME\" \\\n  --session isolated \\\n  --message \"执行定时打车：起点「FROM_NAME」，终点「TO_NAME」，车型「VEHICLE」。请完整执行打车流程：地址解析 → 价格预估（获取最新 traceId）→ 创建订单。订单创建成功后，输出订单信息并提示用户可发送「查询订单」了解订单状态，同时创建 5 分钟后自动回查 cron（模板见 SKILL.md 第 3.8 节「发单后自动回查」）。\" \\\n  --announce \\\n  --channel CHANNEL_NAME \\\n  --to \"CHAT_ID\"\n```\n\n### TIME 填写规则\n\n| 场景 | 写法 | 示例 |\n|------|------|------|\n| 相对时间（X 分钟/小时后） | duration 格式 | `15m` / `2h` / `1h30m` |\n| 绝对时间（具体时刻） | 本地时区 ISO 格式 | `$(date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00')` |\n\n- 相对时间（如 `15m`）无需格式化，直接使用\n- 绝对时间使用带时区的 ISO 8601 格式：`YYYY-MM-DDTHH:MM:SS+08:00`（北京时间东八区）\n\n**系统兼容性说明：**\n- Linux (GNU date): `date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n- macOS (BSD date): `TZ=Asia/Shanghai date -j -v+1d -f '%H:%M' '09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n\n## 查询司机位置\n\n调用顺序：\n\n1. `taxi_get_driver_location`\n2. `maps_regeocode`\n\n返回内容建议包含：地址、距离、预计到达时间、司机信息（如可得）。\n\nFile v1.1.3:assets/PREFERENCE.md\n\n# 用户偏好设置\n\n> 此文件存储用户的个性化偏好数据，用于优化打车体验。当用户的 query 中没有明确指定时，系统会根据此文件的偏好自动匹配。注意：当起终点是从偏好推断的（非用户明确指定），必须先向用户确认后再执行。\n\n## 优先级说明\n\n1. **用户 query 参数**（优先级最高）：用户在当前对话中明确指定的地址、车型等\n2. **PREFERENCE.md 偏好数据**（优先级次之）：用户预设的个性化偏好\n\n## 地址别名\n\n| 别名 | 地址名称 | 经度 | 纬度 | 城市 |\n| ---- | -------- | ---- | ---- | ---- |\n| 家   |          |      |      |      |\n| 公司 |          |      |      |      |\n\n> 说明：\n> - \"家\"和\"公司\"为内置别名，支持\"从家到公司\"、\"打车回家\"等经典简化表达。\n> - 此表可自由扩展行数，用户可添加任意别名（如\"妈妈家\"、\"儿子的学校\"、\"健身房\"等）。**读取时请扫描整张表格到下一个 `##` 章节为止，不要只看默认的前两行。**\n> - **精确优先，语义兜底**：优先精确匹配别名（\"家\"只匹配\"家\"，不会匹配\"妈妈家\"）；无精确匹配时用语义理解（\"接孩子\"可匹配\"儿子的学校\"）。\n\n## 场景车型偏好\n\n| 场景   | 偏好车型 | 品类代码 | 说明     |\n| ------ | -------- | -------- | -------- |\n| 上班   |          |          |          |\n| 下班   |          |          |          |\n| 其他   |          |          |          |\n\n> 说明：当用户说\"我要上班\"或\"下班回家\"时，自动使用对应的车型偏好\n>\n> 品类代码来自 `taxi_estimate` 返回的 `product_category` 字段。常见值：快车=1，特惠快车=201，滴滴轻享=193，专车=8，豪华车=17。\n> ⚠️ 注意：可用车型以 API 实际返回为准，新增车型会自动出现在预估结果中。支持多车型时用英文逗号分隔，如 `1,201`\n\n## 默认偏好\n\n| 配置项     | 值   | 说明 |\n| ---------- | ---- | ---- |\n| 默认车型   |      | 无明确需求时使用 |\n| 叫车手机号 |      | 默认叫车号码 |\n\n> ⚠️ **叫车手机号是可选字段**：如果用户未提供且此处为空，AI **不要反复向用户索要**——直接以不带 `caller_car_phone` 参数的方式下单即可，MCP API 允许无手机号下单。口头询问一次若用户未回复即视为\"用默认/不传\"。\n\n## 使用示例\n\n1. **地址别名使用**（语义匹配，精确优先）：\n   - \"我要回家\" → 精确匹配别名\"家\"（用户自己的家），不会匹配\"妈妈家\"\n   - \"从家到公司\" → 精确匹配\"家\"为起点，\"公司\"为终点\n   - \"从家去公司\" → 同上，\"家\"= 用户自己的家\n   - \"去妈妈家\" / \"去我妈那儿\" → 匹配别名\"妈妈家\"（需明确含\"妈妈\"语义）\n   - \"送儿子上学\" / \"接孩子\" → 匹配别名\"儿子的学校\"\n   - \"去健身\" → 匹配别名\"健身房\"\n\n2. **场景偏好使用**：\n   - \"我要上班\" → 自动使用\"上班\"场景的车型偏好\n   - \"下班了\" → 自动使用\"下班\"场景的车型偏好\n\n## 更新日志\n\n- 2026-03-11: 初始化偏好文件\n\nFile v1.1.3:README.en.md\n\n# didi-ride-skill\n\nEnglish | [中文](README.md)\n\nUnified DiDi mobility entry point — handles all transportation needs with full ride-hailing and route planning capabilities.\n\n**ClawHub**: [didi-ride-skill-official](https://clawhub.ai/didi/didi-ride-skill-official)\n\n> **Service Area**: Covers all cities in **Mainland China** served by DiDi. Not available in Hong Kong, Macau, Taiwan, or outside China.\n\n## Table of Contents\n\n- [Quick Start](#quick-start)\n- [Features](#features)\n- [Setup](#setup)\n- [MCP Tools](#mcp-tools)\n- [Workflow](#workflow)\n- [Examples](#examples)\n- [Technical Reference](#technical-reference)\n\n---\n\n## Quick Start\n\n**Up and running in 3 steps:**\n\n**Step 1 — Install mcporter**\n\n```bash\nnpm install -g mcporter\n```\n\n**Step 2 — Get and configure your MCP KEY**\n\nScan the QR code or visit [DiDi MCP Platform](https://mcp.didichuxing.com/claw) to get your KEY, then tell the AI:\n\n```\nYou: My MCP Key is xxxxxx\n```\n\n**Step 3 — Start using it**\n\n```\nYou: Get me a cab to Beijing West Station\nYou: What's the route from Guomao to Sanlitun?\n```\n\n---\n\n## Features\n\n### Ride-Hailing\n\n| Feature | Description |\n|---------|-------------|\n| Instant Ride | Address lookup → Price estimate → Vehicle selection → Create order |\n| Scheduled Ride | Creates a scheduled task that auto-dispatches a ride at the specified time |\n| Order Status | Query current order status on demand |\n| Driver Location | Reverse geocode driver coordinates and display formatted location |\n| Cancel Order | Show order details → User confirms → Cancel |\n| Price Estimate | Compare prices across available vehicle types |\n| Preferences | Save frequent addresses (home/office), vehicle type preferences, and phone number |\n\n### Route Planning\n\n| Feature | Description |\n|---------|-------------|\n| Driving | Car navigation route |\n| Transit | Combined bus and subway commute options |\n| Walking | Pedestrian route planning |\n| Cycling | Bike route planning |\n| Nearby Search | Search for points of interest around a location |\n\n---\n\n## Setup\n\n### 1. Get Your MCP KEY\n\n**Option A: Scan QR Code (Recommended, fastest)**\n\nOpen the DiDi app and scan the QR code below to instantly get your MCP KEY:\n\n![Scan with DiDi App to get MCP Key](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n\n**Option B: Visit the website**\n\nGo to [DiDi MCP Platform](https://mcp.didichuxing.com/claw) to obtain your MCP KEY.\n\n### 2. Install mcporter\n\n```bash\nnpm install -g mcporter\n```\n\n### 3. Configure MCP KEY\n\n**Option A: Tell the AI in chat (Recommended)**\n\nJust tell the AI your MCP KEY in the conversation — it will persist the configuration automatically:\n\n```\nYou: My MCP Key is xxxxxx\n```\n\n**Option B: Environment variable**\n\n```bash\nexport DIDI_MCP_KEY=\"YOUR_MCP_KEY_HERE\"\n```\n\n**Option C: Config file**\n\nEdit `~/.openclaw/openclaw.json`:\n\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"didi-ride-skill\": {\n        \"apiKey\": \"YOUR_MCP_KEY_HERE\"\n      }\n    }\n  }\n}\n```\n\n### 4. Verify Configuration\n\n```bash\n# Check that the key is set\necho $DIDI_MCP_KEY\n\n# List all available tools and their signatures (verifies key + connectivity)\nexport MCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter list \"$MCP_URL\"\n\n# Test map lookup\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"Xierqi Subway Station\",\"city\":\"北京市\"}'\n```\n\n---\n\n## MCP Tools\n\n### Ride-Hailing\n\n| Tool | Purpose |\n|------|---------|\n| `maps_textsearch` | Text-based address lookup, returns coordinates |\n| `maps_regeocode` | Reverse geocoding (coordinates → address) |\n| `taxi_estimate` | Price estimate across available vehicle types |\n| `taxi_create_order` | Create a ride order |\n| `taxi_query_order` | Query order status and driver info |\n| `taxi_get_driver_location` | Get driver's real-time location |\n| `taxi_cancel_order` | Cancel an order |\n| `taxi_generate_ride_app_link` | Generate deep link to DiDi App |\n\n### Route Planning\n\n| Tool | Purpose |\n|------|---------|\n| `maps_direction_driving` | Driving route planning |\n| `maps_direction_transit` | Bus/subway route planning |\n| `maps_direction_walking` | Walking route planning |\n| `maps_direction_bicycling` | Cycling route planning |\n| `maps_place_around` | Nearby search |\n\n---\n\n## Workflow\n\n### Ride-Hailing Flow\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│                      User requests a ride                       │\n│                \"Take me from Guomao to Sanlitun\"                │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 1: Address lookup (maps_textsearch)                       │\n│  - Resolve origin: Guomao → (116.458, 39.908)                   │\n│  - Resolve destination: Sanlitun → (116.455, 39.937)            │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 2: Confirm origin/destination                             │\n│  - Confirm with user when address was inferred or multiple      │\n│    candidates were returned                                     │\n│  - No confirmation needed when user specified a precise match   │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 3: Price estimate (taxi_estimate)                         │\n│  - Fetch available vehicle types and prices                     │\n│  - Present options if user hasn't specified a vehicle type      │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 4: Vehicle selection                                      │\n│  - Use user-specified type or preference default                │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 5: Create order (taxi_create_order)                       │\n│  - Create order with selected vehicle type                      │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 6: Output order info + tracking hint                      │\n│  - Display order ID, origin/destination, vehicle, estimated fare│\n│  - Prompt: send \"check order\" to see current status             │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 7: Auto status check (creates cron task)                  │\n│  - Schedules a follow-up check 5 minutes later                  │\n│  - Automatically queries order status and pushes notification   │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n### Order Status Codes\n\n| Code | Status | Description |\n|------|--------|-------------|\n| 0 | Matching | Finding a driver for you |\n| 1 | Driver Accepted | Shows driver name, vehicle, plate, ETA |\n| 2 | Driver Arrived | Prompt user to proceed to pickup |\n| 4 | Trip In Progress | Ride has started |\n| 5 | Completed | Display fare information |\n| 6 | Cancelled by System | System auto-cancelled |\n| 7 | Cancelled | User-cancelled |\n| 3/8-12 | Other terminal states | Display corresponding status description |\n\n### Confirmation Policy\n\n| Action | Confirmation |\n|--------|-------------|\n| Instant ride | No confirmation needed — dispatches using user-specified or preferred vehicle type |\n| Scheduled ride | Creates cron task directly; dispatches at scheduled time |\n| Cancel order | Show order details → wait for explicit user confirmation |\n\n---\n\n## Examples\n\n### Ride-Hailing\n\n**Basic ride request**\n```\nYou: Get me a car from Beijing West Station to Xierqi Subway Station\n\nAI: Resolving addresses...\nOrigin found: Beijing West Station (116.321, 39.894)\nDestination found: Xierqi Subway Station (116.297, 40.053)\n\nFetching prices...\n\n1. Economy Express: ~¥32\n2. Express: ~¥34\n3. Premier: ~¥54\n\nPlease select a vehicle type, or say \"confirm\" to use the recommended option.\n```\n\n**Specify vehicle type**\n```\nYou: Get me an Express from home to the office\n\nAI: Dispatching Express ride...\nOrder created! Order ID: qo01uCXI6ojeiD\n```\n\n**Scheduled ride**\n```\nYou: Tomorrow morning at 8am from home to the office\n\nAI: Scheduled task set for tomorrow 08:00.\nA ride will be dispatched automatically at that time.\n```\n\n**Check order**\n```\nYou: Check order qo01uCXI6ojeiD\n\nAI: Order ID: qo01uCXI6ojeiD\nStatus: Driver Accepted\nPlate: 京A·XXXXX\nDistance: ~1.2 km\nETA: 3 minutes\n```\n\n> Note: Only active (in-progress) orders can be queried via API. For historical orders, please check the DiDi app.\n\n**Driver location**\n```\nYou: Where is my driver?\n\nAI: 🚗 Driver Location\n📍 Location: Near CITIC Plaza, Jianguomenwai Ave, Chaoyang, Beijing\n📏 Distance: ~1.2 km\n⏱️ ETA: ~3 minutes\n```\n\n### Route Planning\n\n**Driving**\n```\nYou: Plan a driving route from Wangjing SOHO to Guomao\n\nAI: 🚗 Driving Route\n📍 Route: Wangjing SOHO → Guomao\n📏 Distance: ~8.5 km\n⏱️ Estimated time: ~25 min\n```\n\n**Transit**\n```\nYou: What's the subway/bus route from Beijing West Station to Xierqi?\n\nAI: 🚌 Transit Route\n📍 Route: Beijing West Station → Xierqi Subway Station\n⏱️ Estimated time: ~55 min\n🔄 Transfer: Line 9 → Line 13\n```\n\n**Walking**\n```\nYou: How long does it take to walk from home to the subway?\n\nAI: 🚶 Walking Route\n📍 Route: Home → Subway Station\n📏 Distance: ~800 m\n⏱️ Estimated time: ~10 min\n```\n\n**Cycling**\n```\nYou: How do I bike from Wangjing to Sanlitun?\n\nAI: 🚴 Cycling Route\n📍 Route: Wangjing → Sanlitun\n📏 Distance: ~6.2 km\n⏱️ Estimated time: ~28 min\n```\n\n**Nearby Search**\n```\nYou: Any coffee shops nearby?\n\nAI: ☕ Nearby Search Results\n📍 Coffee shops near your location:\n1. Luckin Coffee - ~150 m away\n2. Starbucks - ~320 m away\n3. Manner Coffee - ~580 m away\n```\n\n---\n\n## Technical Reference\n\n- Full workflow: [SKILL.md](SKILL.md)\n- API reference: [api_references.md](references/api_references.md)\n- Error handling: [error_handling.md](references/error_handling.md)\n\nFile v1.1.3:skill-card.md\n\n## Description:\n\nDiDi Ride SKILL lets an OpenClaw agent use DiDi MCP tools for ride hailing, order status, driver location, cancellation, route planning, and nearby search in supported Mainland China cities.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[didi](https://clawhub.ai/user/didi)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users use this skill through an agent to request DiDi rides, compare route and fare options, query active orders, cancel rides after confirmation, and manage ride preferences.\n\n### Deployment Geography for Use:\n\nMainland China cities served by DiDi; not available in Hong Kong, Macau, Taiwan, or outside China.\n\n## Known Risks and Mitigations:\n\nRisk: The skill requires a DiDi MCP key and can persist that credential.\n\nMitigation: Use a secure key setup path, avoid pasting keys into shared logs, and rotate any key exposed in chat or logs.\n\nRisk: The skill can create real ride orders and scheduled background tasks.\n\nMitigation: Require explicit user confirmation before dispatching, canceling, or scheduling rides.\n\nRisk: The skill can store local ride preferences such as addresses and phone numbers.\n\nMitigation: Store only necessary preference data and review local preference files before sharing or publishing the workspace.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/didi/skills/didi-ride-skill-official)\n- [DiDi MCP platform](https://mcp.didichuxing.com/claw)\n- [README.en.md](README.en.md)\n- [Setup guide](references/setup.md)\n- [Workflow reference](references/workflow.md)\n- [API references](references/api_references.md)\n- [Error handling guide](references/error_handling.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown with inline shell commands and structured ride or route status text]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May issue MCP tool calls through mcporter and may update local ride preference files when the user asks to save preferences.]\n\n## Skill Version(s):\n\n1.1.3 (source: package.json, ClawHub release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.1.3:package.json\n\n{\n  \"name\": \"didi-ride-skill\",\n  \"version\": \"1.1.3\",\n  \"description\": \"DiDi Ride Skill for OpenClaw - 打车、路线规划、周边搜索\",\n  \"type\": \"module\",\n  \"author\": \"DiDi MCP Team\",\n  \"homepage\": \"https://mcp.didichuxing.com\",\n  \"keywords\": [\n    \"didi\",\n    \"taxi\",\n    \"mcp\",\n    \"openclaw\",\n    \"mobility\"\n  ]\n}\n\nArchive v1.1.2: 8 files, 23628 bytes\n\nFiles: assets/PREFERENCE.md (3155b), package.json (323b), references/api_references.md (8174b), references/error_handling.md (7890b), references/setup.md (2478b), references/workflow.md (6533b), SKILL.md (20930b), _meta.json (143b)\n\nFile v1.1.2:SKILL.md\n\n---\nname: didi-ride-skill\ndescription: 中国城市出行服务。当用户表达任何交通出行需求时必须使用此技能——包括打车/叫车/网约车、查价格、路线规划（公交/驾车/步行/骑行）、周边搜索、查询订单/司机位置/取消订单。关键词：\"打车\"、\"叫车\"、\"去[地点]\"、\"回家\"、\"上班\"、\"下班\"、\"查价格\"、\"多少钱\"、\"路线\"、\"怎么走\"、\"步行到\"、\"附近\"、\"周边\"、\"司机\"、\"订单\"、\"查询订单\"。注意：即使用户未明确说\"打车\"，只要涉及从A地到B地、通勤、或交通方式选择，都应触发。不触发场景：开发打车应用、使用其他导航app、订外卖、查公交时刻表、股票/财报查询。\nhomepage: https://mcp.didichuxing.com\nmetadata:\n  { \"openclaw\": { \"emoji\": \"🚕\", \"always\": true, \"requires\": { \"bins\": [\"openclaw\", \"mcporter\"], \"env\": [\"DIDI_MCP_KEY\"] }, \"primaryEnv\": \"DIDI_MCP_KEY\", \"install\": [{ \"id\": \"node\", \"kind\": \"node\", \"package\": \"mcporter\", \"bins\": [\"mcporter\"], \"label\": \"Install mcporter (node)\" }] } }\n---\n\n# 滴滴出行服务 (DiDi Ride Skill)\n\n通过 DiDi MCP Server API 提供打车、查询订单、司机位置、预约叫车、路线规划、周边搜索能力。\n\n---\n\n## 1. 快速开始（2 分钟）\n\n### 1.1 获取 MCP KEY\n\n**方式一：用「滴滴出行App」扫码（推荐，最快）**\n\n![滴滴出行APP扫码获取MCP Key，解锁一键打车](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n> ⚠️ **Agent 注意**：用户客户端无法渲染 Markdown 图片，**禁止直接输出上方图片语法**。需向用户发送二维码时，执行 `### 3.9 MCP KEY 与配置` 中的 `openclaw message send` 命令发图。\n\n打开滴滴出行 App，扫描二维码，即可快速获取 MCP Key。\n\n**方式二：访问官网**\n\n访问 https://mcp.didichuxing.com/claw 获取您的 MCP Key。\n\n### 1.2 配置 Key\n\n**方式一：对话中输入（推荐）**\n\n直接在对话中告诉我您的 MCP Key，我会帮您配置：\n\n```\n你: 我的 MCP Key 是 xxxxxx\n```\n\n**方式二：OpenClaw 配置文件**\n\n编辑 `~/.openclaw/openclaw.json`，添加：\n\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"didi-ride-skill\": {\n        \"enabled\": true,\n        \"apiKey\": \"你的MCP_KEY\"  // apiKey 是 OpenClaw 标准字段名，存储的值就是滴滴平台的 MCP KEY\n      }\n    }\n  }\n}\n```\n\n### 1.3 开始使用\n\n配置完成后，直接对话即可：\n\n```\n你: 打车去北京西站\n你: 帮我查一下从国贸到三里屯的路线\n你: 查询订单\n```\n\n首次使用时，OpenClaw 会提示安装 mcporter 工具。\n\n---\n\n## 2. 用户指南\n\n本 Skill 支持以下操作：\n\n- **打车**：直接说\"打车去[地点]\"、\"回家\"、\"上班\"\n- **查价**：查一下从 A 到 B 多少钱\n- **查询订单**：输入「查询订单」了解当前订单状态（司机位置、行程进度等）\n- **司机位置**：司机在哪里、多久到\n- **预约出行**：\"15分钟后打个车\"、\"明天9点去机场\"\n- **路线规划**：驾车/公交/步行/骑行路线\n- **取消订单**：取消当前订单\n\n---\n\n## 3. Agent 执行指令\n\n以下内容为 AI 执行参考，用户可忽略。\n\n### 3.1 文件地图 \n\n按需读取以下文件，不要猜测未读过的内容：\n\n| 文件 | 用途 | 何时读取 |\n|------|------|----------|\n| `SKILL.md` | 触发、主流程、硬性门禁、查询订单规则、预约出行规则 | 每次触发必读 |\n| `references/workflow.md` | 分阶段详细流程与命令范式 | 需要实现细节时读 |\n| `references/api_references.md` | MCP 函数签名与参数定义 | 每次调用工具前**必须**核对 |\n| `references/error_handling.md` | create_order 失败提示、mcporter 常见错误、统一错误码、参数错误排查 | ⚠️ 遇到任何调用失败（HTTP error / StatusCode=400 / `-32xxx` 错误码 / `Unknown MCP server` / `Missing KEY parameter`）必须读取此文件 |\n| `references/setup.md` | 安装 mcporter、配置 MCP KEY 的完整步骤 | 用户询问安装/配置问题时读 |\n| `assets/PREFERENCE.md` | 地址别名/车型/手机号偏好 | 用户提到别名地址（家、公司、妈妈家等）、车型、手机号，或未明确给出起终点时**必须**读取。别名匹配规则见执行前检查第 7 条 |\n\n### 3.2 执行前检查\n\n1. **检查 mcporter**：若 `mcporter` 不存在（`command not found`），停止并引导用户阅读 `references/setup.md`。没有 mcporter 就无法调用任何 MCP 工具，后续任何流程都无法执行。\n\n2. **检查 Key**：执行 `openclaw config get skills.entries.didi-ride-skill.apiKey`，若输出为空或非 `__OPENCLAW_REDACTED__`，按 `### 3.9 MCP KEY 与配置` 流程引导。Key 缺失时 mcporter 的报错信息具有误导性，不要尝试绕过。\n   - ⚠️ **若 Key 已配置（返回 `__OPENCLAW_REDACTED__`）但 mcporter 仍报 `Missing KEY parameter`**：**不是 Key 失效**，**禁止向用户索要 Key**。排查步骤见 `references/error_handling.md` 中的「mcporter Missing KEY parameter」章节。\n\n3. **mcporter.json 注意事项**：本 skill 使用 URL 直连模式，**不依赖 `config/mcporter.json`**，**禁止创建或修改该文件**。如果 mcporter 启动时报 JSON 校验错误（`invalid_type` / `Failed to parse JSON`），参见 `references/error_handling.md` 中的「mcporter.json 校验错误」章节。\n\n4. **mcporter 调用格式**（固定写法，不要变形）：\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" <tool> --args '{\"key\":\"value\"}'\n```\n\n**必读注意事项**：\n- `MCP_URL` 赋值和 `\"$MCP_URL\"` 引用**都必须用英文双引号**，否则 `$DIDI_MCP_KEY` 不会被 shell 展开。禁止用单引号或中文引号。\n- **禁止添加 `--server` 标志**（如 `--server didi-mcp`）。`--server` 会让 mcporter 去查找已注册的命名 server，找不到直接报 `Unknown MCP server`；即使找到了也会和 URL 参数冲突导致 `Missing tool name`。\n- **参数名必须核对 `references/api_references.md`**，不要凭记忆。常见致命错误：`keyword` → 应为 `keywords`；`region` → 应为 `city`；`from_lng/from_lat/to_lng/to_lat` → 应为 `from_name/from_lat/from_lng/to_name/to_lat/to_lng`（六字段，不是四字段）。\n- mcporter 对参数错误的报错信息为 `backend call failed: ... StatusCode=400`（**不会告诉你具体哪个参数错了**），遇到此错误第一反应是核对参数名，详见 `references/error_handling.md`。\n- 遇到不确定的参数名时，执行 `mcporter list \"$MCP_URL\"` 可以查看所有工具的完整签名。\n\n5. **参数值必须加引号**（字符串格式），包括经纬度和 `product_category` 等数字语义字段——API 只接受字符串，否则会报\"缺少必填参数\"。\n6. **先预估再下单**：`taxi_create_order` 依赖 `taxi_estimate` 返回的 `traceId`，没有 traceId 下单会失败。traceId 有时效性，过期（`-32021` 错误）需重新预估。\n7. **起终点处理**：\n\n   **坐标来源**：坐标必须来自 `maps_textsearch`，不要凭空猜测。**禁止用对话历史记忆补充起终点**——用户可能已换了地方。\n\n   **缺失补全**（按优先级）：① 读 `assets/PREFERENCE.md`，有地址别名**且值非空**则按场景推断（早晨→起点\"家\"、下班→起点\"公司\"；别名行存在但地址为空 = 未配置）→ ② 无可用别名则直接询问用户。\n\n   **别名匹配**：精确优先——\"家\"只匹配\"家\"，不匹配\"妈妈家\"；需明确含\"妈妈\"语义才匹配\"妈妈家\"。读取时**必须扫描整张表格**（到下一个 `##` 为止），不要只看默认的前两行——用户可能已追加\"妈妈家\"\"儿子学校\"\"健身房\"等自定义别名。\n\n   **确认规则**：推断的起终点、或 `maps_textsearch` 返回多个候选时，必须在主流程 step 2 向用户确认；用户明确指定且精确匹配的地点无需确认。\n\n8. **`taxi_create_order` 参数约束**：\n- 只接受三个字段：`estimate_trace_id`、`product_category`、`caller_car_phone`（可选）\n- `taxi_create_order` 的 `caller_car_phone` 未由用户提供时，从 `assets/PREFERENCE.md` 的「默认偏好」表读取；都没有就**不传该参数**，禁止在对话中反复向用户索要手机号——skill 级别已允许没有手机号直接发单，口头询问一次若用户未答应即视为\"用默认/不传\"。\n- 不要把 `taxi_estimate` 的坐标/名称字段（`from_lat` / `from_lng` / `from_name` / `to_lat` / `to_lng` / `to_name`）带入。\n\n### 3.3 用户确认策略\n\n| 场景 | 规则 |\n|------|------|\n| 打车（实时/预约） | 推断的地址或搜索返回多个候选时必须确认起终点（见主流程 step 2），用户明确指定且精确匹配时无需确认，确认后再预估下单 |\n| 取消订单 | 即使用户说了\"取消订单\"，仍必须先明确询问\"确认取消吗？\"，等用户回复确认后才能调用 `taxi_cancel_order`。用户的取消意图 ≠ 取消确认。 |\n\n### 3.4 主流程（最小可执行）\n\n1. 地址解析：`maps_textsearch`（必要时结合 `assets/PREFERENCE.md`，按执行前检查第 7 条处理）。\n2. 确认起终点：\n   - **单一精确匹配**（用户描述明确 + `maps_textsearch` 仅返回 1 个结果）→ 无需确认，直接使用；\n   - **多个候选**（`maps_textsearch` 返回 ≥2 个同名或近似地点）→ **必须列出至少前 3 个候选供用户选择**（如\"搜索到以下万达广场：1) 朝阳CBD店 2) 石景山店 3) 通州店，请问您要去哪个？\"），**不要自行代选或只展示一个**；\n   - **别名推断**（从 PREFERENCE.md 推断的起终点）→ 向用户确认 + 告知推断来源（如\"按偏好里「家」推断终点是望京 SOHO，对吗？\"）；\n   - 用户明确指定且文本精确匹配的地点 → 无需确认。用户纠正则按纠正内容重新解析。\n3. 价格预估：`taxi_estimate`，记录 `traceId`。\n4. 车型决策（优先级：**当前消息 > 偏好 > 询问用户**）：\n   - 用户在当前消息中明确指定车型（如\"叫快车\"\"帮我叫专车\"）→ 在 `taxi_estimate` 返回列表中**精确匹配**对应 `productCategory`（快车=1，专车=8），覆盖一切偏好设置；\n   - 用户未指定 → 使用 `assets/PREFERENCE.md` 中场景车型偏好的精确 `productCategory` 值；\n   - 偏好也未配置 → 向用户询问车型，不要自行推荐；\n   - 注意：快车（1）和特惠快车（201）是**不同服务等级**，不可因价格更优而自动替换；\n   - 可用车型以 `taxi_estimate` API 返回为准。若不包含指定/偏好的 `productCategory`，向用户说明并让其重新选择，不要默默用近似车型替代。\n   - ⚡ **简化原则（尤其对 reasoning 模型）**：用户在当前消息中说什么车型就用什么，不要进一步质疑或反复确认；偏好缺失时直接向用户问一次即可，不要在同一轮列出多个权衡选项让用户挑。规则很短，不要过度展开思考分支。\n5. 创建订单：`taxi_create_order`（使用最新 `traceId`）。\n   - 若此调用返回 `Streamable HTTP error: Unexpected content type: text/plain`，**立即停止流程**，按 `references/error_handling.md` 的「taxi_create_order 调用失败」章节向用户输出固定文案。禁止重试、禁止切换 Key、禁止跳过此步继续往下。\n6. 结果输出：给出订单号、起终点、车型、预估价，末尾提示 `💡 发送「查询订单」可了解当前订单状态`，并告知 `⏱️ 将在 5 分钟后自动为您回查订单状态`。\n7. ⚠️ 自动回查（必做）：根据 `### 3.8 发单后自动回查` 中的 cron 指令内容，创建定时任务，参数信息严格遵循章节内要求。此步不可省略。\n\n### 3.5 偏好设置更新\n\n当用户要求设置/记住/记一下/帮我记/保存地址别名、车型偏好或手机号时，**必须**通过文件编辑工具（`Edit` / `Write`）修改 `assets/PREFERENCE.md` 对应的 markdown 表格行。**严禁**仅以文字回复\"记住了/已保存\"而不调用文件编辑工具——偏好必须落盘到文件，口头承诺无效。\n\n**执行步骤**：\n1. `Read` 读取 `assets/PREFERENCE.md` 完整内容（注意表格可能已有用户追加的行）；\n2. 定位要更新的表格行（地址别名表 / 场景车型偏好表 / 默认偏好表）；\n3. 对地址别名：先调用 `maps_textsearch` 获取坐标，再更新表格行；\n4. 调用 `Edit`（替换单行）或 `Write`（整表重写）写入新值；\n5. **回读验证**：再次 `Read` 确认新值已落盘。若未成功，告知用户并重试。\n\n- **地址别名**（\"我家在…\"、\"公司在…\"、\"儿子的学校是…\"、\"妈妈家在…\"）：先调用 `maps_textsearch` 解析地址获取坐标，然后更新「地址别名」表——已有别名更新对应行，新别名追加新行。别名由用户定义，不限于\"家\"\"公司\"。\n- **场景车型**（\"上班用快车\"、\"下班用特惠和快车\"）：更新「场景车型偏好」表对应行。品类代码参考表底注释，多车型用英文逗号分隔（如 `1,201`）。\n- **叫车手机号**（\"我的手机号是…\"）：更新「默认偏好」表中的叫车手机号行。\n- **创建订单时**：若 PREFERENCE.md 中配置了叫车手机号，将其作为 `caller_car_phone` 参数传入 `taxi_create_order`，`caller_car_phone` 为可选参数，若未配置则不传。\n\n### 3.6 查询订单\n\n触发词：`查询订单` / `查询订单 <orderId>`\n\n订单号来源（优先级从高到低）：\n1. 用户消息中明确给出；\n2. 当前对话上下文中最近一次创建的订单号；\n3. 以上均无时，向用户询问。\n\n调用命令：\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" taxi_query_order --args '{\"order_id\":\"ORDER_ID\"}'\n```\n\n#### 3.6.1 状态码与输出规则\n\n| code | 含义 | 必须输出 |\n|------|------|----------|\n| 0 | 匹配中 | ⏳ 正在为您匹配司机，请稍候 |\n| 1 | 司机已接单 | **必须展示**：司机姓名、车型、车牌、电话；距上车点距离和预计到达时间 |\n| 2 | 司机已到达 | 🔔 司机已到达上车点，请前往上车 |\n| 4 | 行程进行中 | 🚗 行程已开始 |\n| 5 | 订单完成 | ✅ 行程结束，展示费用（如有） |\n| 6 | 订单已被系统取消 | ❌ 订单已被系统取消 |\n| 7 | 订单已被取消 | ❌ 订单已取消 |\n| 3/8-12 | 其他终态 | 显示对应状态描述 |\n\n### 3.7 预约出行规则\n\n当用户要求在特定时间叫车（如\"15分钟后\"、\"明天9点\"）：\n\n- 使用 cron 一次性任务（`--at`），到点由 isolated agent 独立执行完整打车流程；\n- ⚠️ `--message` 必须包含完整起终点（带城市前缀）和车型，isolated session 无历史上下文。起点或终点缺失时先从 `assets/PREFERENCE.md` 推断并向用户确认，推断不了则必须先询问用户，**不要自行推断未知信息**；\n- 到点后 agent 自行执行：地址解析 → 价格预估（获取最新 traceId）→ 创建订单；\n- 如果无法获取当前会话的 metadata（channel/chat_id），**仅跳过 cron 创建步骤**，其余流程（地址解析 → 价格预估 → 展示结果）**正常执行不受影响**。在回复中提醒用户到时手动发消息叫车。metadata 不可用 ≠ 放弃整个打车流程；\n- 如果定时任务创建失败，必须在回复中提示用户，不能默默失败。\n\n```bash\n# ⚠️ 替换占位符：\n#   FROM_NAME    → 带城市前缀的起点全称（如\"北京市西二旗地铁站\"）\n#   TO_NAME      → 带城市前缀的终点全称（如\"北京市佰嘉城小区\"）\n#   VEHICLE      → 车型（如\"快车\"）\n#   TIME         → 见下方时间规则\n#   CHANNEL_NAME → 当前会话 metadata 中的 channel 字段（如 feishu、telegram），CHANNEL_NAME 不需要带引号，例如: feishu ✅, \"feishu\" ❌。不允许使用 last 作为参数值。\n#   CHAT_ID      → 当前会话 metadata 中的 chat_id 字段\n\n\nopenclaw cron add \\\n  --name \"didi-ride-skill:$(date +%s)\" \\\n  --at \"TIME\" \\\n  --session isolated \\\n  --message \"执行定时打车：起点「FROM_NAME」，终点「TO_NAME」，车型「VEHICLE」。请完整执行打车流程：地址解析 → 价格预估（获取最新 traceId）→ 创建订单。订单创建成功后，输出订单信息并提示用户可发送「查询订单」了解订单状态，同时创建 5 分钟后自动回查 cron（模板见 SKILL.md 第 3.8 节「发单后自动回查」）。\" \\\n  --announce \\\n  --channel CHANNEL_NAME \\\n  --to \"CHAT_ID\"\n```\n\n#### 3.7.1 TIME 填写规则\n\n| 场景 | 写法 | 示例 |\n|------|------|------|\n| 相对时间（X 分钟/小时后） | duration 格式 | `15m` / `2h` / `1h30m` |\n| 绝对时间（具体时刻） | 本地时区 ISO 格式 | `$(date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00')` |\n\n- 相对时间（如 `15m`）无需格式化，直接使用\n- 绝对时间使用带时区的 ISO 8601 格式：`YYYY-MM-DDTHH:MM:SS+08:00`（北京时间东八区）\n\n**系统兼容性说明：**\n- Linux (GNU date): `date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n- macOS (BSD date): `TZ=Asia/Shanghai date -j -v+1d -f '%H:%M' '09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n\n### 3.8 发单后自动回查\n\n发单成功后（实时单或预约单），根据本章节下文 \"openclaw cron add\" 命令，创建 cron 任务，务必按照本章节下文bash命令参数设置。\n- 如果无法获取当前会话的 metadata（channel/chat_id），**仅跳过 cron 创建步骤**，主流程正常完成（已出单则告知用户\"5 分钟后可发送'查询订单'了解最新状态\"）。\n- 如果定时任务创建失败，必须在回复中提示用户，不能默默失败。\n\n```bash\n# ⚠️ 替换占位符（CHANNEL_NAME/CHAT_ID 规则见 §3.7）：\n#   ORDER_ID     → 实际订单号（taxi_create_order 返回）\n\nopenclaw cron add \\\n  --name \"didi-ride-skill:check:ORDER_ID\" \\\n  --at \"5m\" \\\n  --session isolated \\\n  --message \"查询滴滴订单状态：订单号 ORDER_ID。调用 taxi_query_order 查询并输出当前状态。如果司机已接单，输出司机姓名、车型、车牌、电话及预计到达时间；如果仍在匹配中，提示用户耐心等待。\" \\\n  --announce \\\n  --channel CHANNEL_NAME \\\n  --to \"CHAT_ID\"\n```\n\n### 3.9 MCP KEY 与配置\n\n> **术语说明**：滴滴平台称此凭证为「MCP KEY」，OpenClaw 配置字段统一叫 `apiKey`，注入后的环境变量为 `DIDI_MCP_KEY`——三者是同一个值。通过 `openclaw config set` 持久化后，OpenClaw 在每次 agent run 启动时自动注入为环境变量。\n\n#### 3.9.1 检查 Key 状态\n\n```bash\n# 执行该命令以判断当前 DIDI_MCP_KEY 是否已配置\nopenclaw config get skills.entries.didi-ride-skill.apiKey\n```\n输出 `__OPENCLAW_REDACTED__` = 已配置，可使用环境变量 `$DIDI_MCP_KEY`；输出为空 = 未配置。\n\n#### 3.9.2 持久化用户 Key\n\n⚠️ 当用户回复了 Key（如\"我的 Key 是 xxxxxx\"），**必须**执行以下命令持久化 & 在当前 Shell 生效：\n\n```bash\n#   YOUR_KEY → 实际的 MCP KEY\nopenclaw config set 'skills.entries.didi-ride-skill.apiKey' 'YOUR_KEY'\nexport DIDI_MCP_KEY='YOUR_KEY'\n```\n\n- 持久化后 OpenClaw 在所有后续 agent run（含 cron isolated session）中自动注入 `DIDI_MCP_KEY`\n- ⚠️⚠️⚠️ 命令输出 `\"Restart the gateway to apply.\"` ——**这是通用提示，必须忽略，禁止执行 restart**。`apiKey` 每次 agent run 动态读取，无需重启；强制重启会导致网关崩溃\n\n#### 3.9.3 Key 缺失或鉴权失败\n\n⚠️ Key 未配置**或** MCP 返回鉴权失败（`error.code: -32002`）时，依次执行：\n\n1. 发送二维码图片（`{CHAT_ID}` → metadata 的 chat_id，`{CHANNEL_NAME}` → metadata 的 channel）：\n\n```bash\nopenclaw message send --channel {CHANNEL_NAME} --target {CHAT_ID} --media \"https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png\" --message \"滴滴出行APP扫码获取MCP Key，解锁一键打车\"\n```\n\n2. 输出文字：\n\n> 您还没有配置 DIDI_MCP_KEY 或 Key 已失效，请访问 [滴滴MCP平台](https://mcp.didichuxing.com/claw) 获取 MCP KEY，然后配置环境变量或在 OpenClaw 配置文件中设置。\n\n### 3.10 工具清单\n\n| 领域 | 工具 |\n|------|------|\n| 地图 | `maps_textsearch`, `maps_regeocode` |\n| 路线 | `maps_direction_driving`, `maps_direction_transit`, `maps_direction_walking`, `maps_direction_bicycling` |\n| 周边 | `maps_place_around` |\n| 打车 | `taxi_estimate`（预估）, `taxi_create_order`（下单）, `taxi_query_order`（查单+司机位置）, `taxi_cancel_order`（取消） |\n\nFile v1.1.2:_meta.json\n\n{\n  \"ownerId\": \"kn7can12c6x8pp8ade0sxqkv6582sfzp\",\n  \"slug\": \"didi-ride-skill-official\",\n  \"version\": \"1.1.2\",\n  \"publishedAt\": 1777021961192\n}\n\nFile v1.1.2:references/api_references.md\n\n# API 文档\n\n## 响应格式说明\n\n所有工具均返回 `content[].text`（自然语言文本）。部分工具（网约车类）额外返回 `structuredContent`（结构化数据）。\n\n- 如果响应中存在 `structuredContent`，优先使用其中的字段做逻辑判断和字段提取\n- 如果没有 `structuredContent`，则解析 `content[].text` 获取所需信息\n\n## 函数签名\n\n```\n/**\n   * 根据用户输入的起点终点坐标，规划骑行通勤方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_bicycling(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户起终点经纬度坐标规划以小客车、轿车通勤出行的方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_driving(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户起终点坐标，规划综合公交、地铁的通勤方案\n   *\n   * @param city 查询城市（**必须使用完整格式，如\"北京市\"而非\"北京\"**）\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_transit(city: string, destination: string, origin: string);\n\n  /**\n   * 根据用户输入的起点终点坐标，规划步行通勤方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_walking(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户传入关键词和位置坐标，搜索出周边的POI地点信息\n   *\n   * @param keywords 搜索关键词\n   * @param location 位置坐标，格式为：经度,纬度\n   * @param max_distance? 搜索半径，单位：米\n   */\n  function maps_place_around(keywords: string, location: string, max_distance?: string);\n\n  /**\n   * 将经纬度坐标转换为地址信息\n   *\n   * @param location 位置坐标，格式为：经度,纬度\n   */\n  function maps_regeocode(location: string);\n\n  /**\n   * 根据用户传入关键词和城市，搜索出相关的POI地点信息\n   *\n   * @param city 查询城市（**必须使用完整格式，如\"北京市\"而非\"北京\"**）\n   * @param keywords 搜索关键词\n   * @param location? 位置坐标，格式为：经度,纬度\n   */\n  function maps_textsearch(city: string, keywords: string, location?: string);\n\n  /**\n   * 取消打车订单\n   *\n   * @param order_id 订单ID，从订单创建或查询结果中获取\n   * @param reason? 取消原因，可选参数。例如：不需要了、等待时间太长、临时有事等\n   */\n  function taxi_cancel_order(order_id: string, reason?: string);\n\n  /**\n   * 直接通过API创建打车订单，无需打开任何应用程序界面，系统自动完成整个发单流程\n   *\n   * @param caller_car_phone? 叫车人手机号，如果有就要传递，没有就不传\n   * @param estimate_trace_id 预估流程ID，从预估结果中获取\n   * @param product_category 车型品类标识，从预估结果中获取，传入多个车型时，用英文逗号分割，不要带空格\n   * @returns structuredContent.orderId   订单ID，后续查询/取消订单使用\n   * @returns structuredContent.status    订单初始状态（created）\n   */\n  function taxi_create_order(caller_car_phone?: string, estimate_trace_id: string, product_category: string);\n\n  /**\n   * 查看当前可用的网约车车型，请先获取对应地点的经纬度信息，如果有maps_textsearch的tool，优先使用maps_textsearch进行经纬度的获取。\n   *\n   * @param from_lat 出发纬度，必须从地图相关的工具获取，不能假设\n   * @param from_lng 出发经度，必须从地图相关的工具获取，不能假设\n   * @param from_name 出发地名称\n   * @param to_lat 目的纬度，必须从地图相关的工具获取，不能假设\n   * @param to_lng 目的经度，必须从地图相关的工具获取，不能假设\n   * @param to_name 目的地名称\n   * @returns structuredContent.traceId          预估流程ID，创建订单时必须传入\n   * @returns structuredContent.items[]          可用车型列表\n   * @returns structuredContent.items[].productName     车型名称\n   * @returns structuredContent.items[].productCategory 车型品类代码，创建订单时传入\n   * @returns structuredContent.items[].priceText       预估价格（元）\n   */\n  function taxi_estimate(from_lat: string, from_lng: string, from_name: string, to_lat: string, to_lng: string, to_name: string);\n\n  /**\n   * 根据起点、终点和车型生成打开移动应用或小程序的深度链接，用户点击后将跳转到相应的打车应用完成发单操作\n   *\n   * @param from_lat 出发纬度，必须从地图相关的工具获取，不能假设\n   * @param from_lng 出发经度，必须从地图相关的工具获取，不能假设\n   * @param product_category? 车型品类标识列表，从预估结果中获取，支持多个车型，仅当用户明确指定某个或某些品类时才传递此参数，格式为英文逗号,分割\n   * @param to_lat 目的地纬度，必须从地图相关的工具获取，不能假设\n   * @param to_lng 目的经度，必须从地图相关的工具获取，不能假设\n   */\n  function taxi_generate_ride_app_link(from_lat: string, from_lng: string, product_category?: string, to_lat: string, to_lng: string);\n\n  /**\n   * 获取打车订单对应司机的实时位置经纬度\n   *\n   * @param order_id 打车订单ID\n   */\n  function taxi_get_driver_location(order_id: string);\n\n  /**\n   * 查询打车订单的状态和信息，如司机联系方式、车牌号、预估到达时间\n   *\n   * ⚠️ 重要：此函数单次调用仅返回当前状态。\n   * 单次调用返回当前状态，详见 SKILL.md `### 3.6 查询订单`。\n   *\n   * @param order_id? 订单ID，从创建订单结果中获取，如果有就要传递，如果没有，会查询当前账号下未完成的订单\n   * @returns structuredContent.statusCode  订单状态码（见下表）\n   * @returns structuredContent.statusText  状态文本描述\n   * @returns structuredContent.driver      司机信息（name/phone/carModel/carPlate），接单后可用\n   * @returns structuredContent.map.distanceKm  距离（公里），行程中可用\n   * @returns structuredContent.map.eta         预计剩余时间（分钟），行程中可用\n   * @returns structuredContent.map.phase       当前阶段：to_pickup（前往上车点）| to_dropoff（前往终点）\n   *\n   * 订单状态码：\n   *   0  匹配中（非终态）\n   *   1  司机已接单（非终态）\n   *   2  司机已到达（非终态，里程碑通知）\n   *   3  未知状态（终态）\n   *   4  行程开始（非终态，里程碑通知）\n   *   5  订单完成（终态）✅\n   *   6  订单已被系统取消（终态）✅\n   *   7  订单已被取消（终态）✅\n   *   8  未知状态（终态）✅\n   *   9  未知状态（终态）✅\n   *   10 未知状态（终态）✅\n   *   11 客服关闭订单（终态）✅\n   *   12 未能完成服务（终态）✅\n   */\n  function taxi_query_order(order_id?: string);\n```\n\nExamples:\n\n```bash\n# 设置 MCP_URL 变量\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\n\n# 地址解析（city 建议使用完整行政区名称）\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"望京SOHO\",\"city\":\"北京市\"}'\n\n# 价格预估（注意：所有参数值必须加引号，使用字符串格式）\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lat\":\"39.9\",\"from_lng\":\"116.4\",\"from_name\":\"望京SOHO\",\"to_lat\":\"39.9\",\"to_lng\":\"116.4\",\"to_name\":\"国贸\"}'\n```\n\nFile v1.1.2:references/error_handling.md\n\n# 错误处理指南\n\n本文档说明 didi-ride-skill skill 使用过程中可能遇到的错误及解决方案。\n\n> `<skill-dir>` 代表 didi-ride-skill 技能的安装根目录（即 SKILL.md 所在目录），可通过 `openclaw skills info didi-ride-skill` 获取。\n\n## 目录\n\n- [错误处理指南](#错误处理指南)\n  - [目录](#目录)\n  - [mcporter Missing KEY parameter](#mcporter-missing-key-parameter)\n  - [mcporter.json 校验错误](#mcporterjson-校验错误invalid_type--failed-to-parse-json)\n  - [taxi_create_order 调用失败](#taxi_create_order-调用失败)\n  - [Unknown MCP server 错误](#unknown-mcp-server-错误)\n  - [统一错误码表](#统一错误码表)\n  - [参数错误排查](#参数错误排查statuscode400--backend-call-failed)\n  - [常见问题 (FAQ)](#常见问题-faq)\n  - [获取帮助](#获取帮助)\n\n***\n\n## mcporter Missing KEY parameter\n\nmcporter 报 `Missing KEY parameter` 时，**不代表 MCP Key 已失效**，禁止直接向用户索要 Key。\n\n可能原因（按概率排序逐一排查）：\n\n1. **`$DIDI_MCP_KEY` 环境变量未展开**：`MCP_URL` 赋值时用了单引号（`'$DIDI_MCP_KEY'`）而非双引号，导致变量字面量传入。确认调用命令中 `MCP_URL` 使用双引号包裹，然后重试。\n2. **当前 shell 未注入环境变量**：openclaw 在每次 agent run 启动时自动注入 `DIDI_MCP_KEY`，但手动在终端直接运行 mcporter 时该变量不存在。执行 `echo $DIDI_MCP_KEY` 验证——若为空，在终端手动 `export DIDI_MCP_KEY=<key>` 后重试，或改在 openclaw agent 环境中调用。\n3. **mcporter.json 配置异常**：若当前目录下 `config/mcporter.json` 或 `~/.mcporter/mcporter.json` 存在且格式异常，mcporter 会在启动阶段直接崩溃（报 `invalid_type` 或 `Failed to parse JSON`），所有命令不可用。**不要删除该文件**（可能包含用户其他应用的配置），改用 `--config` 绕过——见 SKILL.md §3.2 第 3 条。\n4. **Key 本身确实无效**：若以上均排除，执行 `openclaw config get skills.entries.didi-ride-skill.apiKey` 确认 Key 已配置，若返回空则按 `### 3.9 MCP KEY 与配置` 流程重新配置。\n\n***\n\n## mcporter.json 校验错误（`invalid_type` / `Failed to parse JSON`）\n\nmcporter 启动时报 `invalid_type, expected record` 或 `Failed to parse JSON` 等校验错误时，说明当前目录的 `config/mcporter.json` 或 `~/.mcporter/mcporter.json` 存在且内容异常（格式不正确、空文件、或 AI 之前错误创建的）。\n\n**格式错误的 mcporter.json 会阻止 mcporter 所有命令执行**，包括 URL 直连模式。\n\n**解决方法**（不要删除用户的 mcporter.json，可能包含其他应用配置）：\n\n```bash\n# 创建一个空的合法配置用于绕过\necho '{\"mcpServers\":{}}' > /tmp/.mcporter-empty.json\n# 后续所有 mcporter 命令加 --config 参数\nmcporter --config /tmp/.mcporter-empty.json call \"$MCP_URL\" <tool> --args '...'\n```\n\n本 skill 使用 URL 直连模式，不依赖 mcporter.json。**禁止创建或修改 `config/mcporter.json`**。\n\n***\n\n## taxi_create_order 调用失败\n\n调用 `taxi_create_order` 时若返回 `Streamable HTTP error: Unexpected content type: text/plain; charset=utf-8`，按以下方式处理。\n\n1. **停止当前打车流程**（不要继续重试或切换 tool，也不要向用户索要新的 Key）；\n2. 向用户输出以下**固定文案**（原样复制，不要改写）：\n\n   > 未开通DiDi MCP 免密支付的用户，需要到 DiDi MCP 官网开通免密支付，审核完成后，即可调用全部的打车接口能力\n\n> ⚠️ 见到该字面量直接进入本章节处理，输出固定文案并停止流程，不要自行扩展解释。\n\n***\n\n## Unknown MCP server 错误\n\nmcporter 报 `Unknown MCP server 'xxx'` 时，根据 `xxx` 的值判断：\n\n- **`xxx` 是工具名**（如 `Unknown MCP server 'maps_textsearch'`）：说明命令格式不对。第一个位置参数必须是完整 URL（`\"$MCP_URL\"`），第二个位置参数才是 tool name。检查是否遗漏了 URL、或 URL 变量未定义。\n- **`xxx` 是自定义名称**（如 `Unknown MCP server 'didi-mcp'`）：说明使用了 `--server` 标志。**本 skill 禁止使用 `--server` 标志**——它需要已注册的命名 server，而 didi-ride-skill 始终使用 URL 直连模式。去掉 `--server xxx` 参数后重试。\n\n***\n\n## 统一错误码表\n\n所有 MCP 工具返回的统一错误码对照：\n\n| 错误码 | 说明 | 解决方案 |\n|--------|------|----------|\n| `-32001` | 命中限流 | 请等待一段时间后重试（配额限制按时间窗口重置） |\n| `-32002` | 鉴权失败（`auth failed`） | Key 存在但无效或已过期，执行 `### 3.9 MCP KEY 与配置` 的引导流程（含发送二维码） |\n| `-32010` | 参数验证失败 | 检查参数格式，确保所有值为字符串 |\n| `-32011` | 订单不存在 | 确认订单ID正确 |\n| `-32021` | 预估结果过期 | 重新调用价格预估获取新的 traceId |\n| `-32030` | 不支持订单类型 | 该类型订单不支持此操作 |\n| `-32031` | 订单未支付 | 订单未进入支付状态 |\n| `-32040` | 订单已经取消过了 | 订单已被取消，无需重复操作 |\n| `-32041` | 订单无法被取消 | 司机已接单或订单已完成，无法通过 API 取消 |\n| `-32050` | 内部错误 | 稍后重试，如持续失败请联系客服 |\n| `-32060` | 支付失败 | 检查支付账户状态或更换支付方式 |\n\n***\n\n## 参数错误排查（`StatusCode=400` / `backend call failed`）\n\nmcporter 返回 `backend call failed: ... StatusCode=400` 时，**根因几乎都是参数问题**（mcporter 不会展示 MCP Server 返回的具体错误原因，只给出 StatusCode）。按以下顺序逐项排查：\n\n1. **参数名拼写**——最常见根因。典型错误对照：\n\n   | 错误写法 | 正确写法 | 所属工具 |\n   |----------|----------|----------|\n   | `keyword` | `keywords`（复数） | `maps_textsearch`、`maps_place_around` |\n   | `region` / `province` | `city` | `maps_textsearch`、`maps_direction_transit` |\n   | `origin` / `destination` | `from_lat`/`from_lng`/`from_name` 与 `to_lat`/`to_lng`/`to_name`（六字段） | `taxi_estimate`、`taxi_generate_ride_app_link` |\n   | `order` / `orderId` | `order_id`（snake_case） | `taxi_query_order`、`taxi_cancel_order`、`taxi_get_driver_location` |\n   | `traceId` | `estimate_trace_id` | `taxi_create_order` |\n\n2. **必填参数缺失**——例如 `maps_textsearch` 的 `city` 必填（即使已提供坐标也不能省）。\n\n3. **类型错误**——`--args` JSON 对象内**所有参数值必须是字符串**：\n   - 经纬度 `\"39.908858\"` ✅，不是 `39.908858` ❌\n   - `product_category` 填 `\"1\"` ✅，不是 `1` ❌\n\n4. **城市名完整格式**——`\"北京市\"` ✅，`\"北京\"` ❌。\n\n5. **自检手段**——如果以上都核对过仍失败，执行 `mcporter list \"$MCP_URL\"` 查看工具的完整函数签名，逐字段比对。\n\n> ⚠️ **不要因为看到 `StatusCode=400` 就怀疑 mcporter 工具坏了**。这个报错 99% 是参数问题，不是 mcporter 或网络问题。\n\n***\n\n## 常见问题 (FAQ)\n\n**Q: 为什么说\"我要上班\"没反应？**\nA: 需要先配置 `assets/PREFERENCE.md` 中的家和公司地址，以及上班场景的车型偏好。\n\n**Q: 预估价格和实际价格不一致？**\nA: 预估价格为参考值，实际费用以行程完成后为准。\n\n**Q: 如何查看历史订单？**\nA: 当前 API 仅支持查询 MCP 渠道未完成订单，历史订单请在滴滴 App 中查看。\n\n**Q: 支持哪些城市？**\nA: 支持滴滴服务覆盖的所有中国大陆城市。\n\n***\n\n## 获取帮助\n\n如果以上方案无法解决问题，请：\n\n1. 检查 [workflow.md](./workflow.md) 确认操作流程\n2. 访问 <https://mcp.didichuxing.com> 获取最新文档\n\nFile v1.1.2:references/setup.md\n\n# DiDi MCP Server 安装配置指南\n\n本文档说明如何安装和配置 DiDi MCP Server，以便使用 didi-ride-skill skill。\n\n## 1. 安装 mcporter\n\nmcporter 是用于调用 MCP Server 的命令行工具。\n\n```bash\nnpm install -g mcporter\n```\n\n验证安装：\n```bash\nmcporter --version\n```\n\n## 2. 获取 MCP KEY\n\n访问 https://mcp.didichuxing.com/claw 获取您的 MCP KEY，或扫描下方二维码直达官网注册页面。\n\n![滴滴出行APP扫码获取MCP Key，解锁一键打车](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n\n\n## 3. 配置 MCP KEY\n\n**推荐方式：通过 OpenClaw 持久化（所有 isolated session 自动生效）**\n\n```bash\nopenclaw config set 'skills.entries.didi-ride-skill.apiKey' 'YOUR_MCP_KEY'\n```\n\n**备用方式：环境变量（仅当前 shell 会话有效）**\n\n```bash\nexport DIDI_MCP_KEY=\"YOUR_MCP_KEY\"\n```\n\n## 4. 验证连接\n\n> 本 skill 使用 mcporter 的 **URL 直连模式**，不依赖 `config/mcporter.json` 配置文件。如果 mcporter 启动时报 JSON 校验错误（`invalid_type` 或 `Failed to parse JSON`），说明存在格式异常的 `config/mcporter.json`。不要删除它（可能包含其他应用配置），改用 `--config` 绕过——详见 SKILL.md §3.2 第 3 条。\n\n**Step 1 — 查看所有工具签名（同时验证 Key 和连通性）：**\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter list \"$MCP_URL\"\n```\n\n预期输出完整的工具列表（`maps_textsearch`、`taxi_estimate` 等 13 个工具及参数签名）。如果返回鉴权错误，说明 Key 无效。\n\n**Step 2 — 测试地址解析功能：**\n\n```bash\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"西二旗地铁站\",\"city\":\"北京市\"}'\n```\n\n**Step 3 — 测试价格预估功能：**\n\n```bash\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lng\":\"116.322\",\"from_lat\":\"39.893\",\"from_name\":\"北京西站\",\"to_lng\":\"116.482\",\"to_lat\":\"40.004\",\"to_name\":\"首都机场\"}'\n```\n\n## 5. OpenClaw 配置\n\n如果使用 OpenClaw，还需要以下配置：\n\n- 确保已安装 `openclaw` CLI\n- 验证 mcporter 已安装：`which mcporter`\n- 若未找到，执行 `npm install -g mcporter` 后重新验证\n\n## 常见问题\n\n**Q: MCP KEY 无效**\nA: 请检查 MCP KEY 是否正确，以及是否已启用相应权限\n\n**Q: 调用超时**\nA: 检查网络连接，稍后重试\n\n**Q: 地理位置限制**\nA: 部分功能仅支持中国大陆地区\n\nFile v1.1.2:references/workflow.md\n\n# 滴滴打车详细工作流程\n\n## 全局执行约束\n\n1. 参数优先级：`用户 query` > `assets/PREFERENCE.md` > 默认值。\n2. 每次调用前先核对 [api_references.md](./api_references.md) 参数名。\n3. 所有 `--args` 值必须为字符串。\n4. `taxi_create_order` 必须使用最近一次预估返回的 `traceId`。\n5. 起终点缺失时按优先级补全：① 读 assets/PREFERENCE.md，有地址别名且值非空则推断；② 无可用别名时询问用户当前位置，不得用历史记忆补齐。\n6. 用户拒绝提供当前位置时固定回复：不提供当前位置信息则无法满足您的需求。\n7. mcporter 使用 URL 直连模式，**禁止添加 `--server` 标志**，**禁止创建或修改 `config/mcporter.json`**。遇到 `StatusCode=400` 先核对参数名（见 SKILL.md §3.2 第 4 条），遇到 JSON 校验错误用 `--config` 绕过（见 SKILL.md §3.2 第 3 条）。\n\n## Phase 1：地址解析\n\n调用：`maps_textsearch`\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"北京西站\",\"city\":\"北京市\"}'\n```\n调用时需要注意:\n\n- city **必须使用完整格式，如\"北京市\"而非\"北京\"**\n- keywords 和 city 参数值是否为字符串格式（加引号）\n\n解析规则：\n\n- 用户给完整起终点：直接进入预估。\n- \"我要上班/下班了\"：允许按家↔公司偏好直接解析。\n- \"回家/去公司\"但缺起点：先问当前位置。\n\n## Phase 2：价格预估\n\n调用：`taxi_estimate`\n\n```bash\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lat\":\"39.894\",\"from_lng\":\"116.321\",\"from_name\":\"北京西站\",\"to_lat\":\"40.053\",\"to_lng\":\"116.297\",\"to_name\":\"西二旗\"}'\n```\n\n执行要点：\n\n- 记录 `traceId`，后续发单必须使用该值。\n- 若重新预估，覆盖旧 `traceId`，只认最新一份。\n\n## Phase 3：创建订单\n\n调用：`taxi_create_order`\n\n```bash\nmcporter call \"$MCP_URL\" taxi_create_order --args '{\"estimate_trace_id\":\"TRACE_ID\",\"product_category\":\"1\"}'\n```\n\n创建策略：\n\n- 用户已明确车型（当前消息含\"叫快车\"\"叫专车\"等）时允许直发，不必二次确认车型；用户未指定车型且偏好为空时，**必须先展示预估结果让用户选择车型**，禁止默认选择。\n- 用户明确车型时按用户选择发单。\n- 用户未明确车型时，可按偏好车型直发；偏好也未配置时，须向用户询问车型，不要自行推荐。\n- 若缺少 `estimate_trace_id` 或 `product_category`，禁止发单。\n- 若返回 `Streamable HTTP error: Unexpected content type: text/plain`，立即停止流程，按 `error_handling.md` 的「taxi_create_order 调用失败」章节输出固定文案（不要重试、不要切换 Key、不要继续后续步骤）。\n\n成功输出模板：\n\n```text\n✅ 订单已创建！\n\n🚖 订单号: [orderId]\n📍 [起点] → [终点]\n🚗 车型: [车型名称]\n💰 预估: 约 [价格] 元\n📱 手机尾号: [phoneNumberSuffix]\n\n⏳ 正在为您匹配司机...\n💡 发送「查询订单」可了解当前订单状态\n⏱️ 将在 5 分钟后自动为您回查订单状态\n```\n\n## Phase 4：查询订单\n\n触发词：`查询订单` / `查询订单 <orderId>`\n\n调用：`taxi_query_order`\n\n```bash\n# MCP_URL 沿用 Phase 1 已定义的变量\nmcporter call \"$MCP_URL\" taxi_query_order --args '{\"order_id\":\"ORDER_ID\"}'\n```\n\n### 状态码与输出格式\n\n| code | 含义 | 输出建议 |\n|------|------|----------|\n| 0 | 匹配中 | ⏳ 正在为您匹配司机，请稍候 |\n| 1 | 司机已接单 | 展示司机信息（姓名、车型、车牌、电话）及距上车点距离/ETA |\n| 2 | 司机已到达 | 🔔 司机已到达上车点，请前往上车 |\n| 4 | 行程进行中 | 🚗 行程已开始，祝您旅途愉快 |\n| 5 | 订单完成 | ✅ 行程结束，展示费用（如有） |\n| 6 | 订单已被系统取消 | ❌ 订单已被系统取消 |\n| 7 | 订单已被取消 | ❌ 订单已取消 |\n| 3/8-12 | 其他终态 | 显示对应状态描述 |\n\n## Phase 5：取消订单\n\n调用顺序：\n\n1. 向用户确认是否取消（即使用户说了\"取消订单\"，仍需明确询问\"确认取消吗？\"，用户的取消意图 ≠ 取消确认）；\n2. 用户确认后调用 `taxi_cancel_order`；\n3. 调用 `taxi_query_order` 确认取消结果。\n\n## Phase 6：预约出行（cron 托管）\n\n说明：MCP API 是实时发单，预约由 OpenClaw cron 托管叫车需求，到点由 isolated agent 独立执行完整打车流程。\n\n```bash\n# ⚠️ 替换占位符：\n#   FROM_NAME    → 带城市前缀的起点全称（如\"北京市西二旗地铁站\"）\n#   TO_NAME      → 带城市前缀的终点全称（如\"北京市佰嘉城小区\"）\n#   VEHICLE      → 车型（如\"快车\"）\n#   TIME         → 见下方时间规则\n#   CHANNEL_NAME → 当前会话 metadata 中的 channel 字段（如 feishu、telegram），CHANNEL_NAME 不需要带引号，例如: feishu ✅, \"feishu\" ❌。不允许使用 last 作为参数值。\n#   CHAT_ID      → 当前会话 metadata 中的 chat_id 字段\n\nopenclaw cron add \\\n  --name \"didi-ride-skill:$(date +%s)\" \\\n  --at \"TIME\" \\\n  --session isolated \\\n  --message \"执行定时打车：起点「FROM_NAME」，终点「TO_NAME」，车型「VEHICLE」。请完整执行打车流程：地址解析 → 价格预估（获取最新 traceId）→ 创建订单。订单创建成功后，输出订单信息并提示用户可发送「查询订单」了解订单状态，同时创建 5 分钟后自动回查 cron（模板见 SKILL.md 第 3.8 节「发单后自动回查」）。\" \\\n  --announce \\\n  --channel CHANNEL_NAME \\\n  --to \"CHAT_ID\"\n```\n\n### TIME 填写规则\n\n| 场景 | 写法 | 示例 |\n|------|------|------|\n| 相对时间（X 分钟/小时后） | duration 格式 | `15m` / `2h` / `1h30m` |\n| 绝对时间（具体时刻） | 本地时区 ISO 格式 | `$(date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00')` |\n\n- 相对时间（如 `15m`）无需格式化，直接使用\n- 绝对时间使用带时区的 ISO 8601 格式：`YYYY-MM-DDTHH:MM:SS+08:00`（北京时间东八区）\n\n**系统兼容性说明：**\n- Linux (GNU date): `date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n- macOS (BSD date): `TZ=Asia/Shanghai date -j -v+1d -f '%H:%M' '09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n\n## 查询司机位置\n\n调用顺序：\n\n1. `taxi_get_driver_location`\n2. `maps_regeocode`\n\n返回内容建议包含：地址、距离、预计到达时间、司机信息（如可得）。\n\nFile v1.1.2:assets/PREFERENCE.md\n\n# 用户偏好设置\n\n> 此文件存储用户的个性化偏好数据，用于优化打车体验。当用户的 query 中没有明确指定时，系统会根据此文件的偏好自动匹配。注意：当起终点是从偏好推断的（非用户明确指定），必须先向用户确认后再执行。\n\n## 优先级说明\n\n1. **用户 query 参数**（优先级最高）：用户在当前对话中明确指定的地址、车型等\n2. **PREFERENCE.md 偏好数据**（优先级次之）：用户预设的个性化偏好\n\n## 地址别名\n\n| 别名 | 地址名称 | 经度 | 纬度 | 城市 |\n| ---- | -------- | ---- | ---- | ---- |\n| 家   |          |      |      |      |\n| 公司 |          |      |      |      |\n\n> 说明：\n> - \"家\"和\"公司\"为内置别名，支持\"从家到公司\"、\"打车回家\"等经典简化表达。\n> - 此表可自由扩展行数，用户可添加任意别名（如\"妈妈家\"、\"儿子的学校\"、\"健身房\"等）。**读取时请扫描整张表格到下一个 `##` 章节为止，不要只看默认的前两行。**\n> - **精确优先，语义兜底**：优先精确匹配别名（\"家\"只匹配\"家\"，不会匹配\"妈妈家\"）；无精确匹配时用语义理解（\"接孩子\"可匹配\"儿子的学校\"）。\n\n## 场景车型偏好\n\n| 场景   | 偏好车型 | 品类代码 | 说明     |\n| ------ | -------- | -------- | -------- |\n| 上班   |          |          |          |\n| 下班   |          |          |          |\n| 其他   |          |          |          |\n\n> 说明：当用户说\"我要上班\"或\"下班回家\"时，自动使用对应的车型偏好\n>\n> 品类代码来自 `taxi_estimate` 返回的 `product_category` 字段。常见值：快车=1，特惠快车=201，滴滴轻享=193，专车=8，豪华车=17。\n> ⚠️ 注意：可用车型以 API 实际返回为准，新增车型会自动出现在预估结果中。支持多车型时用英文逗号分隔，如 `1,201`\n\n## 默认偏好\n\n| 配置项     | 值   | 说明 |\n| ---------- | ---- | ---- |\n| 默认车型   |      | 无明确需求时使用 |\n| 叫车手机号 |      | 默认叫车号码 |\n\n> ⚠️ **叫车手机号是可选字段**：如果用户未提供且此处为空，AI **不要反复向用户索要**——直接以不带 `caller_car_phone` 参数的方式下单即可，MCP API 允许无手机号下单。口头询问一次若用户未回复即视为\"用默认/不传\"。\n\n## 使用示例\n\n1. **地址别名使用**（语义匹配，精确优先）：\n   - \"我要回家\" → 精确匹配别名\"家\"（用户自己的家），不会匹配\"妈妈家\"\n   - \"从家到公司\" → 精确匹配\"家\"为起点，\"公司\"为终点\n   - \"从家去公司\" → 同上，\"家\"= 用户自己的家\n   - \"去妈妈家\" / \"去我妈那儿\" → 匹配别名\"妈妈家\"（需明确含\"妈妈\"语义）\n   - \"送儿子上学\" / \"接孩子\" → 匹配别名\"儿子的学校\"\n   - \"去健身\" → 匹配别名\"健身房\"\n\n2. **场景偏好使用**：\n   - \"我要上班\" → 自动使用\"上班\"场景的车型偏好\n   - \"下班了\" → 自动使用\"下班\"场景的车型偏好\n\n## 更新日志\n\n- 2026-03-11: 初始化偏好文件\n\nFile v1.1.2:package.json\n\n{\n  \"name\": \"didi-ride-skill\",\n  \"version\": \"1.1.2\",\n  \"description\": \"DiDi Ride Skill for OpenClaw - 打车、路线规划、周边搜索\",\n  \"type\": \"module\",\n  \"author\": \"DiDi MCP Team\",\n  \"homepage\": \"https://mcp.didichuxing.com\",\n  \"keywords\": [\n    \"didi\",\n    \"taxi\",\n    \"mcp\",\n    \"openclaw\",\n    \"mobility\"\n  ]\n}\n\nArchive v1.1.1: 8 files, 18845 bytes\n\nFiles: assets/PREFERENCE.md (2762b), package.json (323b), references/api_references.md (8174b), references/error_handling.md (3863b), references/setup.md (1844b), references/workflow.md (5805b), SKILL.md (16490b), _meta.json (143b)\n\nFile v1.1.1:SKILL.md\n\n---\nname: didi-ride-skill\ndescription: 中国城市出行服务。当用户表达任何交通出行需求时必须使用此技能——包括打车/叫车/网约车、查价格、路线规划（公交/驾车/步行/骑行）、周边搜索、查询订单/司机位置/取消订单。关键词：\"打车\"、\"叫车\"、\"去[地点]\"、\"回家\"、\"上班\"、\"下班\"、\"查价格\"、\"多少钱\"、\"路线\"、\"怎么走\"、\"步行到\"、\"附近\"、\"周边\"、\"司机\"、\"订单\"、\"查询订单\"。注意：即使用户未明确说\"打车\"，只要涉及从A地到B地、通勤、或交通方式选择，都应触发。不触发场景：开发打车应用、使用其他导航app、订外卖、查公交时刻表、股票/财报查询。\nhomepage: https://mcp.didichuxing.com\nmetadata:\n  { \"openclaw\": { \"emoji\": \"🚕\", \"always\": true, \"requires\": { \"bins\": [\"openclaw\", \"mcporter\"], \"env\": [\"DIDI_MCP_KEY\"] }, \"primaryEnv\": \"DIDI_MCP_KEY\", \"install\": [{ \"id\": \"node\", \"kind\": \"node\", \"package\": \"mcporter\", \"bins\": [\"mcporter\"], \"label\": \"Install mcporter (node)\" }] } }\n---\n\n# 滴滴出行服务 (DiDi Ride Skill)\n\n通过 DiDi MCP Server API 提供打车、查询订单、司机位置、预约叫车、路线规划、周边搜索能力。\n\n---\n\n## 1. 快速开始（2 分钟）\n\n### 1.1 获取 MCP KEY\n\n**方式一：用「滴滴出行App」扫码（推荐，最快）**\n\n![滴滴出行APP扫码获取MCP Key，解锁一键打车](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n> ⚠️ **Agent 注意**：用户客户端无法渲染 Markdown 图片，**禁止直接输出上方图片语法**。需向用户发送二维码时，执行 `### 3.9 MCP KEY 与配置` 中的 `openclaw message send` 命令发图。\n\n打开滴滴出行 App，扫描二维码，即可快速获取 MCP Key。\n\n**方式二：访问官网**\n\n访问 https://mcp.didichuxing.com/claw 获取您的 MCP Key。\n\n### 1.2 配置 Key\n\n**方式一：对话中输入（推荐）**\n\n直接在对话中告诉我您的 MCP Key，我会帮您配置：\n\n```\n你: 我的 MCP Key 是 xxxxxx\n```\n\n**方式二：OpenClaw 配置文件**\n\n编辑 `~/.openclaw/openclaw.json`，添加：\n\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"didi-ride-skill\": {\n        \"enabled\": true,\n        \"apiKey\": \"你的MCP_KEY\"  // apiKey 是 OpenClaw 标准字段名，存储的值就是滴滴平台的 MCP KEY\n      }\n    }\n  }\n}\n```\n\n### 1.3 开始使用\n\n配置完成后，直接对话即可：\n\n```\n你: 打车去北京西站\n你: 帮我查一下从国贸到三里屯的路线\n你: 查询订单\n```\n\n首次使用时，OpenClaw 会提示安装 mcporter 工具。\n\n---\n\n## 2. 用户指南\n\n本 Skill 支持以下操作：\n\n- **打车**：直接说\"打车去[地点]\"、\"回家\"、\"上班\"\n- **查价**：查一下从 A 到 B 多少钱\n- **查询订单**：输入「查询订单」了解当前订单状态（司机位置、行程进度等）\n- **司机位置**：司机在哪里、多久到\n- **预约出行**：\"15分钟后打个车\"、\"明天9点去机场\"\n- **路线规划**：驾车/公交/步行/骑行路线\n- **取消订单**：取消当前订单\n\n---\n\n## 3. Agent 执行指令\n\n以下内容为 AI 执行参考，用户可忽略。\n\n### 3.1 文件地图 \n\n按需读取以下文件，不要猜测未读过的内容：\n\n| 文件 | 用途 | 何时读取 |\n|------|------|----------|\n| `SKILL.md` | 触发、主流程、硬性门禁、查询订单规则、预约出行规则 | 每次触发必读 |\n| `references/workflow.md` | 分阶段详细流程与命令范式 | 需要实现细节时读 |\n| `references/api_references.md` | MCP 函数签名与参数定义 | 每次调用工具前**必须**核对 |\n| `references/error_handling.md` | 常见错误与恢复策略 | ⚠️ 遇到调用失败时（比如 400 错误）必须读取此文件 |\n| `references/setup.md` | 安装 mcporter、配置 MCP KEY 的完整步骤 | 用户询问安装/配置问题时读 |\n| `assets/PREFERENCE.md` | 地址别名/车型/手机号偏好 | 用户提到别名地址（家、公司、妈妈家等）、车型、手机号，或未明确给出起终点时**必须**读取。别名匹配规则见执行前检查第 6 条 |\n\n### 3.2 执行前检查\n\n1. **检查 mcporter**：若 `mcporter` 不存在（`command not found`），停止并引导用户阅读 `references/setup.md`。没有 mcporter 就无法调用任何 MCP 工具，后续任何流程都无法执行。\n\n2. **检查 Key**：执行 `openclaw config get skills.entries.didi-ride-skill.apiKey`，若输出为空或非 `__OPENCLAW_REDACTED__`，按 `### 3.9 MCP KEY 与配置` 流程引导。Key 缺失时 mcporter 的报错信息具有误导性，不要尝试绕过。\n   - ⚠️ **若 Key 已配置（返回 `__OPENCLAW_REDACTED__`）但 mcporter 仍报 `Missing KEY parameter`**：**不是 Key 失效**，**禁止向用户索要 Key**。排查步骤见 `references/error_handling.md` 中的「mcporter Missing KEY parameter」章节。\n\n3. **mcporter 调用格式**：\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" <tool> --args '{\"key\":\"value\"}'\n```\n\n4. **参数值必须加引号**（字符串格式），否则 API 会报”缺少必填参数”。\n5. **先预估再下单**：`taxi_create_order` 依赖 `taxi_estimate` 返回的 `traceId`，没有 traceId 下单会失败。traceId 有时效性，过期（`-32021` 错误）需重新预估。\n6. **起终点处理**：\n   - 坐标必须来自 `maps_textsearch`，不要凭空猜测坐标。\n   - **禁止用对话历史记忆补充起终点**——用户可能已经换了地方。\n   - **起终点缺失时**按以下顺序补全：\n     - ① 读 `assets/PREFERENCE.md`，若有地址别名**且地址值非空**，根据场景推断（如早晨→起点\"家\"、下班→起点\"公司\"）。别名行存在但地址为空 = 未配置。\n     - ② 若无可用别名，直接询问用户。\n   - **别名匹配规则（精确优先）**：\"家\"只匹配别名\"家\"，不匹配\"妈妈家\"；需明确含\"妈妈\"语义才匹配\"妈妈家\"。其他自定义别名同理。\n   - **推断的起终点、或 `maps_textsearch` 返回多个候选结果时，必须在主流程 step 2 向用户确认**；用户明确指定且精确匹配的地点无需确认。\n\n### 3.3 用户确认策略\n\n| 场景 | 规则 |\n|------|------|\n| 打车（实时/预约） | 推断的地址或搜索返回多个候选时必须确认起终点（见主流程 step 2），用户明确指定且精确匹配时无需确认，确认后再预估下单 |\n| 取消订单 | 即使用户说了\"取消订单\"，仍必须先明确询问\"确认取消吗？\"，等用户回复确认后才能调用 `taxi_cancel_order`。用户的取消意图 ≠ 取消确认。 |\n\n### 3.4 主流程（最小可执行）\n\n1. 地址解析：`maps_textsearch`（必要时结合 `assets/PREFERENCE.md`，按执行前检查第 6 条处理）。\n2. 确认起终点：推断的地址（如别名推断）或 `maps_textsearch` 返回多个候选结果时，必须向用户确认（如\"从家出发去首都机场T3航站楼，确认吗？\"）；用户明确指定且精确匹配的地点无需确认。用户纠正则按纠正内容重新解析。\n3. 价格预估：`taxi_estimate`，记录 `traceId`。\n4. 车型决策：\n   - 用户明确车型：直接用；\n   - 用户未明确：使用 `assets/PREFERENCE.md` 中的场景车型偏好或默认车型；\n   - 偏好也未配置：向用户询问车型，不要自行推荐。\n   - 可用车型以 `taxi_estimate` API 返回为准，获取对应的 `productCategory` 创建订单。\n5. 创建订单：`taxi_create_order`（使用最新 `traceId`）。\n6. 结果输出：给出订单号、起终点、车型、预估价，末尾提示 `💡 发送「查询订单」可了解当前订单状态`，并告知 `⏱️ 将在 5 分钟后自动为您回查订单状态`。\n7. ⚠️ 自动回查（必做）：根据 `### 3.8 发单后自动回查` 中的 cron 指令内容，创建定时任务，参数信息严格遵循章节内要求。此步不可省略。\n\n### 3.5 偏好设置更新\n\n当用户要求设置/记住/记一下/帮我记/保存地址别名、车型偏好或手机号时，**必须**直接编辑 `assets/PREFERENCE.md` 对应的 markdown 表格行。\n\n- **地址别名**（\"我家在…\"、\"公司在…\"、\"儿子的学校是…\"、\"妈妈家在…\"）：先调用 `maps_textsearch` 解析地址获取坐标，然后更新「地址别名」表——已有别名更新对应行，新别名追加新行。别名由用户定义，不限于\"家\"\"公司\"。\n- **场景车型**（\"上班用快车\"、\"下班用特惠和快车\"）：更新「场景车型偏好」表对应行。品类代码参考表底注释，多车型用英文逗号分隔（如 `1,201`）。\n- **叫车手机号**（\"我的手机号是…\"）：更新「默认偏好」表中的叫车手机号行。\n- **创建订单时**：若 PREFERENCE.md 中配置了叫车手机号，将其作为 `caller_car_phone` 参数传入 `taxi_create_order`。\n\n### 3.6 查询订单\n\n触发词：`查询订单` / `查询订单 <orderId>`\n\n订单号来源（优先级从高到低）：\n1. 用户消息中明确给出；\n2. 当前对话上下文中最近一次创建的订单号；\n3. 以上均无时，向用户询问。\n\n调用命令：\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" taxi_query_order --args '{\"order_id\":\"ORDER_ID\"}'\n```\n\n#### 3.6.1 状态码与输出规则\n\n| code | 含义 | 必须输出 |\n|------|------|----------|\n| 0 | 匹配中 | ⏳ 正在为您匹配司机，请稍候 |\n| 1 | 司机已接单 | **必须展示**：司机姓名、车型、车牌、电话；距上车点距离和预计到达时间 |\n| 2 | 司机已到达 | 🔔 司机已到达上车点，请前往上车 |\n| 4 | 行程进行中 | 🚗 行程已开始 |\n| 5 | 订单完成 | ✅ 行程结束，展示费用（如有） |\n| 6 | 订单已被系统取消 | ❌ 订单已被系统取消 |\n| 7 | 订单已被取消 | ❌ 订单已取消 |\n| 3/8-12 | 其他终态 | 显示对应状态描述 |\n\n### 3.7 预约出行规则\n\n当用户要求在特定时间叫车（如\"15分钟后\"、\"明天9点\"）：\n\n- 使用 cron 一次性任务（`--at`），到点由 isolated agent 独立执行完整打车流程；\n- ⚠️ `--message` 必须包含完整起终点（带城市前缀）和车型，isolated session 无历史上下文。起点或终点缺失时先从 `assets/PREFERENCE.md` 推断并向用户确认，推断不了则必须先询问用户，**不要自行推断未知信息**；\n- 到点后 agent 自行执行：地址解析 → 价格预估（获取最新 traceId）→ 创建订单；\n- 如果无法获取当前会话的 metadata，不要创建 cron，改为在回复中提醒用户主动查询；\n- 如果定时任务创建失败，必须在回复中提示用户，不能默默失败。\n\n```bash\n# ⚠️ 替换占位符：\n#   FROM_NAME    → 带城市前缀的起点全称（如\"北京市西二旗地铁站\"）\n#   TO_NAME      → 带城市前缀的终点全称（如\"北京市佰嘉城小区\"）\n#   VEHICLE      → 车型（如\"快车\"）\n#   TIME         → 见下方时间规则\n#   CHANNEL_NAME → 当前会话 metadata 中的 channel 字段（如 feishu、telegram），CHANNEL_NAME 不需要带引号，例如: feishu ✅, \"feishu\" ❌。不允许使用 last 作为参数值。\n#   CHAT_ID      → 当前会话 metadata 中的 chat_id 字段\n\n\nopenclaw cron add \\\n  --name \"didi-ride-skill:$(date +%s)\" \\\n  --at \"TIME\" \\\n  --session isolated \\\n  --message \"执行定时打车：起点「FROM_NAME」，终点「TO_NAME」，车型「VEHICLE」。请完整执行打车流程：地址解析 → 价格预估（获取最新 traceId）→ 创建订单。订单创建成功后，输出订单信息并提示用户可发送「查询订单」了解订单状态，同时创建 5 分钟后自动回查 cron（模板见 SKILL.md 第 3.8 节「发单后自动回查」）。\" \\\n  --announce \\\n  --channel CHANNEL_NAME \\\n  --to \"CHAT_ID\"\n```\n\n#### 3.7.1 TIME 填写规则\n\n| 场景 | 写法 | 示例 |\n|------|------|------|\n| 相对时间（X 分钟/小时后） | duration 格式 | `15m` / `2h` / `1h30m` |\n| 绝对时间（具体时刻） | 本地时区 ISO 格式 | `$(date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00')` |\n\n- 相对时间（如 `15m`）无需格式化，直接使用\n- 绝对时间使用带时区的 ISO 8601 格式：`YYYY-MM-DDTHH:MM:SS+08:00`（北京时间东八区）\n\n**系统兼容性说明：**\n- Linux (GNU date): `date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n- macOS (BSD date): `TZ=Asia/Shanghai date -j -v+1d -f '%H:%M' '09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n\n### 3.8 发单后自动回查\n\n发单成功后（实时单或预约单），根据本章节下文 \"openclaw cron add\" 命令，创建 cron 任务，务必按照本章节下文bash命令参数设置。\n- 如果无法获取当前会话的 metadata，不要创建 cron，改为在回复中提醒用户主动查询订单状态。\n- 如果定时任务创建失败，必须在回复中提示用户，不能默默失败。\n\n```bash\n# ⚠️ 替换占位符：\n#   ORDER_ID     → 实际订单号（taxi_create_order 返回）\n#   CHANNEL_NAME → 当前会话 metadata 中的 channel 字段（如 feishu、telegram），CHANNEL_NAME 不需要带引号，例如: feishu ✅, \"feishu\" ❌。不允许使用 last 作为参数值。\n#   CHAT_ID      → 当前会话 metadata 中的 chat_id 字段\n\nopenclaw cron add \\\n  --name \"didi-ride-skill:check:ORDER_ID\" \\\n  --at \"5m\" \\\n  --session isolated \\\n  --message \"查询滴滴订单状态：订单号 ORDER_ID。调用 taxi_query_order 查询并输出当前状态。如果司机已接单，输出司机姓名、车型、车牌、电话及预计到达时间；如果仍在匹配中，提示用户耐心等待。\" \\\n  --announce \\\n  --channel CHANNEL_NAME \\\n  --to \"CHAT_ID\"\n```\n\n### 3.9 MCP KEY 与配置\n\n> **术语说明**：滴滴平台称此凭证为「MCP KEY」，OpenClaw 配置字段统一叫 `apiKey`，注入后的环境变量为 `DIDI_MCP_KEY`——三者是同一个值。\n\n⚠️ Key 来源：通过 `openclaw config set` 持久化后，OpenClaw 在每次 agent run 启动时自动注入为环境变量 `DIDI_MCP_KEY`。\n```bash\n# ⚠️ 可以通过以下命令判断当前 DIDI_MCP_KEY 是否配置。如果输出 __OPENCLAW_REDACTED__ ，即为已配置，可在后面使用环境变量`DIDI_MCP_KEY`。\nopenclaw config get skills.entries.didi-ride-skill.apiKey\n```\n\n#### 3.9.1 用户在对话中提供 Key 时（必须持久化）\n\n当用户回复了 Key（如\"我的 Key 是 xxxxxx\"），**必须**执行以下命令持久化，**严禁只 export 到当前 shell**：\n\n```bash\n# ⚠️ 将 YOUR_KEY 替换为用户提供的实际值\nopenclaw config set 'skills.entries.didi-ride-skill.apiKey' 'YOUR_KEY'\n```\n\n持久化成功后：\n- OpenClaw 在所有后续 agent run（含 cron isolated session）中自动注入 `DIDI_MCP_KEY`\n- ⚠️ 命令执行成功后输出 `\"Restart the gateway to apply.\"` ——**这是通用提示，必须忽略，禁止执行任何 restart / 重启操作**。`apiKey` 在每次 agent run 启动时动态读取，无需重启即可生效；强制重启会导致网关崩溃。\n\n⚠️ Key 未配置**或** MCP 返回鉴权失败（`error.code: -32002`）时，执行以下两步：\n\n1. 执行下面的 \"openclaw message send\" 命令，发送二维码图片（`{CHAT_ID}` → metadata 的 chat_id，`{CHANNEL_NAME}` → metadata 的 channel）：\n\n```bash\nopenclaw message send --channel {CHANNEL_NAME} --target {CHAT_ID} --media \"https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png\" --message \"滴滴出行APP扫码获取MCP Key，解锁一键打车\"\n```\n\n2. 输出文字：\n\n> 您还没有配置 DIDI_MCP_KEY 或 Key 已失效，请访问 [滴滴MCP平台](https://mcp.didichuxing.com/claw) 获取 MCP KEY，然后配置环境变量或在 OpenClaw 配置文件中设置。\n\n### 3.10 工具清单\n\n| 领域 | 工具 |\n|------|------|\n| 打车 | `maps_textsearch`, `taxi_estimate`, `taxi_create_order`, `taxi_query_order`, `taxi_get_driver_location`, `taxi_cancel_order`, `maps_regeocode`, `taxi_generate_ride_app_link`（用户无 API 直发权限时的备选：生成深度链接让用户在 App 内完成发单） |\n| 路线 | `maps_direction_driving`, `maps_direction_transit`, `maps_direction_walking`, `maps_direction_bicycling` |\n| 周边 | `maps_place_around` |\n\nFile v1.1.1:_meta.json\n\n{\n  \"ownerId\": \"kn7can12c6x8pp8ade0sxqkv6582sfzp\",\n  \"slug\": \"didi-ride-skill-official\",\n  \"version\": \"1.1.1\",\n  \"publishedAt\": 1775201142501\n}\n\nFile v1.1.1:references/api_references.md\n\n# API 文档\n\n## 响应格式说明\n\n所有工具均返回 `content[].text`（自然语言文本）。部分工具（网约车类）额外返回 `structuredContent`（结构化数据）。\n\n- 如果响应中存在 `structuredContent`，优先使用其中的字段做逻辑判断和字段提取\n- 如果没有 `structuredContent`，则解析 `content[].text` 获取所需信息\n\n## 函数签名\n\n```\n/**\n   * 根据用户输入的起点终点坐标，规划骑行通勤方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_bicycling(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户起终点经纬度坐标规划以小客车、轿车通勤出行的方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_driving(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户起终点坐标，规划综合公交、地铁的通勤方案\n   *\n   * @param city 查询城市（**必须使用完整格式，如\"北京市\"而非\"北京\"**）\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_transit(city: string, destination: string, origin: string);\n\n  /**\n   * 根据用户输入的起点终点坐标，规划步行通勤方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_walking(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户传入关键词和位置坐标，搜索出周边的POI地点信息\n   *\n   * @param keywords 搜索关键词\n   * @param location 位置坐标，格式为：经度,纬度\n   * @param max_distance? 搜索半径，单位：米\n   */\n  function maps_place_around(keywords: string, location: string, max_distance?: string);\n\n  /**\n   * 将经纬度坐标转换为地址信息\n   *\n   * @param location 位置坐标，格式为：经度,纬度\n   */\n  function maps_regeocode(location: string);\n\n  /**\n   * 根据用户传入关键词和城市，搜索出相关的POI地点信息\n   *\n   * @param city 查询城市（**必须使用完整格式，如\"北京市\"而非\"北京\"**）\n   * @param keywords 搜索关键词\n   * @param location? 位置坐标，格式为：经度,纬度\n   */\n  function maps_textsearch(city: string, keywords: string, location?: string);\n\n  /**\n   * 取消打车订单\n   *\n   * @param order_id 订单ID，从订单创建或查询结果中获取\n   * @param reason? 取消原因，可选参数。例如：不需要了、等待时间太长、临时有事等\n   */\n  function taxi_cancel_order(order_id: string, reason?: string);\n\n  /**\n   * 直接通过API创建打车订单，无需打开任何应用程序界面，系统自动完成整个发单流程\n   *\n   * @param caller_car_phone? 叫车人手机号，如果有就要传递，没有就不传\n   * @param estimate_trace_id 预估流程ID，从预估结果中获取\n   * @param product_category 车型品类标识，从预估结果中获取，传入多个车型时，用英文逗号分割，不要带空格\n   * @returns structuredContent.orderId   订单ID，后续查询/取消订单使用\n   * @returns structuredContent.status    订单初始状态（created）\n   */\n  function taxi_create_order(caller_car_phone?: string, estimate_trace_id: string, product_category: string);\n\n  /**\n   * 查看当前可用的网约车车型，请先获取对应地点的经纬度信息，如果有maps_textsearch的tool，优先使用maps_textsearch进行经纬度的获取。\n   *\n   * @param from_lat 出发纬度，必须从地图相关的工具获取，不能假设\n   * @param from_lng 出发经度，必须从地图相关的工具获取，不能假设\n   * @param from_name 出发地名称\n   * @param to_lat 目的纬度，必须从地图相关的工具获取，不能假设\n   * @param to_lng 目的经度，必须从地图相关的工具获取，不能假设\n   * @param to_name 目的地名称\n   * @returns structuredContent.traceId          预估流程ID，创建订单时必须传入\n   * @returns structuredContent.items[]          可用车型列表\n   * @returns structuredContent.items[].productName     车型名称\n   * @returns structuredContent.items[].productCategory 车型品类代码，创建订单时传入\n   * @returns structuredContent.items[].priceText       预估价格（元）\n   */\n  function taxi_estimate(from_lat: string, from_lng: string, from_name: string, to_lat: string, to_lng: string, to_name: string);\n\n  /**\n   * 根据起点、终点和车型生成打开移动应用或小程序的深度链接，用户点击后将跳转到相应的打车应用完成发单操作\n   *\n   * @param from_lat 出发纬度，必须从地图相关的工具获取，不能假设\n   * @param from_lng 出发经度，必须从地图相关的工具获取，不能假设\n   * @param product_category? 车型品类标识列表，从预估结果中获取，支持多个车型，仅当用户明确指定某个或某些品类时才传递此参数，格式为英文逗号,分割\n   * @param to_lat 目的地纬度，必须从地图相关的工具获取，不能假设\n   * @param to_lng 目的经度，必须从地图相关的工具获取，不能假设\n   */\n  function taxi_generate_ride_app_link(from_lat: string, from_lng: string, product_category?: string, to_lat: string, to_lng: string);\n\n  /**\n   * 获取打车订单对应司机的实时位置经纬度\n   *\n   * @param order_id 打车订单ID\n   */\n  function taxi_get_driver_location(order_id: string);\n\n  /**\n   * 查询打车订单的状态和信息，如司机联系方式、车牌号、预估到达时间\n   *\n   * ⚠️ 重要：此函数单次调用仅返回当前状态。\n   * 单次调用返回当前状态，详见 SKILL.md `### 3.6 查询订单`。\n   *\n   * @param order_id? 订单ID，从创建订单结果中获取，如果有就要传递，如果没有，会查询当前账号下未完成的订单\n   * @returns structuredContent.statusCode  订单状态码（见下表）\n   * @returns structuredContent.statusText  状态文本描述\n   * @returns structuredContent.driver      司机信息（name/phone/carModel/carPlate），接单后可用\n   * @returns structuredContent.map.distanceKm  距离（公里），行程中可用\n   * @returns structuredContent.map.eta         预计剩余时间（分钟），行程中可用\n   * @returns structuredContent.map.phase       当前阶段：to_pickup（前往上车点）| to_dropoff（前往终点）\n   *\n   * 订单状态码：\n   *   0  匹配中（非终态）\n   *   1  司机已接单（非终态）\n   *   2  司机已到达（非终态，里程碑通知）\n   *   3  未知状态（终态）\n   *   4  行程开始（非终态，里程碑通知）\n   *   5  订单完成（终态）✅\n   *   6  订单已被系统取消（终态）✅\n   *   7  订单已被取消（终态）✅\n   *   8  未知状态（终态）✅\n   *   9  未知状态（终态）✅\n   *   10 未知状态（终态）✅\n   *   11 客服关闭订单（终态）✅\n   *   12 未能完成服务（终态）✅\n   */\n  function taxi_query_order(order_id?: string);\n```\n\nExamples:\n\n```bash\n# 设置 MCP_URL 变量\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\n\n# 地址解析（city 建议使用完整行政区名称）\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"望京SOHO\",\"city\":\"北京市\"}'\n\n# 价格预估（注意：所有参数值必须加引号，使用字符串格式）\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lat\":\"39.9\",\"from_lng\":\"116.4\",\"from_name\":\"望京SOHO\",\"to_lat\":\"39.9\",\"to_lng\":\"116.4\",\"to_name\":\"国贸\"}'\n```\n\nFile v1.1.1:references/error_handling.md\n\n# 错误处理指南\n\n本文档说明 didi-ride-skill skill 使用过程中可能遇到的错误及解决方案。\n\n> `<skill-dir>` 代表 didi-ride-skill 技能的安装根目录（即 SKILL.md 所在目录），可通过 `openclaw skills info didi-ride-skill` 获取。\n\n## 目录\n\n- [错误处理指南](#错误处理指南)\n  - [目录](#目录)\n  - [mcporter Missing KEY parameter](#mcporter-missing-key-parameter)\n  - [统一错误码表](#统一错误码表)\n  - [API 返回 400 错误](#400-错误排查)\n  - [常见问题 (FAQ)](#常见问题-faq)\n  - [获取帮助](#获取帮助)\n\n***\n\n## mcporter Missing KEY parameter\n\nmcporter 报 `Missing KEY parameter` 时，**不代表 MCP Key 已失效**，禁止直接向用户索要 Key。\n\n可能原因（按概率排序逐一排查）：\n\n1. **`$DIDI_MCP_KEY` 环境变量未展开**：`MCP_URL` 赋值时用了单引号（`'$DIDI_MCP_KEY'`）而非双引号，导致变量字面量传入。确认调用命令中 `MCP_URL` 使用双引号包裹，然后重试。\n2. **当前 shell 未注入环境变量**：openclaw 在每次 agent run 启动时自动注入 `DIDI_MCP_KEY`，但手动在终端直接运行 mcporter 时该变量不存在。执行 `echo $DIDI_MCP_KEY` 验证——若为空，在终端手动 `export DIDI_MCP_KEY=<key>` 后重试，或改在 openclaw agent 环境中调用。\n3. **mcporter.json 配置异常**：若 `~/.openclaw/workspace/config/mcporter.json` 存在但内容异常，mcporter 可能无法正确构造请求。检查该文件内容是否完整。\n4. **Key 本身确实无效**：若以上均排除，执行 `openclaw config get skills.entries.didi-ride-skill.apiKey` 确认 Key 已配置，若返回空则按 `### 3.9 MCP KEY 与配置` 流程重新配置。\n\n***\n\n## 统一错误码表\n\n所有 MCP 工具返回的统一错误码对照：\n\n| 错误码 | 说明 | 解决方案 |\n|--------|------|----------|\n| `-32001` | 命中限流 | 请等待一段时间后重试（配额限制按时间窗口重置） |\n| `-32002` | 鉴权失败（`auth failed`） | Key 存在但无效或已过期，执行 `### 3.9 MCP KEY 与配置` 的引导流程（含发送二维码） |\n| `-32010` | 参数验证失败 | 检查参数格式，确保所有值为字符串 |\n| `-32011` | 订单不存在 | 确认订单ID正确 |\n| `-32021` | 预估结果过期 | 重新调用价格预估获取新的 traceId |\n| `-32030` | 不支持订单类型 | 该类型订单不支持此操作 |\n| `-32031` | 订单未支付 | 订单未进入支付状态 |\n| `-32040` | 订单已经取消过了 | 订单已被取消，无需重复操作 |\n| `-32041` | 订单无法被取消 | 司机已接单或订单已完成，无法通过 API 取消 |\n| `-32050` | 内部错误 | 稍后重试，如持续失败请联系客服 |\n| `-32060` | 支付失败 | 检查支付账户状态或更换支付方式 |\n\n***\n\n## 400 错误排查\n\n> 💡 **故障排查**：如果配置后 API 返回 400 错误，请检查：\n> 1. 参数名是否正确（如 `keywords` 而非 `keyword`）\n> 2. 城市名称是否使用完整格式（如 `\"北京市\"` 而非 `\"北京\"`）\n> 3. 所有参数值是否为字符串格式（加引号）\n\n***\n\n## 常见问题 (FAQ)\n\n**Q: 为什么说\"我要上班\"没反应？**\nA: 需要先配置 `assets/PREFERENCE.md` 中的家和公司地址，以及上班场景的车型偏好。\n\n**Q: 预估价格和实际价格不一致？**\nA: 预估价格为参考值，实际费用以行程完成后为准。\n\n**Q: 如何查看历史订单？**\nA: 当前 API 仅支持查询 MCP 渠道未完成订单，历史订单请在滴滴 App 中查看。\n\n**Q: 支持哪些城市？**\nA: 支持滴滴服务覆盖的所有中国大陆城市。\n\n***\n\n## 获取帮助\n\n如果以上方案无法解决问题，请：\n\n1. 检查 [workflow.md](./workflow.md) 确认操作流程\n2. 访问 <https://mcp.didichuxing.com> 获取最新文档\n\nFile v1.1.1:references/setup.md\n\n# DiDi MCP Server 安装配置指南\n\n本文档说明如何安装和配置 DiDi MCP Server，以便使用 didi-ride-skill skill。\n\n## 1. 安装 mcporter\n\nmcporter 是用于调用 MCP Server 的命令行工具。\n\n```bash\nnpm install -g mcporter\n```\n\n验证安装：\n```bash\nmcporter --version\n```\n\n## 2. 获取 MCP KEY\n\n访问 https://mcp.didichuxing.com/claw 获取您的 MCP KEY，或扫描下方二维码直达官网注册页面。\n\n![滴滴出行APP扫码获取MCP Key，解锁一键打车](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n\n\n## 3. 配置 MCP KEY\n\n**推荐方式：通过 OpenClaw 持久化（所有 isolated session 自动生效）**\n\n```bash\nopenclaw config set 'skills.entries.didi-ride-skill.apiKey' 'YOUR_MCP_KEY'\n```\n\n**备用方式：环境变量（仅当前 shell 会话有效）**\n\n```bash\nexport DIDI_MCP_KEY=\"YOUR_MCP_KEY\"\n```\n\n## 4. 验证连接\n\n设置 MCP_URL 变量：\n```bash\nexport MCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\n```\n\n测试地址解析功能：\n```bash\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"西二旗地铁站\",\"city\":\"北京市\"}'\n```\n\n测试价格预估功能：\n```bash\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lng\":\"116.322\",\"from_lat\":\"39.893\",\"from_name\":\"北京西站\",\"to_lng\":\"116.482\",\"to_lat\":\"40.004\",\"to_name\":\"首都机场\"}'\n```\n\n## 5. OpenClaw 配置\n\n如果使用 OpenClaw，还需要以下配置：\n\n- 确保已安装 `openclaw` CLI\n- 验证 mcporter 已安装：`which mcporter`\n- 若未找到，执行 `npm install -g mcporter` 后重新验证\n\n## 常见问题\n\n**Q: MCP KEY 无效**\nA: 请检查 MCP KEY 是否正确，以及是否已启用相应权限\n\n**Q: 调用超时**\nA: 检查网络连接，稍后重试\n\n**Q: 地理位置限制**\nA: 部分功能仅支持中国大陆地区\n\nFile v1.1.1:references/workflow.md\n\n# 滴滴打车详细工作流程\n\n## 全局执行约束\n\n1. 参数优先级：`用户 query` > `assets/PREFERENCE.md` > 默认值。\n2. 每次调用前先核对 [api_references.md](./api_references.md) 参数名。\n3. 所有 `--args` 值必须为字符串。\n4. `taxi_create_order` 必须使用最近一次预估返回的 `traceId`。\n5. 起终点缺失时按优先级补全：① 读 assets/PREFERENCE.md，有地址别名且值非空则推断；② 无可用别名时询问用户当前位置，不得用历史记忆补齐。\n6. 用户拒绝提供当前位置时固定回复：不提供当前位置信息则无法满足您的需求。\n\n## Phase 1：地址解析\n\n调用：`maps_textsearch`\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"北京西站\",\"city\":\"北京市\"}'\n```\n调用时需要注意:\n\n- city **必须使用完整格式，如\"北京市\"而非\"北京\"**\n- keywords 和 city 参数值是否为字符串格式（加引号）\n\n解析规则：\n\n- 用户给完整起终点：直接进入预估。\n- “我要上班/下班了”：允许按家↔公司偏好直接解析。\n- “回家/去公司”但缺起点：先问当前位置。\n\n## Phase 2：价格预估\n\n调用：`taxi_estimate`\n\n```bash\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lat\":\"39.894\",\"from_lng\":\"116.321\",\"from_name\":\"北京西站\",\"to_lat\":\"40.053\",\"to_lng\":\"116.297\",\"to_name\":\"西二旗\"}'\n```\n\n执行要点：\n\n- 记录 `traceId`，后续发单必须使用该值。\n- 若重新预估，覆盖旧 `traceId`，只认最新一份。\n\n## Phase 3：创建订单\n\n调用：`taxi_create_order`\n\n```bash\nmcporter call \"$MCP_URL\" taxi_create_order --args '{\"estimate_trace_id\":\"TRACE_ID\",\"product_category\":\"1\"}'\n```\n\n创建策略：\n\n- 实时单允许直发，不必二次确认。\n- 用户明确车型时按用户选择发单。\n- 用户未明确车型时，可按偏好车型直发；偏好也未配置时，须向用户询问车型，不要自行推荐。\n- 若缺少 `estimate_trace_id` 或 `product_category`，禁止发单。\n\n成功输出模板：\n\n```text\n✅ 订单已创建！\n\n🚖 订单号: [orderId]\n📍 [起点] → [终点]\n🚗 车型: [车型名称]\n💰 预估: 约 [价格] 元\n📱 手机尾号: [phoneNumberSuffix]\n\n⏳ 正在为您匹配司机...\n💡 发送「查询订单」可了解当前订单状态\n```\n\n## Phase 4：查询订单\n\n触发词：`查询订单` / `查询订单 <orderId>`\n\n调用：`taxi_query_order`\n\n```bash\n# MCP_URL 沿用 Phase 1 已定义的变量\nmcporter call “$MCP_URL” taxi_query_order --args '{“order_id”:”ORDER_ID”}'\n```\n\n### 状态码与输出格式\n\n| code | 含义 | 输出建议 |\n|------|------|----------|\n| 0 | 匹配中 | ⏳ 正在为您匹配司机，请稍候 |\n| 1 | 司机已接单 | 展示司机信息（姓名、车型、车牌、电话）及距上车点距离/ETA |\n| 2 | 司机已到达 | 🔔 司机已到达上车点，请前往上车 |\n| 4 | 行程进行中 | 🚗 行程已开始，祝您旅途愉快 |\n| 5 | 订单完成 | ✅ 行程结束，展示费用（如有） |\n| 6 | 订单已被系统取消 | ❌ 订单已被系统取消 |\n| 7 | 订单已被取消 | ❌ 订单已取消 |\n| 3/8-12 | 其他终态 | 显示对应状态描述 |\n\n## Phase 5：取消订单\n\n调用顺序：\n\n1. 向用户确认是否取消（即使用户说了\"取消订单\"，仍需明确询问\"确认取消吗？\"，用户的取消意图 ≠ 取消确认）；\n2. 用户确认后调用 `taxi_cancel_order`；\n3. 调用 `taxi_query_order` 确认取消结果。\n\n## Phase 6：预约出行（cron 托管）\n\n说明：MCP API 是实时发单，预约由 OpenClaw cron 托管叫车需求，到点由 isolated agent 独立执行完整打车流程。\n\n```bash\n# ⚠️ 替换占位符：\n#   FROM_NAME    → 带城市前缀的起点全称（如”北京市西二旗地铁站”）\n#   TO_NAME      → 带城市前缀的终点全称（如”北京市佰嘉城小区”）\n#   VEHICLE      → 车型（如”快车”）\n#   TIME         → 见下方时间规则\n#   CHANNEL_NAME → 当前会话 metadata 中的 channel 字段（如 feishu、telegram），CHANNEL_NAME 不需要带引号，例如: feishu ✅, “feishu” ❌。不允许使用 last 作为参数值。\n#   CHAT_ID      → 当前会话 metadata 中的 chat_id 字段\n\nopenclaw cron add \\\n  --name “didi-ride-skill:$(date +%s)” \\\n  --at “TIME” \\\n  --session isolated \\\n  --message “执行定时打车：起点「FROM_NAME」，终点「TO_NAME」，车型「VEHICLE」。请完整执行打车流程：地址解析 → 价格预估（获取最新 traceId）→ 创建订单。订单创建成功后，输出订单信息并提示用户可发送「查询订单」了解订单状态，同时创建 5 分钟后自动回查 cron（模板见 SKILL.md 第 3.8 节「发单后自动回查」）。” \\\n  --announce \\\n  --channel CHANNEL_NAME \\\n  --to “CHAT_ID”\n```\n\n### TIME 填写规则\n\n| 场景 | 写法 | 示例 |\n|------|------|------|\n| 相对时间（X 分钟/小时后） | duration 格式 | `15m` / `2h` / `1h30m` |\n| 绝对时间（具体时刻） | 本地时区 ISO 格式 | `$(date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00')` |\n\n- 相对时间（如 `15m`）无需格式化，直接使用\n- 绝对时间使用带时区的 ISO 8601 格式：`YYYY-MM-DDTHH:MM:SS+08:00`（北京时间东八区）\n\n**系统兼容性说明：**\n- Linux (GNU date): `date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n- macOS (BSD date): `TZ=Asia/Shanghai date -j -v+1d -f '%H:%M' '09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n\n## 查询司机位置\n\n调用顺序：\n\n1. `taxi_get_driver_location`\n2. `maps_regeocode`\n\n返回内容建议包含：地址、距离、预计到达时间、司机信息（如可得）。\n\nFile v1.1.1:assets/PREFERENCE.md\n\n# 用户偏好设置\n\n> 此文件存储用户的个性化偏好数据，用于优化打车体验。当用户的 query 中没有明确指定时，系统会根据此文件的偏好自动匹配。注意：当起终点是从偏好推断的（非用户明确指定），必须先向用户确认后再执行。\n\n## 优先级说明\n\n1. **用户 query 参数**（优先级最高）：用户在当前对话中明确指定的地址、车型等\n2. **PREFERENCE.md 偏好数据**（优先级次之）：用户预设的个性化偏好\n\n## 地址别名\n\n| 别名 | 地址名称 | 经度 | 纬度 | 城市 |\n| ---- | -------- | ---- | ---- | ---- |\n| 家   |          |      |      |      |\n| 公司 |          |      |      |      |\n\n> 说明：\n> - \"家\"和\"公司\"为内置别名，支持\"从家到公司\"、\"打车回家\"等经典简化表达。\n> - 此表可自由扩展行数，用户可添加任意别名（如\"妈妈家\"、\"儿子的学校\"、\"健身房\"等）。\n> - **精确优先，语义兜底**：优先精确匹配别名（\"家\"只匹配\"家\"，不会匹配\"妈妈家\"）；无精确匹配时用语义理解（\"接孩子\"可匹配\"儿子的学校\"）。\n\n## 场景车型偏好\n\n| 场景   | 偏好车型 | 品类代码 | 说明     |\n| ------ | -------- | -------- | -------- |\n| 上班   |          |          |          |\n| 下班   |          |          |          |\n| 其他   |          |          |          |\n\n> 说明：当用户说\"我要上班\"或\"下班回家\"时，自动使用对应的车型偏好\n>\n> 品类代码来自 `taxi_estimate` 返回的 `product_category` 字段。常见值：快车=1，特惠快车=201，滴滴轻享=193，专车=8，豪华车=17。\n> ⚠️ 注意：可用车型以 API 实际返回为准，新增车型会自动出现在预估结果中。支持多车型时用英文逗号分隔，如 `1,201`\n\n## 默认偏好\n\n| 配置项     | 值   | 说明 |\n| ---------- | ---- | ---- |\n| 默认车型   |      | 无明确需求时使用 |\n| 叫车手机号 |      | 默认叫车号码 |\n\n## 使用示例\n\n1. **地址别名使用**（语义匹配，精确优先）：\n   - \"我要回家\" → 精确匹配别名\"家\"（用户自己的家），不会匹配\"妈妈家\"\n   - \"从家到公司\" → 精确匹配\"家\"为起点，\"公司\"为终点\n   - \"从家去公司\" → 同上，\"家\"= 用户自己的家\n   - \"去妈妈家\" / \"去我妈那儿\" → 匹配别名\"妈妈家\"（需明确含\"妈妈\"语义）\n   - \"送儿子上学\" / \"接孩子\" → 匹配别名\"儿子的学校\"\n   - \"去健身\" → 匹配别名\"健身房\"\n\n2. **场景偏好使用**：\n   - \"我要上班\" → 自动使用\"上班\"场景的车型偏好\n   - \"下班了\" → 自动使用\"下班\"场景的车型偏好\n\n## 更新日志\n\n- 2026-03-11: 初始化偏好文件\n\nFile v1.1.1:package.json\n\n{\n  \"name\": \"didi-ride-skill\",\n  \"version\": \"1.1.1\",\n  \"description\": \"DiDi Ride Skill for OpenClaw - 打车、路线规划、周边搜索\",\n  \"type\": \"module\",\n  \"author\": \"DiDi MCP Team\",\n  \"homepage\": \"https://mcp.didichuxing.com\",\n  \"keywords\": [\n    \"didi\",\n    \"taxi\",\n    \"mcp\",\n    \"openclaw\",\n    \"mobility\"\n  ]\n}\n\nArchive v1.1.0: 8 files, 18041 bytes\n\nFiles: assets/PREFERENCE.md (2762b), package.json (323b), references/api_references.md (8174b), references/error_handling.md (2637b), references/setup.md (1844b), references/workflow.md (5805b), SKILL.md (15951b), _meta.json (143b)\n\nFile v1.1.0:SKILL.md\n\n---\nname: didi-ride-skill\ndescription: 中国城市出行服务。当用户表达任何交通出行需求时必须使用此技能——包括打车/叫车/网约车、查价格、路线规划（公交/驾车/步行/骑行）、周边搜索、查询订单/司机位置/取消订单。关键词：\"打车\"、\"叫车\"、\"去[地点]\"、\"回家\"、\"上班\"、\"下班\"、\"查价格\"、\"多少钱\"、\"路线\"、\"怎么走\"、\"步行到\"、\"附近\"、\"周边\"、\"司机\"、\"订单\"、\"查询订单\"。注意：即使用户未明确说\"打车\"，只要涉及从A地到B地、通勤、或交通方式选择，都应触发。不触发场景：开发打车应用、使用其他导航app、订外卖、查公交时刻表、股票/财报查询。\nhomepage: https://mcp.didichuxing.com\nmetadata:\n  { \"openclaw\": { \"emoji\": \"🚕\", \"always\": true, \"requires\": { \"bins\": [\"openclaw\", \"mcporter\"], \"env\": [\"DIDI_MCP_KEY\"] }, \"primaryEnv\": \"DIDI_MCP_KEY\", \"install\": [{ \"id\": \"node\", \"kind\": \"node\", \"package\": \"mcporter\", \"bins\": [\"mcporter\"], \"label\": \"Install mcporter (node)\" }] } }\n---\n\n# 滴滴出行服务 (DiDi Ride Skill)\n\n通过 DiDi MCP Server API 提供打车、查询订单、司机位置、预约叫车、路线规划、周边搜索能力。\n\n---\n\n## 1. 快速开始（2 分钟）\n\n### 1.1 获取 MCP KEY\n\n**方式一：用「滴滴出行App」扫码（推荐，最快）**\n\n![滴滴出行APP扫码获取MCP Key，解锁一键打车](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n> ⚠️ **Agent 注意**：用户客户端无法渲染 Markdown 图片，**禁止直接输出上方图片语法**。需向用户发送二维码时，执行 `### 3.9 MCP KEY 与配置` 中的 `openclaw message send` 命令发图。\n\n打开滴滴出行 App，扫描二维码，即可快速获取 MCP Key。\n\n**方式二：访问官网**\n\n访问 https://mcp.didichuxing.com/claw 获取您的 MCP Key。\n\n### 1.2 配置 Key\n\n**方式一：对话中输入（推荐）**\n\n直接在对话中告诉我您的 MCP Key，我会帮您配置：\n\n```\n你: 我的 MCP Key 是 xxxxxx\n```\n\n**方式二：OpenClaw 配置文件**\n\n编辑 `~/.openclaw/openclaw.json`，添加：\n\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"didi-ride-skill\": {\n        \"enabled\": true,\n        \"apiKey\": \"你的MCP_KEY\"  // apiKey 是 OpenClaw 标准字段名，存储的值就是滴滴平台的 MCP KEY\n      }\n    }\n  }\n}\n```\n\n### 1.3 开始使用\n\n配置完成后，直接对话即可：\n\n```\n你: 打车去北京西站\n你: 帮我查一下从国贸到三里屯的路线\n你: 查询订单\n```\n\n首次使用时，OpenClaw 会提示安装 mcporter 工具。\n\n---\n\n## 2. 用户指南\n\n本 Skill 支持以下操作：\n\n- **打车**：直接说\"打车去[地点]\"、\"回家\"、\"上班\"\n- **查价**：查一下从 A 到 B 多少钱\n- **查询订单**：输入「查询订单」了解当前订单状态（司机位置、行程进度等）\n- **司机位置**：司机在哪里、多久到\n- **预约出行**：\"15分钟后打个车\"、\"明天9点去机场\"\n- **路线规划**：驾车/公交/步行/骑行路线\n- **取消订单**：取消当前订单\n\n---\n\n## 3. Agent 执行指令\n\n以下内容为 AI 执行参考，用户可忽略。\n\n### 3.1 文件地图 \n\n按需读取以下文件，不要猜测未读过的内容：\n\n| 文件 | 用途 | 何时读取 |\n|------|------|----------|\n| `SKILL.md` | 触发、主流程、硬性门禁、查询订单规则、预约出行规则 | 每次触发必读 |\n| `references/workflow.md` | 分阶段详细流程与命令范式 | 需要实现细节时读 |\n| `references/api_references.md` | MCP 函数签名与参数定义 | 每次调用工具前**必须**核对 |\n| `references/error_handling.md` | 常见错误与恢复策略 | ⚠️ 遇到调用失败时（比如 400 错误）必须读取此文件 |\n| `references/setup.md` | 安装 mcporter、配置 MCP KEY 的完整步骤 | 用户询问安装/配置问题时读 |\n| `assets/PREFERENCE.md` | 地址别名/车型/手机号偏好 | 用户提到别名地址（家、公司、妈妈家等）、车型、手机号，或未明确给出起终点时**必须**读取。别名匹配规则见执行前检查第 6 条 |\n\n### 3.2 执行前检查\n\n1. **检查 mcporter**：若 `mcporter` 不存在（`command not found`），停止并引导用户阅读 `references/setup.md`。没有 mcporter 就无法调用任何 MCP 工具，后续任何流程都无法执行。\n\n2. **检查 Key**：执行 `openclaw config get skills.entries.didi-ride-skill.apiKey`，若输出为空或非 `__OPENCLAW_REDACTED__`，按 `### 3.9 MCP KEY 与配置` 流程引导。Key 缺失时 mcporter 的报错信息具有误导性，不要尝试绕过。\n\n3. **mcporter 调用格式**：\n\n```bash\nMCP_URL=”https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY”\nmcporter call “$MCP_URL” <tool> --args '{“key”:”value”}'\n```\n\n4. **参数值必须加引号**（字符串格式），否则 API 会报”缺少必填参数”。\n5. **先预估再下单**：`taxi_create_order` 依赖 `taxi_estimate` 返回的 `traceId`，没有 traceId 下单会失败。traceId 有时效性，过期（`-32021` 错误）需重新预估。\n6. **起终点处理**：\n   - 坐标必须来自 `maps_textsearch`，不要凭空猜测坐标。\n   - **禁止用对话历史记忆补充起终点**——用户可能已经换了地方。\n   - **起终点缺失时**按以下顺序补全：\n     - ① 读 `assets/PREFERENCE.md`，若有地址别名**且地址值非空**，根据场景推断（如早晨→起点\"家\"、下班→起点\"公司\"）。别名行存在但地址为空 = 未配置。\n     - ② 若无可用别名，直接询问用户。\n   - **别名匹配规则（精确优先）**：\"家\"只匹配别名\"家\"，不匹配\"妈妈家\"；需明确含\"妈妈\"语义才匹配\"妈妈家\"。其他自定义别名同理。\n   - **推断的起终点、或 `maps_textsearch` 返回多个候选结果时，必须在主流程 step 2 向用户确认**；用户明确指定且精确匹配的地点无需确认。\n\n### 3.3 用户确认策略\n\n| 场景 | 规则 |\n|------|------|\n| 打车（实时/预约） | 推断的地址或搜索返回多个候选时必须确认起终点（见主流程 step 2），用户明确指定且精确匹配时无需确认，确认后再预估下单 |\n| 取消订单 | 即使用户说了\"取消订单\"，仍必须先明确询问\"确认取消吗？\"，等用户回复确认后才能调用 `taxi_cancel_order`。用户的取消意图 ≠ 取消确认。 |\n\n### 3.4 主流程（最小可执行）\n\n1. 地址解析：`maps_textsearch`（必要时结合 `assets/PREFERENCE.md`，按执行前检查第 6 条处理）。\n2. 确认起终点：推断的地址（如别名推断）或 `maps_textsearch` 返回多个候选结果时，必须向用户确认（如\"从家出发去首都机场T3航站楼，确认吗？\"）；用户明确指定且精确匹配的地点无需确认。用户纠正则按纠正内容重新解析。\n3. 价格预估：`taxi_estimate`，记录 `traceId`。\n4. 车型决策：\n   - 用户明确车型：直接用；\n   - 用户未明确：使用 `assets/PREFERENCE.md` 中的场景车型偏好或默认车型；\n   - 偏好也未配置：向用户询问车型，不要自行推荐。\n   - 可用车型以 `taxi_estimate` API 返回为准，获取对应的 `productCategory` 创建订单。\n5. 创建订单：`taxi_create_order`（使用最新 `traceId`）。\n6. 结果输出：给出订单号、起终点、车型、预估价，末尾提示 `💡 发送「查询订单」可了解当前订单状态`。\n7. ⚠️ 自动回查（必做）：根据 `### 3.8 发单后自动回查` 中的 cron 指令内容，创建定时任务，参数信息严格遵循章节内要求。此步不可省略。\n\n### 3.5 偏好设置更新\n\n当用户要求设置/记住/记一下/帮我记/保存地址别名、车型偏好或手机号时，**必须**直接编辑 `assets/PREFERENCE.md` 对应的 markdown 表格行。\n\n- **地址别名**（\"我家在…\"、\"公司在…\"、\"儿子的学校是…\"、\"妈妈家在…\"）：先调用 `maps_textsearch` 解析地址获取坐标，然后更新「地址别名」表——已有别名更新对应行，新别名追加新行。别名由用户定义，不限于\"家\"\"公司\"。\n- **场景车型**（\"上班用快车\"、\"下班用特惠和快车\"）：更新「场景车型偏好」表对应行。品类代码参考表底注释，多车型用英文逗号分隔（如 `1,201`）。\n- **叫车手机号**（\"我的手机号是…\"）：更新「默认偏好」表中的叫车手机号行。\n- **创建订单时**：若 PREFERENCE.md 中配置了叫车手机号，将其作为 `caller_car_phone` 参数传入 `taxi_create_order`。\n\n### 3.6 查询订单\n\n触发词：`查询订单` / `查询订单 <orderId>`\n\n订单号来源（优先级从高到低）：\n1. 用户消息中明确给出；\n2. 当前对话上下文中最近一次创建的订单号；\n3. 以上均无时，向用户询问。\n\n调用命令：\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" taxi_query_order --args '{\"order_id\":\"ORDER_ID\"}'\n```\n\n#### 3.6.1 状态码与输出规则\n\n| code | 含义 | 必须输出 |\n|------|------|----------|\n| 0 | 匹配中 | ⏳ 正在为您匹配司机，请稍候 |\n| 1 | 司机已接单 | **必须展示**：司机姓名、车型、车牌、电话；距上车点距离和预计到达时间 |\n| 2 | 司机已到达 | 🔔 司机已到达上车点，请前往上车 |\n| 4 | 行程进行中 | 🚗 行程已开始 |\n| 5 | 订单完成 | ✅ 行程结束，展示费用（如有） |\n| 6 | 订单已被系统取消 | ❌ 订单已被系统取消 |\n| 7 | 订单已被取消 | ❌ 订单已取消 |\n| 3/8-12 | 其他终态 | 显示对应状态描述 |\n\n### 3.7 预约出行规则\n\n当用户要求在特定时间叫车（如\"15分钟后\"、\"明天9点\"）：\n\n- 使用 cron 一次性任务（`--at`），到点由 isolated agent 独立执行完整打车流程；\n- ⚠️ `--message` 必须包含完整起终点（带城市前缀）和车型，isolated session 无历史上下文。起点或终点缺失时先从 `assets/PREFERENCE.md` 推断并向用户确认，推断不了则必须先询问用户，**不要自行推断未知信息**；\n- 到点后 agent 自行执行：地址解析 → 价格预估（获取最新 traceId）→ 创建订单；\n- 如果无法获取当前会话的 metadata，不要创建 cron，改为在回复中提醒用户主动查询；\n- 如果定时任务创建失败，必须在回复中提示用户，不能默默失败。\n\n```bash\n# ⚠️ 替换占位符：\n#   FROM_NAME    → 带城市前缀的起点全称（如\"北京市西二旗地铁站\"）\n#   TO_NAME      → 带城市前缀的终点全称（如\"北京市佰嘉城小区\"）\n#   VEHICLE      → 车型（如\"快车\"）\n#   TIME         → 见下方时间规则\n#   CHANNEL_NAME → 当前会话 metadata 中的 channel 字段（如 feishu、telegram），CHANNEL_NAME 不需要带引号，例如: feishu ✅, \"feishu\" ❌。不允许使用 last 作为参数值。\n#   CHAT_ID      → 当前会话 metadata 中的 chat_id 字段\n\n\nopenclaw cron add \\\n  --name \"didi-ride-skill:$(date +%s)\" \\\n  --at \"TIME\" \\\n  --session isolated \\\n  --message \"执行定时打车：起点「FROM_NAME」，终点「TO_NAME」，车型「VEHICLE」。请完整执行打车流程：地址解析 → 价格预估（获取最新 traceId）→ 创建订单。订单创建成功后，输出订单信息并提示用户可发送「查询订单」了解订单状态，同时创建 5 分钟后自动回查 cron（模板见 SKILL.md 第 3.8 节「发单后自动回查」）。\" \\\n  --announce \\\n  --channel CHANNEL_NAME \\\n  --to \"CHAT_ID\"\n```\n\n#### 3.7.1 TIME 填写规则\n\n| 场景 | 写法 | 示例 |\n|------|------|------|\n| 相对时间（X 分钟/小时后） | duration 格式 | `15m` / `2h` / `1h30m` |\n| 绝对时间（具体时刻） | 本地时区 ISO 格式 | `$(date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00')` |\n\n- 相对时间（如 `15m`）无需格式化，直接使用\n- 绝对时间使用带时区的 ISO 8601 格式：`YYYY-MM-DDTHH:MM:SS+08:00`（北京时间东八区）\n\n**系统兼容性说明：**\n- Linux (GNU date): `date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n- macOS (BSD date): `TZ=Asia/Shanghai date -j -v+1d -f '%H:%M' '09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n\n### 3.8 发单后自动回查\n\n发单成功后（实时单或预约单），根据本章节下文 \"openclaw cron add\" 命令，创建 cron 任务，务必按照本章节下文bash命令参数设置。\n- 如果无法获取当前会话的 metadata，不要创建 cron，改为在回复中提醒用户主动查询订单状态。\n- 如果定时任务创建失败，必须在回复中提示用户，不能默默失败。\n\n```bash\n# ⚠️ 替换占位符：\n#   ORDER_ID     → 实际订单号（taxi_create_order 返回）\n#   CHANNEL_NAME → 当前会话 metadata 中的 channel 字段（如 feishu、telegram），CHANNEL_NAME 不需要带引号，例如: feishu ✅, \"feishu\" ❌。不允许使用 last 作为参数值。\n#   CHAT_ID      → 当前会话 metadata 中的 chat_id 字段\n\nopenclaw cron add \\\n  --name \"didi-ride-skill:check:ORDER_ID\" \\\n  --at \"5m\" \\\n  --session isolated \\\n  --message \"查询滴滴订单状态：订单号 ORDER_ID。调用 taxi_query_order 查询并输出当前状态。如果司机已接单，输出司机姓名、车型、车牌、电话及预计到达时间；如果仍在匹配中，提示用户耐心等待。\" \\\n  --announce \\\n  --channel CHANNEL_NAME \\\n  --to \"CHAT_ID\"\n```\n\n### 3.9 MCP KEY 与配置\n\n> **术语说明**：滴滴平台称此凭证为「MCP KEY」，OpenClaw 配置字段统一叫 `apiKey`，注入后的环境变量为 `DIDI_MCP_KEY`——三者是同一个值。\n\n⚠️ Key 来源：通过 `openclaw config set` 持久化后，OpenClaw 在每次 agent run 启动时自动注入为环境变量 `DIDI_MCP_KEY`。\n```bash\n# ⚠️ 可以通过以下命令判断当前 DIDI_MCP_KEY 是否配置。如果输出 __OPENCLAW_REDACTED__ ，即为已配置，可在后面使用环境变量`DIDI_MCP_KEY`。\nopenclaw config get skills.entries.didi-ride-skill.apiKey\n```\n\n#### 3.9.1 用户在对话中提供 Key 时（必须持久化）\n\n当用户回复了 Key（如\"我的 Key 是 xxxxxx\"），**必须**执行以下命令持久化，**严禁只 export 到当前 shell**：\n\n```bash\n# ⚠️ 将 YOUR_KEY 替换为用户提供的实际值\nopenclaw config set 'skills.entries.didi-ride-skill.apiKey' 'YOUR_KEY'\n```\n\n持久化成功后：\n- OpenClaw 在所有后续 agent run（含 cron isolated session）中自动注入 `DIDI_MCP_KEY`\n- 配置更改后会自动生效，无需额外操作指令。\n\n⚠️ Key 未配置**或** MCP 返回鉴权失败（`error.code: -32002`）时，执行以下两步：\n\n1. 执行下面的 \"openclaw message send\" 命令，发送二维码图片（`{CHAT_ID}` → metadata 的 chat_id，`{CHANNEL_NAME}` → metadata 的 channel）：\n\n```bash\nopenclaw message send --channel {CHANNEL_NAME} --target {CHAT_ID} --media \"https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png\" --message \"滴滴出行APP扫码获取MCP Key，解锁一键打车\"\n```\n\n2. 输出文字：\n\n> 您还没有配置 DIDI_MCP_KEY 或 Key 已失效，请访问 [滴滴MCP平台](https://mcp.didichuxing.com/claw) 获取 MCP KEY，然后配置环境变量或在 OpenClaw 配置文件中设置。\n\n### 3.10 工具清单\n\n| 领域 | 工具 |\n|------|------|\n| 打车 | `maps_textsearch`, `taxi_estimate`, `taxi_create_order`, `taxi_query_order`, `taxi_get_driver_location`, `taxi_cancel_order`, `maps_regeocode`, `taxi_generate_ride_app_link`（用户无 API 直发权限时的备选：生成深度链接让用户在 App 内完成发单） |\n| 路线 | `maps_direction_driving`, `maps_direction_transit`, `maps_direction_walking`, `maps_direction_bicycling` |\n| 周边 | `maps_place_around` |\n\nFile v1.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn7can12c6x8pp8ade0sxqkv6582sfzp\",\n  \"slug\": \"didi-ride-skill-official\",\n  \"version\": \"1.1.0\",\n  \"publishedAt\": 1774956684939\n}\n\nFile v1.1.0:references/api_references.md\n\n# API 文档\n\n## 响应格式说明\n\n所有工具均返回 `content[].text`（自然语言文本）。部分工具（网约车类）额外返回 `structuredContent`（结构化数据）。\n\n- 如果响应中存在 `structuredContent`，优先使用其中的字段做逻辑判断和字段提取\n- 如果没有 `structuredContent`，则解析 `content[].text` 获取所需信息\n\n## 函数签名\n\n```\n/**\n   * 根据用户输入的起点终点坐标，规划骑行通勤方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_bicycling(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户起终点经纬度坐标规划以小客车、轿车通勤出行的方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_driving(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户起终点坐标，规划综合公交、地铁的通勤方案\n   *\n   * @param city 查询城市（**必须使用完整格式，如\"北京市\"而非\"北京\"**）\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_transit(city: string, destination: string, origin: string);\n\n  /**\n   * 根据用户输入的起点终点坐标，规划步行通勤方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_walking(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户传入关键词和位置坐标，搜索出周边的POI地点信息\n   *\n   * @param keywords 搜索关键词\n   * @param location 位置坐标，格式为：经度,纬度\n   * @param max_distance? 搜索半径，单位：米\n   */\n  function maps_place_around(keywords: string, location: string, max_distance?: string);\n\n  /**\n   * 将经纬度坐标转换为地址信息\n   *\n   * @param location 位置坐标，格式为：经度,纬度\n   */\n  function maps_regeocode(location: string);\n\n  /**\n   * 根据用户传入关键词和城市，搜索出相关的POI地点信息\n   *\n   * @param city 查询城市（**必须使用完整格式，如\"北京市\"而非\"北京\"**）\n   * @param keywords 搜索关键词\n   * @param location? 位置坐标，格式为：经度,纬度\n   */\n  function maps_textsearch(city: string, keywords: string, location?: string);\n\n  /**\n   * 取消打车订单\n   *\n   * @param order_id 订单ID，从订单创建或查询结果中获取\n   * @param reason? 取消原因，可选参数。例如：不需要了、等待时间太长、临时有事等\n   */\n  function taxi_cancel_order(order_id: string, reason?: string);\n\n  /**\n   * 直接通过API创建打车订单，无需打开任何应用程序界面，系统自动完成整个发单流程\n   *\n   * @param caller_car_phone? 叫车人手机号，如果有就要传递，没有就不传\n   * @param estimate_trace_id 预估流程ID，从预估结果中获取\n   * @param product_category 车型品类标识，从预估结果中获取，传入多个车型时，用英文逗号分割，不要带空格\n   * @returns structuredContent.orderId   订单ID，后续查询/取消订单使用\n   * @returns structuredContent.status    订单初始状态（created）\n   */\n  function taxi_create_order(caller_car_phone?: string, estimate_trace_id: string, product_category: string);\n\n  /**\n   * 查看当前可用的网约车车型，请先获取对应地点的经纬度信息，如果有maps_textsearch的tool，优先使用maps_textsearch进行经纬度的获取。\n   *\n   * @param from_lat 出发纬度，必须从地图相关的工具获取，不能假设\n   * @param from_lng 出发经度，必须从地图相关的工具获取，不能假设\n   * @param from_name 出发地名称\n   * @param to_lat 目的纬度，必须从地图相关的工具获取，不能假设\n   * @param to_lng 目的经度，必须从地图相关的工具获取，不能假设\n   * @param to_name 目的地名称\n   * @returns structuredContent.traceId          预估流程ID，创建订单时必须传入\n   * @returns structuredContent.items[]          可用车型列表\n   * @returns structuredContent.items[].productName     车型名称\n   * @returns structuredContent.items[].productCategory 车型品类代码，创建订单时传入\n   * @returns structuredContent.items[].priceText       预估价格（元）\n   */\n  function taxi_estimate(from_lat: string, from_lng: string, from_name: string, to_lat: string, to_lng: string, to_name: string);\n\n  /**\n   * 根据起点、终点和车型生成打开移动应用或小程序的深度链接，用户点击后将跳转到相应的打车应用完成发单操作\n   *\n   * @param from_lat 出发纬度，必须从地图相关的工具获取，不能假设\n   * @param from_lng 出发经度，必须从地图相关的工具获取，不能假设\n   * @param product_category? 车型品类标识列表，从预估结果中获取，支持多个车型，仅当用户明确指定某个或某些品类时才传递此参数，格式为英文逗号,分割\n   * @param to_lat 目的地纬度，必须从地图相关的工具获取，不能假设\n   * @param to_lng 目的经度，必须从地图相关的工具获取，不能假设\n   */\n  function taxi_generate_ride_app_link(from_lat: string, from_lng: string, product_category?: string, to_lat: string, to_lng: string);\n\n  /**\n   * 获取打车订单对应司机的实时位置经纬度\n   *\n   * @param order_id 打车订单ID\n   */\n  function taxi_get_driver_location(order_id: string);\n\n  /**\n   * 查询打车订单的状态和信息，如司机联系方式、车牌号、预估到达时间\n   *\n   * ⚠️ 重要：此函数单次调用仅返回当前状态。\n   * 单次调用返回当前状态，详见 SKILL.md `### 3.6 查询订单`。\n   *\n   * @param order_id? 订单ID，从创建订单结果中获取，如果有就要传递，如果没有，会查询当前账号下未完成的订单\n   * @returns structuredContent.statusCode  订单状态码（见下表）\n   * @returns structuredContent.statusText  状态文本描述\n   * @returns structuredContent.driver      司机信息（name/phone/carModel/carPlate），接单后可用\n   * @returns structuredContent.map.distanceKm  距离（公里），行程中可用\n   * @returns structuredContent.map.eta         预计剩余时间（分钟），行程中可用\n   * @returns structuredContent.map.phase       当前阶段：to_pickup（前往上车点）| to_dropoff（前往终点）\n   *\n   * 订单状态码：\n   *   0  匹配中（非终态）\n   *   1  司机已接单（非终态）\n   *   2  司机已到达（非终态，里程碑通知）\n   *   3  未知状态（终态）\n   *   4  行程开始（非终态，里程碑通知）\n   *   5  订单完成（终态）✅\n   *   6  订单已被系统取消（终态）✅\n   *   7  订单已被取消（终态）✅\n   *   8  未知状态（终态）✅\n   *   9  未知状态（终态）✅\n   *   10 未知状态（终态）✅\n   *   11 客服关闭订单（终态）✅\n   *   12 未能完成服务（终态）✅\n   */\n  function taxi_query_order(order_id?: string);\n```\n\nExamples:\n\n```bash\n# 设置 MCP_URL 变量\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\n\n# 地址解析（city 建议使用完整行政区名称）\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"望京SOHO\",\"city\":\"北京市\"}'\n\n# 价格预估（注意：所有参数值必须加引号，使用字符串格式）\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lat\":\"39.9\",\"from_lng\":\"116.4\",\"from_name\":\"望京SOHO\",\"to_lat\":\"39.9\",\"to_lng\":\"116.4\",\"to_name\":\"国贸\"}'\n```\n\nFile v1.1.0:references/error_handling.md\n\n# 错误处理指南\n\n本文档说明 didi-ride-skill skill 使用过程中可能遇到的错误及解决方案。\n\n> `<skill-dir>` 代表 didi-ride-skill 技能的安装根目录（即 SKILL.md 所在目录），可通过 `openclaw skills info didi-ride-skill` 获取。\n\n## 目录\n\n- [错误处理指南](#错误处理指南)\n  - [目录](#目录)\n  - [统一错误码表](#统一错误码表)\n  - [API 返回 400 错误](#400-错误排查)\n  - [常见问题 (FAQ)](#常见问题-faq)\n  - [获取帮助](#获取帮助)\n\n***\n\n## 统一错误码表\n\n所有 MCP 工具返回的统一错误码对照：\n\n| 错误码 | 说明 | 解决方案 |\n|--------|------|----------|\n| `-32001` | 命中限流 | 请等待一段时间后重试（配额限制按时间窗口重置） |\n| `-32002` | 鉴权失败（`auth failed`） | Key 存在但无效或已过期，执行 `### 3.9 MCP KEY 与配置` 的引导流程（含发送二维码） |\n| `-32010` | 参数验证失败 | 检查参数格式，确保所有值为字符串 |\n| `-32011` | 订单不存在 | 确认订单ID正确 |\n| `-32021` | 预估结果过期 | 重新调用价格预估获取新的 traceId |\n| `-32030` | 不支持订单类型 | 该类型订单不支持此操作 |\n| `-32031` | 订单未支付 | 订单未进入支付状态 |\n| `-32040` | 订单已经取消过了 | 订单已被取消，无需重复操作 |\n| `-32041` | 订单无法被取消 | 司机已接单或订单已完成，无法通过 API 取消 |\n| `-32050` | 内部错误 | 稍后重试，如持续失败请联系客服 |\n| `-32060` | 支付失败 | 检查支付账户状态或更换支付方式 |\n\n***\n\n## 400 错误排查\n\n> 💡 **故障排查**：如果配置后 API 返回 400 错误，请检查：\n> 1. 参数名是否正确（如 `keywords` 而非 `keyword`）\n> 2. 城市名称是否使用完整格式（如 `\"北京市\"` 而非 `\"北京\"`）\n> 3. 所有参数值是否为字符串格式（加引号）\n\n***\n\n## 常见问题 (FAQ)\n\n**Q: 为什么说\"我要上班\"没反应？**\nA: 需要先配置 `assets/PREFERENCE.md` 中的家和公司地址，以及上班场景的车型偏好。\n\n**Q: 预估价格和实际价格不一致？**\nA: 预估价格为参考值，实际费用以行程完成后为准。\n\n**Q: 如何查看历史订单？**\nA: 当前 API 仅支持查询 MCP 渠道未完成订单，历史订单请在滴滴 App 中查看。\n\n**Q: 支持哪些城市？**\nA: 支持滴滴服务覆盖的所有中国大陆城市。\n\n***\n\n## 获取帮助\n\n如果以上方案无法解决问题，请：\n\n1. 检查 [workflow.md](./workflow.md) 确认操作流程\n2. 访问 <https://mcp.didichuxing.com> 获取最新文档\n\nFile v1.1.0:references/setup.md\n\n# DiDi MCP Server 安装配置指南\n\n本文档说明如何安装和配置 DiDi MCP Server，以便使用 didi-ride-skill skill。\n\n## 1. 安装 mcporter\n\nmcporter 是用于调用 MCP Server 的命令行工具。\n\n```bash\nnpm install -g mcporter\n```\n\n验证安装：\n```bash\nmcporter --version\n```\n\n## 2. 获取 MCP KEY\n\n访问 https://mcp.didichuxing.com/claw 获取您的 MCP KEY，或扫描下方二维码直达官网注册页面。\n\n![滴滴出行APP扫码获取MCP Key，解锁一键打车](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n\n\n## 3. 配置 MCP KEY\n\n**推荐方式：通过 OpenClaw 持久化（所有 isolated session 自动生效）**\n\n```bash\nopenclaw config set 'skills.entries.didi-ride-skill.apiKey' 'YOUR_MCP_KEY'\n```\n\n**备用方式：环境变量（仅当前 shell 会话有效）**\n\n```bash\nexport DIDI_MCP_KEY=\"YOUR_MCP_KEY\"\n```\n\n## 4. 验证连接\n\n设置 MCP_URL 变量：\n```bash\nexport MCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\n```\n\n测试地址解析功能：\n```bash\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"西二旗地铁站\",\"city\":\"北京市\"}'\n```\n\n测试价格预估功能：\n```bash\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lng\":\"116.322\",\"from_lat\":\"39.893\",\"from_name\":\"北京西站\",\"to_lng\":\"116.482\",\"to_lat\":\"40.004\",\"to_name\":\"首都机场\"}'\n```\n\n## 5. OpenClaw 配置\n\n如果使用 OpenClaw，还需要以下配置：\n\n- 确保已安装 `openclaw` CLI\n- 验证 mcporter 已安装：`which mcporter`\n- 若未找到，执行 `npm install -g mcporter` 后重新验证\n\n## 常见问题\n\n**Q: MCP KEY 无效**\nA: 请检查 MCP KEY 是否正确，以及是否已启用相应权限\n\n**Q: 调用超时**\nA: 检查网络连接，稍后重试\n\n**Q: 地理位置限制**\nA: 部分功能仅支持中国大陆地区\n\nFile v1.1.0:references/workflow.md\n\n# 滴滴打车详细工作流程\n\n## 全局执行约束\n\n1. 参数优先级：`用户 query` > `assets/PREFERENCE.md` > 默认值。\n2. 每次调用前先核对 [api_references.md](./api_references.md) 参数名。\n3. 所有 `--args` 值必须为字符串。\n4. `taxi_create_order` 必须使用最近一次预估返回的 `traceId`。\n5. 起终点缺失时按优先级补全：① 读 assets/PREFERENCE.md，有地址别名且值非空则推断；② 无可用别名时询问用户当前位置，不得用历史记忆补齐。\n6. 用户拒绝提供当前位置时固定回复：不提供当前位置信息则无法满足您的需求。\n\n## Phase 1：地址解析\n\n调用：`maps_textsearch`\n\n```bash\nMCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"北京西站\",\"city\":\"北京市\"}'\n```\n调用时需要注意:\n\n- city **必须使用完整格式，如\"北京市\"而非\"北京\"**\n- keywords 和 city 参数值是否为字符串格式（加引号）\n\n解析规则：\n\n- 用户给完整起终点：直接进入预估。\n- “我要上班/下班了”：允许按家↔公司偏好直接解析。\n- “回家/去公司”但缺起点：先问当前位置。\n\n## Phase 2：价格预估\n\n调用：`taxi_estimate`\n\n```bash\nmcporter call \"$MCP_URL\" taxi_estimate --args '{\"from_lat\":\"39.894\",\"from_lng\":\"116.321\",\"from_name\":\"北京西站\",\"to_lat\":\"40.053\",\"to_lng\":\"116.297\",\"to_name\":\"西二旗\"}'\n```\n\n执行要点：\n\n- 记录 `traceId`，后续发单必须使用该值。\n- 若重新预估，覆盖旧 `traceId`，只认最新一份。\n\n## Phase 3：创建订单\n\n调用：`taxi_create_order`\n\n```bash\nmcporter call \"$MCP_URL\" taxi_create_order --args '{\"estimate_trace_id\":\"TRACE_ID\",\"product_category\":\"1\"}'\n```\n\n创建策略：\n\n- 实时单允许直发，不必二次确认。\n- 用户明确车型时按用户选择发单。\n- 用户未明确车型时，可按偏好车型直发；偏好也未配置时，须向用户询问车型，不要自行推荐。\n- 若缺少 `estimate_trace_id` 或 `product_category`，禁止发单。\n\n成功输出模板：\n\n```text\n✅ 订单已创建！\n\n🚖 订单号: [orderId]\n📍 [起点] → [终点]\n🚗 车型: [车型名称]\n💰 预估: 约 [价格] 元\n📱 手机尾号: [phoneNumberSuffix]\n\n⏳ 正在为您匹配司机...\n💡 发送「查询订单」可了解当前订单状态\n```\n\n## Phase 4：查询订单\n\n触发词：`查询订单` / `查询订单 <orderId>`\n\n调用：`taxi_query_order`\n\n```bash\n# MCP_URL 沿用 Phase 1 已定义的变量\nmcporter call “$MCP_URL” taxi_query_order --args '{“order_id”:”ORDER_ID”}'\n```\n\n### 状态码与输出格式\n\n| code | 含义 | 输出建议 |\n|------|------|----------|\n| 0 | 匹配中 | ⏳ 正在为您匹配司机，请稍候 |\n| 1 | 司机已接单 | 展示司机信息（姓名、车型、车牌、电话）及距上车点距离/ETA |\n| 2 | 司机已到达 | 🔔 司机已到达上车点，请前往上车 |\n| 4 | 行程进行中 | 🚗 行程已开始，祝您旅途愉快 |\n| 5 | 订单完成 | ✅ 行程结束，展示费用（如有） |\n| 6 | 订单已被系统取消 | ❌ 订单已被系统取消 |\n| 7 | 订单已被取消 | ❌ 订单已取消 |\n| 3/8-12 | 其他终态 | 显示对应状态描述 |\n\n## Phase 5：取消订单\n\n调用顺序：\n\n1. 向用户确认是否取消（即使用户说了\"取消订单\"，仍需明确询问\"确认取消吗？\"，用户的取消意图 ≠ 取消确认）；\n2. 用户确认后调用 `taxi_cancel_order`；\n3. 调用 `taxi_query_order` 确认取消结果。\n\n## Phase 6：预约出行（cron 托管）\n\n说明：MCP API 是实时发单，预约由 OpenClaw cron 托管叫车需求，到点由 isolated agent 独立执行完整打车流程。\n\n```bash\n# ⚠️ 替换占位符：\n#   FROM_NAME    → 带城市前缀的起点全称（如”北京市西二旗地铁站”）\n#   TO_NAME      → 带城市前缀的终点全称（如”北京市佰嘉城小区”）\n#   VEHICLE      → 车型（如”快车”）\n#   TIME         → 见下方时间规则\n#   CHANNEL_NAME → 当前会话 metadata 中的 channel 字段（如 feishu、telegram），CHANNEL_NAME 不需要带引号，例如: feishu ✅, “feishu” ❌。不允许使用 last 作为参数值。\n#   CHAT_ID      → 当前会话 metadata 中的 chat_id 字段\n\nopenclaw cron add \\\n  --name “didi-ride-skill:$(date +%s)” \\\n  --at “TIME” \\\n  --session isolated \\\n  --message “执行定时打车：起点「FROM_NAME」，终点「TO_NAME」，车型「VEHICLE」。请完整执行打车流程：地址解析 → 价格预估（获取最新 traceId）→ 创建订单。订单创建成功后，输出订单信息并提示用户可发送「查询订单」了解订单状态，同时创建 5 分钟后自动回查 cron（模板见 SKILL.md 第 3.8 节「发单后自动回查」）。” \\\n  --announce \\\n  --channel CHANNEL_NAME \\\n  --to “CHAT_ID”\n```\n\n### TIME 填写规则\n\n| 场景 | 写法 | 示例 |\n|------|------|------|\n| 相对时间（X 分钟/小时后） | duration 格式 | `15m` / `2h` / `1h30m` |\n| 绝对时间（具体时刻） | 本地时区 ISO 格式 | `$(date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00')` |\n\n- 相对时间（如 `15m`）无需格式化，直接使用\n- 绝对时间使用带时区的 ISO 8601 格式：`YYYY-MM-DDTHH:MM:SS+08:00`（北京时间东八区）\n\n**系统兼容性说明：**\n- Linux (GNU date): `date -d '明天 09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n- macOS (BSD date): `TZ=Asia/Shanghai date -j -v+1d -f '%H:%M' '09:00' '+%Y-%m-%dT%H:%M:%S+08:00'`\n\n## 查询司机位置\n\n调用顺序：\n\n1. `taxi_get_driver_location`\n2. `maps_regeocode`\n\n返回内容建议包含：地址、距离、预计到达时间、司机信息（如可得）。\n\nFile v1.1.0:assets/PREFERENCE.md\n\n# 用户偏好设置\n\n> 此文件存储用户的个性化偏好数据，用于优化打车体验。当用户的 query 中没有明确指定时，系统会根据此文件的偏好自动匹配。注意：当起终点是从偏好推断的（非用户明确指定），必须先向用户确认后再执行。\n\n## 优先级说明\n\n1. **用户 query 参数**（优先级最高）：用户在当前对话中明确指定的地址、车型等\n2. **PREFERENCE.md 偏好数据**（优先级次之）：用户预设的个性化偏好\n\n## 地址别名\n\n| 别名 | 地址名称 | 经度 | 纬度 | 城市 |\n| ---- | -------- | ---- | ---- | ---- |\n| 家   |          |      |      |      |\n| 公司 |          |      |      |      |\n\n> 说明：\n> - \"家\"和\"公司\"为内置别名，支持\"从家到公司\"、\"打车回家\"等经典简化表达。\n> - 此表可自由扩展行数，用户可添加任意别名（如\"妈妈家\"、\"儿子的学校\"、\"健身房\"等）。\n> - **精确优先，语义兜底**：优先精确匹配别名（\"家\"只匹配\"家\"，不会匹配\"妈妈家\"）；无精确匹配时用语义理解（\"接孩子\"可匹配\"儿子的学校\"）。\n\n## 场景车型偏好\n\n| 场景   | 偏好车型 | 品类代码 | 说明     |\n| ------ | -------- | -------- | -------- |\n| 上班   |          |          |          |\n| 下班   |          |          |          |\n| 其他   |          |          |          |\n\n> 说明：当用户说\"我要上班\"或\"下班回家\"时，自动使用对应的车型偏好\n>\n> 品类代码来自 `taxi_estimate` 返回的 `product_category` 字段。常见值：快车=1，特惠快车=201，滴滴轻享=193，专车=8，豪华车=17。\n> ⚠️ 注意：可用车型以 API 实际返回为准，新增车型会自动出现在预估结果中。支持多车型时用英文逗号分隔，如 `1,201`\n\n## 默认偏好\n\n| 配置项     | 值   | 说明 |\n| ---------- | ---- | ---- |\n| 默认车型   |      | 无明确需求时使用 |\n| 叫车手机号 |      | 默认叫车号码 |\n\n## 使用示例\n\n1. **地址别名使用**（语义匹配，精确优先）：\n   - \"我要回家\" → 精确匹配别名\"家\"（用户自己的家），不会匹配\"妈妈家\"\n   - \"从家到公司\" → 精确匹配\"家\"为起点，\"公司\"为终点\n   - \"从家去公司\" → 同上，\"家\"= 用户自己的家\n   - \"去妈妈家\" / \"去我妈那儿\" → 匹配别名\"妈妈家\"（需明确含\"妈妈\"语义）\n   - \"送儿子上学\" / \"接孩子\" → 匹配别名\"儿子的学校\"\n   - \"去健身\" → 匹配别名\"健身房\"\n\n2. **场景偏好使用**：\n   - \"我要上班\" → 自动使用\"上班\"场景的车型偏好\n   - \"下班了\" → 自动使用\"下班\"场景的车型偏好\n\n## 更新日志\n\n- 2026-03-11: 初始化偏好文件\n\nFile v1.1.0:package.json\n\n{\n  \"name\": \"didi-ride-skill\",\n  \"version\": \"1.1.0\",\n  \"description\": \"DiDi Ride Skill for OpenClaw - 打车、路线规划、周边搜索\",\n  \"type\": \"module\",\n  \"author\": \"DiDi MCP Team\",\n  \"homepage\": \"https://mcp.didichuxing.com\",\n  \"keywords\": [\n    \"didi\",\n    \"taxi\",\n    \"mcp\",\n    \"openclaw\",\n    \"mobility\"\n  ]\n}","readmeExcerpt":"Skill: DiDi Ride SKILL Owner: didi Summary: 中国城市出行服务。当用户表达任何交通出行需求时必须使用此技能——包括打车/叫车/网约车、查价格、路线规划（公交/驾车/步行/骑行）、周边搜索、查询订单/司机位置/取消订单。关键词：\"打车\"、\"叫车\"、\"去[地点]\"、\"回家\"、\"上班\"、\"下班\"、\"查价格\"、\"多少钱\"、\"路线\"、\"怎么走\"、\"步行到\"、\"附近\"、... Tags: latest:1.1.3 Version history: v1.1.3 | 2026-05-18T11:20:49.288Z | user Summary: This update adds documentation for the DiDi Ride Skill. - Added safety guardrails in SKILL.md to prevent the __OPENCLAW_REDACTED_","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"你: 我的 MCP Key 是 xxxxxx"},{"language":"json","snippet":"{\n  \"skills\": {\n    \"entries\": {\n      \"didi-ride-skill\": {\n        \"enabled\": true,\n        \"apiKey\": \"你的MCP_KEY\"  // apiKey 是 OpenClaw 标准字段名，存储的值就是滴滴平台的 MCP KEY\n      }\n    }\n  }\n}"},{"language":"text","snippet":"你: 打车去北京西站\n你: 帮我查一下从国贸到三里屯的路线\n你: 查询订单"},{"language":"bash","snippet":"MCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" <tool> --args '{\"key\":\"value\"}'"},{"language":"bash","snippet":"MCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" taxi_query_order --args '{\"order_id\":\"ORDER_ID\"}'"},{"language":"bash","snippet":"# ⚠️ 占位符替换规则：所有 <XXX> 形式都是占位符，必须替换为真实值；\n#    禁止保留 <> 字面、禁止当成 shell 变量加 $（不是 $TIME / $CHAT_ID）。\n#   <FROM_NAME>    → 带城市前缀的起点全称（如\"北京市西二旗地铁站\"）\n#   <TO_NAME>      → 带城市前缀的终点全称（如\"北京市佰嘉城小区\"）\n#   <VEHICLE>      → 车型（如\"快车\"）\n#   <TIME>         → 见下方时间规则（如 \"10m\" / \"2h\" / ISO 时间）\n#   <CHANNEL_NAME> → 当前会话 metadata 中的 channel 字段（如 feishu、telegram），命令行参数不带引号；不可用 last\n#   <CHAT_ID>      → 当前会话 metadata 中的 chat_id 字段\n\nopenclaw cron add \\\n  --name \"didi-ride-skill:$(date +%s)\" \\\n  --at \"<TIME>\" \\\n  --session isolated \\\n  --message \"执行定时打车：起点「<FROM_NAME>」，终点「<TO_NAME>」，车型「<VEHICLE>」。请完整执行打车流程：地址解析 → 价格预估（获取最新 traceId）→ 创建订单。订单创建成功后，输出订单信息并提示用户可发送「查询订单」了解订单状态，同时创建 5 分钟后自动回查 cron（模板见 SKILL.md 第 3.8 节「发单后自动回查」）。\" \\\n  --announce \\\n  --channel <CHANNEL_NAME> \\\n  --to \"<CHAT_ID>\""}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: didi-ride-skill\ndescription: 中国城市出行服务。当用户表达任何交通出行需求时必须使用此技能——包括打车/叫车/网约车、查价格、路线规划（公交/驾车/步行/骑行）、周边搜索、查询订单/司机位置/取消订单。关键词：\"打车\"、\"叫车\"、\"去[地点]\"、\"回家\"、\"上班\"、\"下班\"、\"查价格\"、\"多少钱\"、\"路线\"、\"怎么走\"、\"步行到\"、\"附近\"、\"周边\"、\"司机\"、\"订单\"、\"查询订单\"。注意：即使用户未明确说\"打车\"，只要涉及从A地到B地、通勤、或交通方式选择，都应触发。不触发场景：开发打车应用、使用其他导航app、订外卖、查公交时刻表、股票/财报查询。\nhomepage: https://mcp.didichuxing.com\nmetadata:\n  { \"openclaw\": { \"emoji\": \"🚕\", \"always\": true, \"requires\": { \"bins\": [\"openclaw\", \"mcporter\"], \"env\": [\"DIDI_MCP_KEY\"] }, \"primaryEnv\": \"DIDI_MCP_KEY\", \"install\": [{ \"id\": \"node\", \"kind\": \"node\", \"package\": \"mcporter\", \"bins\": [\"mcporter\"], \"label\": \"Install mcporter (node)\" }] } }\n---\n\n# 滴滴出行服务 (DiDi Ride Skill)\n\n通过 DiDi MCP Server API 提供打车、查询订单、司机位置、预约叫车、路线规划、周边搜索能力。\n\n---\n\n## 1. 快速开始（2 分钟）\n\n### 1.1 获取 MCP KEY\n\n**方式一：用「滴滴出行App」扫码（推荐，最快）**\n\n![滴滴出行APP扫码获取MCP Key，解锁一键打车](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n> ⚠️ **Agent 注意**：用户客户端无法渲染 Markdown 图片，**禁止直接输出上方图片语法**。需向用户发送二维码时，执行 `### 3.9 MCP KEY 与配置` 中的 `openclaw message send` 命令发图。\n\n打开滴滴出行 App，扫描二维码，即可快速获取 MCP Key。\n\n**方式二：访问官网**\n\n访问 https://mcp.didichuxing.com/claw 获取您的 MCP Key。\n\n### 1.2 配置 Key\n\n**方式一：对话中输入（推荐）**\n\n直接在对话中告诉我您的 MCP Key，我会帮您配置：\n\n```\n你: 我的 MCP Key 是 xxxxxx\n```\n\n**方式二：OpenClaw 配置文件**\n\n编辑 `~/.openclaw/openclaw.json`，添加：\n\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"didi-ride-skill\": {\n        \"enabled\": true,\n        \"apiKey\": \"你的MCP_KEY\"  // apiKey 是 OpenClaw 标准字段名，存储的值就是滴滴平台的 MCP KEY\n      }\n    }\n  }\n}\n```\n\n### 1.3 开始使用\n\n配置完成后，直接对话即可：\n\n```\n你: 打车去北京西站\n你: 帮我查一下从国贸到三里屯的路线\n你: 查询订单\n```\n\n首次使用时，OpenClaw 会提示安装 mcporter 工具。\n\n---\n\n## 2. 用户指南\n\n本 Skill 支持以下操作：\n\n- **打车**：直接说\"打车去[地点]\"、\"回家\"、\"上班\"\n- **查价**：查一下从 A 到 B 多少钱\n- **查询订单**：输入「查询订单」了解当前订单状态（司机位置、行程进度等）\n- **司机位置**：司机在哪里、多久到\n- **预约出行**：\"15分钟后打个车\"、\"明天9点去机场\"\n- **路线规划**：驾车/公交/步行/骑行路线\n- **取消订单**：取消当前订单\n\n---\n\n## 3. Agent 执行指令\n\n以下内容为 AI 执行参考，用户可忽略。\n\n### 3.1 文件地图 \n\n按需读取以下文件，不要猜测未读过的内容：\n\n| 文件 | 用途 | 何时读取 |\n|------|------|----------|\n| `SKILL.md` | 触发、主流程、硬性门禁、查询订单规则、预约出行规则 | 每次触发必读 |\n| `references/workflow.md` | 分阶段详细流程与命令范式 | 需要实现细节时读 |\n| `references/api_references.md` | MCP 函数签名与参数定义 | 每次调用工具前**必须**核对 |\n| `references/error_handling.md` | create_order 失败提示、mcporter 常见错误、统一错误码、参数错误排查、apiKey 占位符泄漏 | ⚠️ 遇到任何调用失败（HTTP error / StatusCode=400 / `-32xxx` 错误码 / `Unknown MCP server` / `Missing KEY parameter` / `SSE error: Invalid content type`）必须读取此文件 |\n| `references/setup.md` | 安装 mcporter、配置 MCP KEY 的完整步骤 | 用户询问安装/配置问题时读 |\n| `assets/PREFERENCE.md` | 地址别名/车型/手机号偏好 | 用户提到别名地址（家、公司、妈妈家等）、车型、手机号，或未明确给出起终点时**必须**读取。别名匹配规则见执行前检查第 7 条 |\n\n### 3.2 执行前检查\n\n1. **检查 mcporter**：若 `mcporter` 不存在（`command not found`），停止并引导用户阅读 `references/setup.md`。没有 mcporter 就无法调用任何 MCP 工具，后续任何流程都无法执行。\n\n2. **检查 Key**：执行 `openclaw config get skills.entries.didi-ride-skill.apiKey`，若输出为空或非 `__OPENCLAW_REDACTED__`，按 `### 3.9 MCP KEY 与配置` 流程引导。Key 缺失时 mcporter 的报错信息具有误导性，不要尝试绕过。\n   - ⚠️ **若 Key 已配置（返回 `__OPENCLAW_REDACTED__`）但 mcporter 仍报 `Missing KEY parameter`**：**不是 Key 失效**，**禁止向用户索要 Key**。排查步骤见 `refe"},{"path":"README.md","content":"# didi-ride-skill\n\n[English](README.en.md) | 中文\n\n【滴滴出行统一入口】处理用户所有出行相关需求，提供完整的打车服务和路线规划功能。\n\n**ClawHub**: [didi-ride-skill-official](https://clawhub.ai/didi/didi-ride-skill-official)\n\n> **服务范围**：支持滴滴出行服务覆盖的中国大陆城市。\n\n## 目录\n\n- [快速开始](#快速开始)\n- [功能介绍](#功能介绍)\n- [前置安装](#前置安装)\n- [MCP 工具](#mcp-工具)\n- [工作流程](#工作流程)\n- [使用示例](#使用示例)\n- [技术支持](#技术支持)\n\n---\n\n## 快速开始\n\n**3 步开始使用：**\n\n**Step 1 — 安装 mcporter**\n\n```bash\nnpm install -g mcporter\n```\n\n**Step 2 — 获取并配置 MCP KEY**\n\n扫描 [滴滴 MCP 平台](https://mcp.didichuxing.com/claw) 二维码获取 KEY，然后直接告诉 AI：\n\n```\n你: 我的 MCP Key 是 xxxxxx\n```\n\n**Step 3 — 开始出行**\n\n```\n你: 帮我打车去北京西站\n你: 从国贸到三里屯怎么走\n```\n\n---\n\n## 功能介绍\n\n### 打车服务\n\n| 功能 | 说明 |\n|------|------|\n| 实时叫车 | 地址解析 → 价格预估 → 车型决策（用户或偏好）→ 创建订单 |\n| 预约出行 | 创建定时任务，到点后自动发起打车请求 |\n| 查询订单 | 用户主动发送「查询订单」，单次查询当前状态 |\n| 查询司机位置 | 逆地址编码，美化输出司机位置信息 |\n| 取消订单 | 展示订单信息 → 用户确认 → 取消 |\n| 价格预估 | 获取各车型价格对比 |\n| 偏好设置 | 记住常用地址（家/公司）、车型偏好、叫车手机号 |\n\n### 路线规划\n\n| 功能 | 说明 |\n|------|------|\n| 驾车路线 | 规划小客车/轿车出行方案 |\n| 公交地铁 | 综合公交、地铁通勤方案 |\n| 步行路线 | 规划步行出行方案 |\n| 骑行路线 | 规划骑行出行方案 |\n| 周边搜索 | 搜索附近的地点、设施 |\n\n---\n\n## 前置安装\n\n### 1. 获取 MCP KEY\n\n**方式 A：扫码获取（推荐，最快）**\n\n打开滴滴出行 App，扫描下方二维码，即可快速获取 MCP KEY：\n\n![滴滴出行APP扫码获取MCP Key](https://s3-yspu-cdn.didistatic.com/mcp-web/qrcode/didi_ride_skill_qrcode.png)\n\n**方式 B：访问官网**\n\n访问 [滴滴 MCP 平台](https://mcp.didichuxing.com/claw) 获取 MCP KEY。\n\n### 2. 安装 mcporter\n\n```bash\nnpm install -g mcporter\n```\n\n### 3. 配置 MCP KEY\n\n**方式 A：对话中输入（推荐）**\n\n直接在对话中告诉 AI 您的 MCP KEY，AI 会自动持久化配置：\n\n```\n你: 我的 MCP Key 是 xxxxxx\n```\n\n**方式 B：环境变量**\n\n```bash\nexport DIDI_MCP_KEY=\"YOUR_MCP_KEY_HERE\"\n```\n\n**方式 C：配置文件**\n\n编辑 `~/.openclaw/openclaw.json`：\n\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"didi-ride-skill\": {\n        \"apiKey\": \"YOUR_MCP_KEY_HERE\"\n      }\n    }\n  }\n}\n```\n\n### 4. 验证配置\n\n```bash\n# 检查 Key 是否已配置\necho $DIDI_MCP_KEY\n\n# 测试 API 连通性\nexport MCP_URL=\"https://mcp.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\nmcporter call \"$MCP_URL\" maps_textsearch --args '{\"keywords\":\"西二旗地铁站\",\"city\":\"北京市\"}'\n```\n\n---\n\n## MCP 工具\n\n### 打车相关\n\n| 工具 | 用途 |\n|------|------|\n| `maps_textsearch` | 文本地址解析，获取经纬度坐标 |\n| `taxi_estimate` | 价格预估，查询可用车型及价格 |\n| `taxi_create_order` | 创建打车订单 |\n| `taxi_query_order` | 查询订单状态和司机信息 |\n| `taxi_get_driver_location` | 获取司机实时位置 |\n| `maps_regeocode` | 逆地址编码（坐标转地址） |\n| `taxi_cancel_order` | 取消订单 |\n| `taxi_generate_ride_app_link` | 生成 App 深度链接（无 API 直发权限时的备选方案） |\n\n### 路线规划相关\n\n| 工具 | 用途 |\n|------|------|\n| `maps_direction_driving` | 驾车路线规划 |\n| `maps_direction_transit` | 公交地铁路线规划 |\n| `maps_direction_walking` | 步行路线规划 |\n| `maps_direction_bicycling` | 骑行路线规划 |\n| `maps_place_around` | 周边搜索 |\n\n---\n\n## 工作流程\n\n### 打车流程\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│                    用户发起打车请求                             │\n│               \"我要从国贸去三里屯\"                              │\n└──────────────────────────┬──────────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────────┐\n│  Step 1: 地址解析 (maps_textsearch)  "},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7can12c6x8pp8ade0sxqkv6582sfzp\",\n  \"slug\": \"didi-ride-skill-official\",\n  \"version\": \"1.1.3\",\n  \"publishedAt\": 1779103249288\n}"},{"path":"references/api_references.md","content":"# API 文档\n\n## 响应格式说明\n\n所有工具均返回 `content[].text`（自然语言文本）。部分工具（网约车类）额外返回 `structuredContent`（结构化数据）。\n\n- 如果响应中存在 `structuredContent`，优先使用其中的字段做逻辑判断和字段提取\n- 如果没有 `structuredContent`，则解析 `content[].text` 获取所需信息\n\n## 函数签名\n\n```\n/**\n   * 根据用户输入的起点终点坐标，规划骑行通勤方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_bicycling(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户起终点经纬度坐标规划以小客车、轿车通勤出行的方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_driving(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户起终点坐标，规划综合公交、地铁的通勤方案\n   *\n   * @param city 查询城市（**必须使用完整格式，如\"北京市\"而非\"北京\"**）\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_transit(city: string, destination: string, origin: string);\n\n  /**\n   * 根据用户输入的起点终点坐标，规划步行通勤方案\n   *\n   * @param destination 终点坐标，格式为：经度,纬度\n   * @param need_geo? 是否需要返回途经的点序列，默认值为true\n   * @param origin 起点坐标，格式为：经度,纬度\n   */\n  function maps_direction_walking(destination: string, need_geo?: boolean, origin: string);\n\n  /**\n   * 根据用户传入关键词和位置坐标，搜索出周边的POI地点信息\n   *\n   * @param keywords 搜索关键词\n   * @param location 位置坐标，格式为：经度,纬度\n   * @param max_distance? 搜索半径，单位：米\n   */\n  function maps_place_around(keywords: string, location: string, max_distance?: string);\n\n  /**\n   * 将经纬度坐标转换为地址信息\n   *\n   * @param location 位置坐标，格式为：经度,纬度\n   */\n  function maps_regeocode(location: string);\n\n  /**\n   * 根据用户传入关键词和城市，搜索出相关的POI地点信息\n   *\n   * @param city 查询城市（**必须使用完整格式，如\"北京市\"而非\"北京\"**）\n   * @param keywords 搜索关键词\n   * @param location? 位置坐标，格式为：经度,纬度\n   */\n  function maps_textsearch(city: string, keywords: string, location?: string);\n\n  /**\n   * 取消打车订单\n   *\n   * @param order_id 订单ID，从订单创建或查询结果中获取\n   * @param reason? 取消原因，可选参数。例如：不需要了、等待时间太长、临时有事等\n   */\n  function taxi_cancel_order(order_id: string, reason?: string);\n\n  /**\n   * 直接通过API创建打车订单，无需打开任何应用程序界面，系统自动完成整个发单流程\n   *\n   * @param caller_car_phone? 叫车人手机号，如果有就要传递，没有就不传\n   * @param estimate_trace_id 预估流程ID，从预估结果中获取\n   * @param product_category 车型品类标识，从预估结果中获取，传入多个车型时，用英文逗号分割，不要带空格\n   * @returns structuredContent.orderId   订单ID，后续查询/取消订单使用\n   * @returns structuredContent.status    订单初始状态（created）\n   */\n  function taxi_create_order(caller_car_phone?: string, estimate_trace_id: string, product_category: string);\n\n  /**\n   * 查看当前可用的网约车车型，请先获取对应地点的经纬度信息，如果有maps_textsearch的tool，优先使用maps_textsearch进行经纬度的获取。\n   *\n   * @param from_lat 出发纬度，必须从地图相关的工具获取，不能假设\n   * @param from_lng 出发经度，必须从地图相关的工具获取，不能假设\n   * @param from_name 出发地名称\n   * @param to_lat 目的纬度，必须从地图相关的工具获取，不能假设\n   * @param to_lng 目的经度，必须从地图相关的工具获取，不能假设\n   * @param to_name 目的地名称\n   * @returns structuredContent.traceId          预估流程ID，创建订单时必须传入\n   * @returns structuredContent.items[]          可用车型列表\n   * @returns structuredContent.items[].productName     车型名称\n   * @retu"},{"path":"references/error_handling.md","content":"# 错误处理指南\n\n本文档说明 didi-ride-skill skill 使用过程中可能遇到的错误及解决方案。\n\n> `<skill-dir>` 代表 didi-ride-skill 技能的安装根目录（即 SKILL.md 所在目录），可通过 `openclaw skills info didi-ride-skill` 获取。\n\n## 目录\n\n- [错误处理指南](#错误处理指南)\n  - [目录](#目录)\n  - [mcporter Missing KEY parameter](#mcporter-missing-key-parameter)\n  - [SSE error / apiKey 占位符泄漏](#sse-error--apikey-占位符泄漏)\n  - [mcporter.json 校验错误](#mcporterjson-校验错误invalid_type--failed-to-parse-json)\n  - [taxi_create_order 调用失败](#taxi_create_order-调用失败)\n  - [Unknown MCP server 错误](#unknown-mcp-server-错误)\n  - [统一错误码表](#统一错误码表)\n  - [参数错误排查](#参数错误排查statuscode400--backend-call-failed)\n  - [常见问题 (FAQ)](#常见问题-faq)\n  - [获取帮助](#获取帮助)\n\n***\n\n## mcporter Missing KEY parameter\n\nmcporter 报 `Missing KEY parameter` 时，**不代表 MCP Key 已失效**，禁止直接向用户索要 Key。\n\n可能原因（按概率排序逐一排查）：\n\n1. **`$DIDI_MCP_KEY` 环境变量未展开**：`MCP_URL` 赋值时用了单引号（`'$DIDI_MCP_KEY'`）而非双引号，导致变量字面量传入。确认调用命令中 `MCP_URL` 使用双引号包裹，然后重试。\n2. **当前 shell 未注入环境变量**：openclaw 在每次 agent run 启动时自动注入 `DIDI_MCP_KEY`，但手动在终端直接运行 mcporter 时该变量不存在。执行 `echo $DIDI_MCP_KEY` 验证——若为空，在终端手动 `export DIDI_MCP_KEY=<key>` 后重试，或改在 openclaw agent 环境中调用。\n3. **mcporter.json 配置异常**：若当前目录下 `config/mcporter.json` 或 `~/.mcporter/mcporter.json` 存在且格式异常，mcporter 会在启动阶段直接崩溃（报 `invalid_type` 或 `Failed to parse JSON`），所有命令不可用。**不要删除该文件**（可能包含用户其他应用的配置），改用 `--config` 绕过——见 SKILL.md §3.2 第 3 条。\n4. **Key 本身确实无效**：若以上均排除，执行 `openclaw config get skills.entries.didi-ride-skill.apiKey` 确认 Key 已配置，若返回空则按 `### 3.9 MCP KEY 与配置` 流程重新配置。\n\n***\n\n## SSE error / apiKey 占位符泄漏\n\nmcporter 报 `SseError: SSE error: Invalid content type, expected \"text/event-stream\"` 时，最常见根因是把 OpenClaw 的哨兵值 `__OPENCLAW_REDACTED__` 当成真实 Key 拼进了 MCP URL。\n\n**症状**：\n\n- 拼出来的 URL 实际是 `https://mcp-dev.didichuxing.com/mcp-servers?key=__OPENCLAW_REDACTED__`\n- 服务端把它当成无效 Key 拒绝，返回 HTML / 纯文本错误页（不是 SSE 流）\n- mcporter 收到非 `text/event-stream` 响应直接抛 `SseError`\n\n**为什么会拼错**：误以为 `openclaw config get skills.entries.didi-ride-skill.apiKey` 配上 `--raw` / `awk` / `sed` 之类的手段能拿到真实 Key 字面量。实际上：\n\n> `openclaw config get`（含 `--raw`）**永远不会**返回真实 Key 字面量。`__OPENCLAW_REDACTED__` 是\"已配置\"的哨兵值，不是 Key 本身。真实 Key 由 OpenClaw 在每次 agent run 启动时注入到环境变量 `DIDI_MCP_KEY`，调用方只能通过 `$DIDI_MCP_KEY` 使用。\n\n**修复步骤**：\n\n1. 自检环境变量是否注入：\n\n   ```bash\n   printenv DIDI_MCP_KEY >/dev/null && echo env_ok || echo env_missing\n   ```\n\n2. 若 `env_ok`：把 URL 拼接改回 SKILL.md §3.2 第 4 条的固定写法，不要再尝试从 config 提取 Key：\n\n   ```bash\n   MCP_URL=\"https://mcp-dev.didichuxing.com/mcp-servers?key=$DIDI_MCP_KEY\"\n   mcporter call \"$MCP_URL\" <tool> --args '...'\n   ```\n\n3. 若 `env_missing`：当前不在 openclaw agent run 上下文里（例如手动终端调用），按 SKILL.md §3.9 引导用户重新配置；或临时 `export DIDI_MCP_KEY=<key>` 后重试。\n\n**禁止**：\n\n- 禁止用 `openclaw config get ... --raw` / `awk` / `sed` / `jq` 等任何手段尝试从配置提取 Key 字面量\n- 禁止把 `__OPENCLAW_REDACTED__` 出现在任何 URL / header / 参数中\n- 禁止在见到本错误时向用户索要新的 Key——Key 可能完全有效，只是用错了\n\n***\n\n## mcporter.json 校验错误（`invalid_type` / `Failed to parse JSON`）\n\nmcporter 启动时报 `invalid_type, expected record` 或 `Failed to parse JSON` 等校验错误时，说明当前目录的 `config/mcporter.json` 或 `~/.mcporter/mcporter.js"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1611,"uniquenessScore":41,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-09T14:34:16.233Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-09T14:34:16.233Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-09T19:57:29.664Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}