{
  "canonical_name": "dmang-dev/mcp-pine",
  "compilation_id": "pack_5fe2f45887fe42fbac04143f81381c85",
  "created_at": "2026-05-20T07:14:55.086199+00:00",
  "created_by": "project-pack-compiler",
  "feedback": {
    "carrier_selection_notes": [
      "viable_asset_types=mcp_config, recipe, host_instruction, eval, preflight",
      "recommended_asset_types=mcp_config, recipe, host_instruction, eval, preflight"
    ],
    "evidence_delta": {
      "confirmed_claims": [
        "identity_anchor_present",
        "capability_and_host_targets_present",
        "install_path_declared_or_better"
      ],
      "missing_required_fields": [],
      "must_verify_forwarded": [
        "Run or inspect `npm install -g mcp-pine` in an isolated environment.",
        "Confirm the project exposes the claimed capability to at least one target host."
      ],
      "quickstart_execution_scope": "allowlisted_sandbox_smoke",
      "sandbox_command": "npm install -g mcp-pine",
      "sandbox_container_image": "node:22-slim",
      "sandbox_execution_backend": "docker",
      "sandbox_planner_decision": "deterministic_isolated_install",
      "sandbox_validation_id": "sbx_1f2360bcd9b84433ae713dfc4476c37e"
    },
    "feedback_event_type": "project_pack_compilation_feedback",
    "learning_candidate_reasons": [],
    "template_gaps": []
  },
  "identity": {
    "canonical_id": "project_3dd7b7863aca3feec2afb3bebb628f46",
    "canonical_name": "dmang-dev/mcp-pine",
    "homepage_url": null,
    "license": "unknown",
    "repo_url": "https://github.com/dmang-dev/mcp-pine",
    "slug": "mcp-pine",
    "source_packet_id": "phit_ed4e41c994a146838e2fbfe975eb809b",
    "source_validation_id": "dval_99340a3d39b8461282fe507952ba5142"
  },
  "merchandising": {
    "best_for": "需要工具连接与集成能力，并使用 mcp_host的用户",
    "github_forks": 0,
    "github_stars": 0,
    "one_liner_en": "MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control",
    "one_liner_zh": "MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control",
    "primary_category": {
      "category_id": "tool-integrations",
      "confidence": "high",
      "name_en": "Tool Integrations",
      "name_zh": "工具连接与集成",
      "reason": "matched_keywords:mcp, server, github"
    },
    "target_user": "使用 mcp_host, claude 等宿主 AI 的用户",
    "title_en": "mcp-pine",
    "title_zh": "mcp-pine 能力包",
    "visible_tags": [
      {
        "label_en": "MCP Tools",
        "label_zh": "MCP 工具",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-mcp-tools",
        "type": "product_domain"
      },
      {
        "label_en": "Tool Integration",
        "label_zh": "工具接入扩展",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-tool-integration",
        "type": "user_job"
      },
      {
        "label_en": "Workflow Automation",
        "label_zh": "流程自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-workflow-automation",
        "type": "core_capability"
      },
      {
        "label_en": "Node-based Workflow",
        "label_zh": "节点式流程编排",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-node-based-workflow",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Local-first",
        "label_zh": "本地优先",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-local-first",
        "type": "selection_signal"
      }
    ]
  },
  "packet_id": "phit_ed4e41c994a146838e2fbfe975eb809b",
  "page_model": {
    "artifacts": {
      "artifact_slug": "mcp-pine",
      "files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json",
        "REPO_INSPECTION.md",
        "CAPABILITY_CONTRACT.json",
        "EVIDENCE_INDEX.json",
        "CLAIM_GRAPH.json"
      ],
      "required_files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json"
      ]
    },
    "detail": {
      "capability_source": "Project Hit Packet + DownstreamValidationResult",
      "commands": [
        {
          "command": "npm install -g mcp-pine",
          "label": "Node.js / npm · 官方安装入口",
          "source": "https://github.com/dmang-dev/mcp-pine#readme",
          "verified": true
        }
      ],
      "display_tags": [
        "MCP 工具",
        "工具接入扩展",
        "流程自动化",
        "节点式流程编排",
        "本地优先"
      ],
      "eyebrow": "工具连接与集成",
      "glance": [
        {
          "body": "判断自己是不是目标用户。",
          "label": "最适合谁",
          "value": "需要工具连接与集成能力，并使用 mcp_host的用户"
        },
        {
          "body": "先理解能力边界，再决定是否继续。",
          "label": "核心价值",
          "value": "MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control"
        },
        {
          "body": "未完成验证前保持审慎。",
          "label": "继续前",
          "value": "publish to Doramagic.ai project surfaces"
        }
      ],
      "guardrail_source": "Boundary & Risk Card",
      "guardrails": [
        {
          "body": "Prompt Preview 只展示流程，不证明项目已安装或运行。",
          "label": "Check 1",
          "value": "不要把试用当真实运行"
        },
        {
          "body": "mcp_host, claude",
          "label": "Check 2",
          "value": "确认宿主兼容"
        },
        {
          "body": "publish to Doramagic.ai project surfaces",
          "label": "Check 3",
          "value": "先隔离验证"
        }
      ],
      "mode": "mcp_config, recipe, host_instruction, eval, preflight",
      "pitfall_log": {
        "items": [
          {
            "body": "GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Submit listing PR to punkpeye/awesome-mcp-servers",
            "category": "安装坑",
            "evidence": [
              "community_evidence:github | cevd_540ae479012f437fb2cb5e7d33636f1f | https://github.com/dmang-dev/mcp-pine/issues/2 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：Submit listing PR to punkpeye/awesome-mcp-servers",
            "user_impact": "可能阻塞安装或首次运行。"
          },
          {
            "body": "项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。",
            "category": "配置坑",
            "evidence": [
              "capability.host_targets | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | host_targets=mcp_host, claude"
            ],
            "severity": "medium",
            "suggested_check": "列出会写入的配置文件、目录和卸载/回滚步骤。",
            "title": "可能修改宿主 AI 配置",
            "user_impact": "安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。"
          },
          {
            "body": "README/documentation is current enough for a first validation pass.",
            "category": "能力坑",
            "evidence": [
              "capability.assumptions | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | README/documentation is current enough for a first validation pass."
            ],
            "severity": "medium",
            "suggested_check": "将假设转成下游验证清单。",
            "title": "能力判断依赖假设",
            "user_impact": "假设不成立时，用户拿不到承诺的能力。"
          },
          {
            "body": "未记录 last_activity_observed。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | last_activity_observed missing"
            ],
            "severity": "medium",
            "suggested_check": "补 GitHub 最近 commit、release、issue/PR 响应信号。",
            "title": "维护活跃度未知",
            "user_impact": "新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "downstream_validation.risk_items | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "进入安全/权限治理复核队列。",
            "title": "下游验证发现风险项",
            "user_impact": "下游已经要求复核，不能在页面中弱化。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "risks.scoring_risks | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "把风险写入边界卡，并确认是否需要人工复核。",
            "title": "存在评分风险",
            "user_impact": "风险会影响是否适合普通用户安装。"
          },
          {
            "body": "issue_or_pr_quality=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | issue_or_pr_quality=unknown"
            ],
            "severity": "low",
            "suggested_check": "抽样最近 issue/PR，判断是否长期无人处理。",
            "title": "issue/PR 响应质量未知",
            "user_impact": "用户无法判断遇到问题后是否有人维护。"
          },
          {
            "body": "release_recency=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | release_recency=unknown"
            ],
            "severity": "low",
            "suggested_check": "确认最近 release/tag 和 README 安装命令是否一致。",
            "title": "发布节奏不明确",
            "user_impact": "安装命令和文档可能落后于代码，用户踩坑概率升高。"
          }
        ],
        "source": "ProjectPitfallLog + ProjectHitPacket + validation + community signals",
        "summary": "发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：安装坑 - 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers。",
        "title": "踩坑日志"
      },
      "snapshot": {
        "contributors": 1,
        "forks": 0,
        "license": "unknown",
        "note": "站点快照，非实时质量证明；用于开工前背景判断。",
        "stars": 0
      },
      "source_url": "https://github.com/dmang-dev/mcp-pine",
      "steps": [
        {
          "body": "不安装项目，先体验能力节奏。",
          "code": "preview",
          "title": "先试 Prompt"
        },
        {
          "body": "理解输入、输出、失败模式和边界。",
          "code": "manual",
          "title": "读说明书"
        },
        {
          "body": "把上下文交给宿主 AI 继续工作。",
          "code": "context",
          "title": "带给 AI"
        },
        {
          "body": "进入主力环境前先完成安装入口与风险边界验证。",
          "code": "verify",
          "title": "沙箱验证"
        }
      ],
      "subtitle": "MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control",
      "title": "mcp-pine 能力包",
      "trial_prompt": "# mcp-pine - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 mcp-pine 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的工具连接与集成任务。\n我常用的宿主 AI：MCP Client / claude\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-introduction：项目介绍。围绕“项目介绍”模拟一次用户任务，不展示安装或运行结果。\n2. page-quickstart：快速开始。围绕“快速开始”模拟一次用户任务，不展示安装或运行结果。\n3. page-architecture：系统架构。围绕“系统架构”模拟一次用户任务，不展示安装或运行结果。\n4. page-tools-reference：工具参考。围绕“工具参考”模拟一次用户任务，不展示安装或运行结果。\n5. page-memory-operations：内存操作指南。围绕“内存操作指南”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-introduction\n输入：用户提供的“项目介绍”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-quickstart\n输入：用户提供的“快速开始”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-architecture\n输入：用户提供的“系统架构”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-tools-reference\n输入：用户提供的“工具参考”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-memory-operations\n输入：用户提供的“内存操作指南”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-introduction：Step 1 必须围绕“项目介绍”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-quickstart：Step 2 必须围绕“快速开始”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-architecture：Step 3 必须围绕“系统架构”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-tools-reference：Step 4 必须围绕“工具参考”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-memory-operations：Step 5 必须围绕“内存操作指南”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/dmang-dev/mcp-pine\n- https://github.com/dmang-dev/mcp-pine#readme\n- README.md\n- package.json\n- src/index.ts\n- src/pine.ts\n- src/tools.ts\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 mcp-pine 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "voices": [
        {
          "body": "来源平台：github。github/github_issue: Submit listing PR to punkpeye/awesome-mcp-servers（https://github.com/dmang-dev/mcp-pine/issues/2）；github/github_release: v0.3.0 — target-aware tool descriptions（https://github.com/dmang-dev/mcp-pine/releases/tag/v0.3.0）。这些是项目级外部声音，不作为单独质量证明。",
          "items": [
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Submit listing PR to punkpeye/awesome-mcp-servers",
              "url": "https://github.com/dmang-dev/mcp-pine/issues/2"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "v0.3.0 — target-aware tool descriptions",
              "url": "https://github.com/dmang-dev/mcp-pine/releases/tag/v0.3.0"
            }
          ],
          "status": "已收录 2 条来源",
          "title": "社区讨论"
        }
      ]
    },
    "homepage_card": {
      "category": "工具连接与集成",
      "desc": "MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control",
      "effort": "安装已验证",
      "forks": 0,
      "icon": "link",
      "name": "mcp-pine 能力包",
      "risk": "需复核",
      "slug": "mcp-pine",
      "stars": 0,
      "tags": [
        "MCP 工具",
        "工具接入扩展",
        "流程自动化",
        "节点式流程编排",
        "本地优先"
      ],
      "thumb": "gray",
      "type": "MCP 配置"
    },
    "manual": {
      "markdown": "# https://github.com/dmang-dev/mcp-pine 项目说明书\n\n生成时间：2026-05-17 20:22:23 UTC\n\n## 目录\n\n- [项目介绍](#page-introduction)\n- [快速开始](#page-quickstart)\n- [系统架构](#page-architecture)\n- [PINE 协议详解](#page-pine-protocol)\n- [工具参考](#page-tools-reference)\n- [内存操作指南](#page-memory-operations)\n- [存档状态管理](#page-savestate)\n- [安装指南](#page-installation)\n- [模拟器配置](#page-emulator-setup)\n- [配置参考](#page-configuration)\n- [使用范例](#page-recipes)\n- [故障排除](#page-troubleshooting)\n\n<a id='page-introduction'></a>\n\n## 项目介绍\n\n### 相关页面\n\n相关主题：[系统架构](#page-architecture), [快速开始](#page-quickstart)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 项目介绍\n\n## 概述\n\nmcp-pine 是一个基于 **Model Context Protocol (MCP)** 的桥接服务器，用于连接 MCP 客户端（如 Claude Code、Claude Desktop）与支持 PINE 协议的 PlayStation 系列模拟器。该项目使 AI 助手能够直接读取和写入模拟器内存、保存/加载游戏状态，从而实现自动化游戏调试、内存修改、状态快照实验等高级功能。\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 项目背景与目标\n\n在传统的游戏逆向工程和模拟器调试中，开发者需要手动使用调试工具或编写专用脚本与模拟器交互。mcp-pine 的出现旨在将这种能力抽象为一个标准化的 MCP 工具集，使 AI 助手能够：\n\n- 实时查询游戏运行状态和元数据\n- 读取任意内存地址的数据\n- 写入内存实现游戏修改（Cheats/Pokes）\n- 保存和恢复游戏快照\n- 执行自动化的内存搜索和结构解码\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 支持的模拟器\n\nmcp-pine 目前支持以下模拟器：\n\n| 模拟器 | 状态 | 说明 |\n|--------|------|------|\n| **PCSX2** | 完整支持 | 1.7.x Qt 或更高版本，支持 PINE Server |\n| **RPCS3** | 实验性支持 | 有独立的 IPC 实现，与 PINE 操作码兼容 |\n| **Duckstation** | 部分支持 | 取决于具体编译版本是否包含 PINE Server |\n\n对于 PCSX2，用户只需在 `Settings → Advanced → Enable PINE Server` 中启用即可，无需脚本或控制台命令。默认插槽为 **28011**。\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 系统架构\n\nmcp-pine 采用典型的客户端-服务器分层架构：\n\n```mermaid\ngraph TD\n    A[MCP 客户端<br/>Claude Code/Desktop] -->|MCP 协议<br/>stdio| B[mcp-pine<br/>桥接服务器]\n    B -->|PINE 协议<br/>Unix Socket| C[PCSX2 PINE Server]\n    B -->|PINE 协议<br/>TCP| D[RPCS3 IPC Server]\n    B -->|PINE 协议<br/>Socket| E[Duckstation PINE]\n    \n    F[EE 主内存<br/>0x00100000-0x01FFFFFF] --> C\n    G[IOP RAM<br/>0x1C000000+] --> C\n```\n\n### 核心组件\n\n| 组件 | 文件位置 | 职责 |\n|------|----------|------|\n| **PineClient** | `src/pine.ts` | 底层 PINE 协议通信，处理 socket 连接、请求队列、响应解析 |\n| **工具注册器** | `src/tools.ts` | 定义 MCP 工具 schema，实现工具调用路由 |\n| **入口点** | `src/index.ts` | MCP 服务器初始化，工具注册，stdin/stdout 管道 |\n\n资料来源：[src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)，[src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## MCP 工具集详解\n\nmcp-pine 提供以下 MCP 工具，分为四个类别：\n\n### 连接与自检\n\n| 工具名 | 功能描述 | 返回值 |\n|--------|----------|--------|\n| `pine_ping` | 检查与模拟器的连接，获取模拟器版本 | `OK — emulator: VERSION` |\n\n### 游戏信息查询\n\n| 工具名 | 功能描述 | 返回值示例 |\n|--------|----------|------------|\n| `pine_get_info` | 批量获取游戏元数据（标题、序列号、CRC、版本、状态） | `Title: GameName\\nSerial: SLUS-12345\\nDisc CRC: ABCD1234\\nGame version: 1.00\\nStatus: running` |\n| `pine_get_status` | 获取模拟器运行状态 | `Status: running/paused/shutdown/unknown` |\n\n### 内存读取\n\n| 工具名 | 数据宽度 | 对齐要求 | 说明 |\n|--------|----------|----------|------|\n| `pine_read8` | 8 位 | 无 | 单字节读取 |\n| `pine_read16` | 16 位 | 2 字节 | 小端序 |\n| `pine_read32` | 32 位 | 4 字节 | 小端序，用于指针、RGBA 颜色 |\n| `pine_read64` | 64 位 | 8 字节 | 完整 PS2 EE 指针、大 ID |\n| `pine_read_range` | 可变 | 自动选择最大对齐 | 批量读取最多 4096 字节 |\n\n### 内存写入\n\n| 工具名 | 数据宽度 | 对齐要求 | 风险提示 |\n|--------|----------|----------|----------|\n| `pine_write8` | 8 位 | 无 | 直接写入，无撤销 |\n| `pine_write16` | 16 位 | 2 字节 | 覆盖式写入，绕过 TLB |\n| `pine_write32` | 32 位 | 4 字节 | 32 位 Cheats/Pokes |\n| `pine_write64` | 64 位 | 8 字节 | 完整 64 位值写入 |\n\n### 状态管理\n\n| 工具名 | 功能描述 | 参数 |\n|--------|----------|------|\n| `pine_save_state` | 保存当前游戏状态到指定槽位 | `slot: 0-255` |\n| `pine_load_state` | 从指定槽位加载游戏状态 | `slot: 0-255` |\n\n资料来源：[src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## 配置与环境变量\n\nmcp-pine 通过环境变量进行配置：\n\n| 环境变量 | 默认值 | 用途 |\n|----------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 指定模拟器名称，用于 Unix socket 文件路径前缀 |\n| `PINE_SLOT` | `28011` | PINE 插槽号（Linux/macOS）或 TCP 端口（Windows） |\n| `PINE_PIPELINE_BATCH` | `1` | 批量请求数，控制性能与稳定性权衡 |\n\n### 连接路径说明\n\n| 操作系统 | 连接方式 | 路径格式 |\n|----------|----------|----------|\n| Linux | Unix Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>` 或 `$TMPDIR/<target>.sock.<slot>` 或 `/tmp/<target>.sock.<slot>` |\n| macOS | Unix Socket | 同 Linux |\n| Windows | TCP | `127.0.0.1:<slot>` |\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 安装与部署\n\n### 方式一：npm 全局安装\n\n```bash\nnpm install -g mcp-pine\n```\n\n### 方式二：npx 临时运行\n\n```bash\nnpx -y mcp-pine\n```\n\n### 方式三：源码开发\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install\n```\n\n### Claude Code 集成\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\n验证连接：\n\n```bash\nclaude mcp list\n# pine: mcp-pine - ✓ Connected\n```\n\n### Claude Desktop 集成\n\n编辑配置文件：\n\n| 平台 | 路径 |\n|------|------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 已知问题与限制\n\n### PCSX2 PINE 服务器脆弱性\n\nPCSX2 的 PINE 服务器请求队列非常脆弱。当有超过约 **6-7 个飞行中的请求**时，服务器会静默丢弃请求，导致回复管道失同步。一旦失同步，即使新的 `pine_ping` 也会超时，只能通过完全重启 PCSX2 恢复。\n\n**缓解措施**：\n- `pine_read_range` 默认以完全串行方式发出请求\n- 使用 `PINE_PIPELINE_BATCH=2` 或更高值可提升延迟，但有失同步风险\n\n### 内存访问注意事项\n\n| 问题 | 原因 | 解决方案 |\n|------|------|----------|\n| 读取返回零值 | 地址在未分配区域 | 尝试 `0x00100000`（几乎总在 EE RAM 内） |\n| 数值看起来损坏 | 对齐问题 | PINE 不强制对齐，未对齐的多字节读取会返回对齐地址下的数据 |\n| 字符串解析错误 | 字节序问题 | PINE 返回小端序，字符串应使用 `read_range` 按字节读取 |\n| 写入 IOP ROM 无效 | 只读区域 | BIOS、IOP ROM 区域写入会被静默丢弃 |\n\n### 性能基准\n\n| 操作 | 耗时 | 说明 |\n|------|------|------|\n| 完整 4096 字节读取 | ~52 ms | PCSX2 v2.6.3，loopback TCP |\n| 单次 `pine_ping` | <1 ms | 本地连接 |\n| 状态保存/加载 | 取决于存档大小 | 通过 PINE 协议传输 |\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)，[CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n## 项目依赖\n\nmcp-pine 的核心依赖非常精简：\n\n| 依赖 | 版本 | 用途 |\n|------|------|------|\n| `@modelcontextprotocol/sdk` | ^1.12.0 | MCP 协议 SDK，处理 stdio 通信 |\n\n开发依赖：\n\n| 依赖 | 版本 | 用途 |\n|------|------|------|\n| `typescript` | ^5.5.0 | TypeScript 编译 |\n| `@types/node` | ^22.0.0 | Node.js 类型定义 |\n\n资料来源：[package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n\n## 开发指南\n\n### 本地开发\n\n```bash\nnpm install\nnpm run dev      # tsc --watch 监听文件变化\n```\n\n### 冒烟测试\n\n在运行 PCSX2 并启用 PINE Server 后：\n\n```bash\nnode .scratch/smoke.cjs\n```\n\n### 相关项目\n\n- **[mcp-mgba](https://github.com/dmang-dev/mcp-mgba)** — 姐妹项目，支持 mGBA Game Boy Advance 模拟器，包含按钮输入和截图功能（mcp-pine 不支持）\n- **[PINE 协议规范](https://github.com/GovanifY/pine)** — 底层 IPC 标准文档\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 版本历史\n\n| 版本 | 日期 | 主要变更 |\n|------|------|----------|\n| 0.2.1 | 2026-05-15 | 工具描述质量改进，完整 TDQS 模板重构 |\n| 0.2.0 | 2026-05-10 | 新增 `pine_read_range`，10 秒超时，文档化 PCSX2 管道问题 |\n| 0.1.0 | 初始版本 | 基础 MCP 工具集 |\n\n资料来源：[CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n## 许可证\n\n本项目采用 **MIT** 许可证开源。\n\n---\n\n*最后更新：基于 mcp-pine 仓库当前主分支内容生成*\n\n---\n\n<a id='page-quickstart'></a>\n\n## 快速开始\n\n### 相关页面\n\n相关主题：[安装指南](#page-installation), [模拟器配置](#page-emulator-setup), [配置参考](#page-configuration)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [src/index.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/index.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n</details>\n\n# 快速开始\n\n本页面介绍如何快速部署和配置 **mcp-pine**，这是一个基于 Model Context Protocol (MCP) 的桥接工具，用于连接 Claude 等 AI 助手与支持 PINE 协议的模拟器（PCSX2、RPCS3、Duckstation），从而实现对 PlayStation 模拟器的内存读取、写入和状态管理。\n\n## 架构概览\n\n```mermaid\ngraph TD\n    subgraph \"MCP 客户端\"\n        A[Claude Desktop / Claude Code]\n    end\n    \n    subgraph \"mcp-pine 桥接层\"\n        B[MCP Server<br/>stdio 传输]\n        C[PINE Client<br/>网络通信]\n    end\n    \n    subgraph \"目标模拟器\"\n        D[PCSX2 / RPCS3 / Duckstation]\n        E[PINE Server]\n    end\n    \n    A -->|\"MCP 协议\"| B\n    B -->|\"工具调用\"| C\n    C -->|\"PINE 协议\"| E\n    E -->|\"游戏状态\"| D\n    \n    style B fill:#e1f5fe\n    style C fill:#fff3e0\n    style E fill:#f3e5f5\n```\n\n**工作原理**：mcp-pine 作为 MCP 服务器运行在 stdio 管道上，将 MCP 工具调用转换为 PINE 协议的二进制请求，通过 TCP 或 Unix 域套接字发送至模拟器的 PINE Server，从而实现对模拟器内存空间的读写操作。\n\n## 前置要求\n\n| 组件 | 要求 | 说明 |\n|------|------|------|\n| Node.js | ≥ 18.0.0 | 用于运行 mcp-pine |\n| 包管理器 | npm / npx | 安装和执行 |\n| 模拟器 | PCSX2 1.7.x+ / RPCS3 / Duckstation | 支持 PINE 协议 |\n| MCP 客户端 | Claude Desktop / Claude Code | AI 助手界面 |\n| 操作系统 | Windows / macOS / Linux | 跨平台支持 |\n\n## 安装方式\n\n### 方式一：全局安装（推荐）\n\n```bash\nnpm install -g mcp-pine\n```\n\n安装完成后，`mcp-pine` 命令将全局可用：\n\n```bash\nmcp-pine\n```\n\n资料来源：[README.md:安装方法]()\n\n### 方式二：npx 免安装运行\n\n如仅需临时使用，无需安装依赖：\n\n```bash\nnpx -y mcp-pine\n```\n\n资料来源：[README.md:npx 安装]()\n\n### 方式三：源码本地开发\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install        # 同时运行 build（prepare hook 触发）\n```\n\n开发模式热重载：\n\n```bash\nnpm run dev        # tsc --watch 监听源码变更\n```\n\n资料来源：[README.md:clone and develop]()\n\n## 环境变量配置\n\nmcp-pine 通过环境变量控制连接目标和通信方式：\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器标识名称，用于生成 Unix 套接字路径 `<target>.sock.<slot>` |\n| `PINE_SLOT` | `28011` | PINE 槽位/端口号 |\n| `PINE_HOST` | `127.0.0.1` | TCP 目标主机（Windows 默认使用 TCP） |\n| `PINE_SOCKET_PATH` | 自动解析 | Unix 套接字路径，优先级最高 |\n| `PINE_PIPELINE_BATCH` | `1` | 请求流水线批次大小，建议保持默认 |\n\n**跨平台套接字路径解析规则**：\n\n```mermaid\ngraph TD\n    A[启动 mcp-pine] --> B{操作系统?}\n    B -->|Windows| C[使用 TCP<br/>127.0.0.1:PINE_SLOT]\n    B -->|Linux/macOS| D[检查 XDG_RUNTIME_DIR]\n    D -->|存在| E[使用 $XDG_RUNTIME_DIR/<target>.sock.<slot>]\n    D -->|不存在| F[检查 TMPDIR]\n    F -->|存在| G[使用 $TMPDIR/<target>.sock.<slot>]\n    F -->|不存在| H[使用 /tmp/<target>.sock.<slot>]\n    \n    style C fill:#ffcdd2\n    style E fill:#c8e6c9\n    style G fill:#c8e6c9\n    style H fill:#c8e6c9\n```\n\n资料来源：[README.md:Configuration]()\n\n## 模拟器配置\n\n### PCSX2 设置\n\n1. 启动 PCSX2（1.7.x Qt 或更高版本）\n2. 进入 **Settings → Advanced**\n3. 启用 **Enable PINE Server** 选项\n4. 默认槽位为 **28011**（如需修改，记下新端口并设置 `PINE_SLOT`）\n5. 加载任意游戏\n\n> **注意**：无需脚本或控制台命令，PINE 启用后始终保持运行状态。\n\n资料来源：[README.md:PCSX2]()\n\n### RPCS3 设置\n\nRPCS3 实现了兼容 PINE 操作码的 IPC 机制，但线级兼容性尚未完全测试：\n\n1. 进入 **Configuration → Advanced**\n2. 启用 **IPC Server**（具体菜单位置请参考当前 RPCS3 文档）\n3. 记录配置的端口号\n4. 运行命令：\n\n```bash\nPINE_TARGET=rpcs3 PINE_SLOT=<端口号> mcp-pine\n```\n\n资料来源：[README.md:RPCS3]()\n\n### Duckstation 设置\n\n1. 确认 Duckstation 构建版本包含 PINE 服务器（并非所有版本都包含）\n2. 如包含，设置环境变量后运行：\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=<端口号> mcp-pine\n```\n\n资料来源：[README.md:Duckstation]()\n\n## MCP 客户端配置\n\n### Claude Code (CLI)\n\n添加 MCP 服务器：\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\n验证连接状态：\n\n```bash\nclaude mcp list\n# 输出示例：pine: mcp-pine - ✓ Connected\n```\n\n资料来源：[README.md:Claude Code (CLI)]()\n\n### Claude Desktop\n\n编辑配置文件 `claude_desktop_config.json`：\n\n| 平台 | 配置文件路径 |\n|------|--------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n添加服务器配置：\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\n修改配置后需重启 Claude Desktop。\n\n资料来源：[README.md:Claude Desktop]()\n\n### 其他 MCP 客户端\n\nmcp-pine 使用标准 MCP over stdio 协议，可连接任何兼容 MCP 的客户端：\n\n```bash\nmcp-pine    # 直接运行，stdin/stdout 用于通信\n```\n\n## 可用工具一览\n\n连接成功后，以下 MCP 工具将自动注册到客户端：\n\n| 工具名称 | 功能描述 | 用途场景 |\n|----------|----------|----------|\n| `pine_ping` | 获取模拟器版本 | 连接验证 |\n| `pine_get_info` | 获取游戏完整信息 | 游戏识别 |\n| `pine_get_status` | 获取运行状态 | 状态监控 |\n| `pine_read8/16/32/64` | 读取指定地址内存 | 内存读取 |\n| `pine_write8/16/32/64` | 写入指定地址内存 | 内存修改 |\n| `pine_read_range` | 批量读取内存区域 | 大块数据读取 |\n| `pine_save_state` | 保存游戏状态 | 存档快照 |\n| `pine_load_state` | 加载游戏状态 | 恢复存档 |\n\n**地址参数说明**：\n- 地址为 EE 主地址空间的绝对字节地址\n- 多字节访问需对齐（`read16` 需 2 字节对齐，`read32` 需 4 字节对齐）\n- 推荐范围：`0x00100000-0x01FFFFFF`（EE 主内存，99% 游戏状态所在区域）\n- 未映射地址返回 PINE FAIL 响应\n\n资料来源：[src/tools.ts:工具定义]()\n\n## 快速验证流程\n\n```mermaid\nsequenceDiagram\n    participant User as 用户\n    participant MCP as Claude MCP\n    participant Bridge as mcp-pine\n    participant Emu as PCSX2\n\n    User->>Emu: 1. 启动 PCSX2 并启用 PINE Server\n    User->>MCP: 2. 配置并启动 Claude Desktop\n    MCP->>Bridge: 3. 启动 mcp-pine 进程\n    Bridge->>Emu: 4. 建立 PINE 连接\n    User->>MCP: 5. 调用 pine_ping\n    MCP->>Bridge: 6. 转发工具调用\n    Bridge->>Emu: 7. PINE Version 请求\n    Emu-->>Bridge: 8. 返回版本信息\n    Bridge-->>MCP: 9. 返回工具结果\n    MCP-->>User: 10. 显示 \"OK — emulator: PCSX2 v2.x.x\"\n```\n\n首次使用建议按以下顺序测试：\n\n```bash\n# 步骤 1：验证连接\npine_ping\n# 预期输出：OK — emulator: PCSX2 v2.x.x\n\n# 步骤 2：获取游戏信息\npine_get_info\n# 预期输出：Title, Serial, Disc CRC, Game version, Status\n\n# 步骤 3：读取内存（示例：EE RAM 起始地址）\npine_read32 address=0x00100000\n# 预期输出：ADDR_HEX: VAL_DEC (0xVAL_HEX)\n\n# 步骤 4：保存当前状态\npine_save_state slot=0\n# 预期输出：State saved to slot 0\n\n# 步骤 5：测试写入（谨慎操作）\npine_write32 address=0x00100000 value=0\n# 预期输出：Wrote 0 → ADDR_HEX\n```\n\n## 常见问题排查\n\n| 问题现象 | 原因 | 解决方案 |\n|----------|------|----------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 | 检查 `PINE_SLOT` 配置 |\n| `PINE FAIL response (0xFF)` | 模拟器拒绝请求（无游戏加载、地址未映射） | 加载游戏、检查地址有效性 |\n| 读取返回全零 | 地址在未分配区域 | 尝试 `0x00100000`（几乎总是 EE RAM 内部） |\n| 数值看起来损坏 | 字节序错误 | PINE 返回小端序，字符串读取使用 `read_range` |\n| `pine_ping` 超时（10s） | PCSX2 PINE 服务器卡死 | 完全重启 PCSX2（重新连接无效） |\n\n**重要提示**：PCSX2 的 PINE 服务器请求队列较脆弱，当超过约 6 个飞行中请求时会静默丢弃请求，导致回复错位与错误客户端配对。一旦卡死，只能通过完全重启模拟器恢复。mcp-pine 默认使用完全串行请求（`PINE_PIPELINE_BATCH=1`），实测 Loopback TCP 速度足够（4096 字节读取约 52ms）。\n\n资料来源：[README.md:Troubleshooting]()\n\n## 下一步\n\n- 阅读 [工具详细文档](./工具详细文档.md)，了解每个工具的完整参数说明\n- 参考 [内存狩猎指南](./内存狩猎指南.md)，学习定位游戏状态地址\n- 查看 [架构设计](./架构设计.md)，深入理解 PINE 协议实现\n\n---\n\n<a id='page-architecture'></a>\n\n## 系统架构\n\n### 相关页面\n\n相关主题：[PINE 协议详解](#page-pine-protocol), [工具参考](#page-tools-reference)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/index.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/index.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 系统架构\n\n## 1. 概述\n\nmcp-pine 是一个基于 Model Context Protocol (MCP) 的桥接服务器，用于连接 MCP 客户端（如 Claude Desktop、Claude Code）与游戏模拟器的 PINE (Programmable Interface for Networked Emulation) 协议接口。\n\n该项目的核心功能是让 AI 助手能够通过标准化的 MCP 工具接口与运行中的模拟器进行交互，实现内存读取、内存写入、保存/加载游戏状态等操作。资料来源：[README.md]()\n\n## 2. 整体架构\n\nmcp-pine 采用分层架构设计，从上到下依次为：\n\n| 层级 | 组件 | 职责 |\n|------|------|------|\n| MCP 协议层 | MCP Server | 暴露标准化的工具接口，处理 MCP 协议的请求/响应 |\n| 工具定义层 | Tools Registry | 定义所有可用的 MCP 工具及其参数模式 |\n| PINE 客户端层 | PineClient | 实现 PINE 协议的二进制通信 |\n| 传输层 | Socket/TCP | 处理底层网络通信，支持 Unix Domain Socket 和 TCP |\n\n```mermaid\ngraph TD\n    A[MCP 客户端<br/>Claude Desktop/Code] -->|stdio| B[MCP Server]\n    B -->|工具调用| C[Tools Registry]\n    C -->|调用方法| D[PineClient]\n    D -->|TCP/Unix Socket| E[模拟器 PINE Server]\n    \n    F[src/index.ts] --> B\n    G[src/tools.ts] --> C\n    H[src/pine.ts] --> D\n```\n\n资料来源：[src/index.ts:1-50]()\n\n## 3. 核心组件\n\n### 3.1 MCP Server\n\nMCP Server 是整个应用的入口点，负责初始化和启动服务。\n\n```typescript\n// src/index.ts 核心逻辑\nconst server = new Server(\n  { name: \"mcp-pine\", version: \"0.2.0\" },\n  { capabilities: { tools: {} } },\n);\n\nregisterTools(server, pine);\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n```\n\n关键特性：\n- 使用 `@modelcontextprotocol/sdk` 包提供的 Server 类\n- 通过 StdioServerTransport 实现标准输入/输出通信\n- 仅声明 `tools` 能力，不使用资源或提示功能\n- 工具注册由 `registerTools()` 函数完成\n\n资料来源：[src/index.ts:20-35]()\n\n### 3.2 PineClient\n\nPineClient 是 PINE 协议的客户端实现，负责与模拟器的 PINE 服务器进行二进制通信。\n\n**主要职责：**\n\n| 功能 | 方法 | 说明 |\n|------|------|------|\n| 连接管理 | `connect()` | 建立 TCP 或 Unix Socket 连接 |\n| 内存读取 | `read8/16/32/64()` | 按指定宽度读取内存 |\n| 内存写入 | `write8/16/32/64()` | 按指定宽度写入内存 |\n| 批量读取 | `readRange()` | 连续内存区域读取 |\n| 状态管理 | `saveState()` / `loadState()` | 保存/加载游戏状态 |\n| 信息查询 | `getVersion/Tittle/Id/Uuid/Status()` | 获取模拟器和游戏信息 |\n\n**连接传输方式：**\n\n```typescript\n// Unix Domain Socket (Linux/macOS)\nnet.createConnection({ path: this.descriptor.path })\n\n// TCP 连接 (Windows)\nnet.createConnection({ host: this.descriptor.host, port: this.descriptor.port })\n```\n\n资料来源：[src/pine.ts:60-90]()\n\n### 3.3 工具注册系统\n\n工具系统基于 TOOLS 数组定义，每个工具包含完整的元数据：\n\n```typescript\nconst TOOLS: Tool[] = [\n  {\n    name: \"pine_ping\",\n    description: \"PURPOSE: ...\",\n    inputSchema: { ... }\n  },\n  // ... 其他工具\n];\n```\n\n工具处理流程：\n\n```mermaid\ngraph LR\n    A[MCP 请求] -->|name + arguments| B[switch 语句]\n    B -->|匹配工具名| C[执行 PineClient 方法]\n    C -->|结果| D[ok() 格式化]\n    D -->|{content: [...]} | E[MCP 响应]\n```\n\n资料来源：[src/tools.ts:80-150]()\n\n## 4. 通信协议\n\n### 4.1 PINE Wire Protocol\n\nPINE 协议采用二进制格式，消息结构如下：\n\n| 字段 | 大小 | 字节序 | 说明 |\n|------|------|--------|------|\n| Size | 4 字节 | Little-endian | 消息总长度 |\n| Opcode | 1 字节 | - | 操作码 |\n| Payload | N 字节 | Little-endian | 操作数据 |\n\n**Opcode 定义：**\n\n| 操作码 | 值 | 功能 |\n|--------|-----|------|\n| Version | 0x01 | 获取模拟器版本 |\n| Title | 0x02 | 获取游戏标题 |\n| ID | 0x03 | 获取游戏序列号 |\n| UUID | 0x04 | 获取光盘 CRC |\n| GameVersion | 0x05 | 获取游戏版本 |\n| Status | 0x06 | 获取运行状态 |\n| Read8 | 0x10 | 读取 8 位 |\n| Read16 | 0x11 | 读取 16 位 |\n| Read32 | 0x12 | 读取 32 位 |\n| Read64 | 0x13 | 读取 64 位 |\n| Write8 | 0x14 | 写入 8 位 |\n| Write16 | 0x15 | 写入 16 位 |\n| Write32 | 0x16 | 写入 32 位 |\n| Write64 | 0x17 | 写入 64 位 |\n| SaveState | 0x30 | 保存状态 |\n| LoadState | 0x31 | 加载状态 |\n\n资料来源：[src/pine.ts:1-50]()\n\n### 4.2 请求队列管理\n\nPineClient 内部维护一个待处理请求队列：\n\n```typescript\ninterface Pending {\n  size: number;\n  resolve: (data: Buffer) => void;\n  reject: (err: Error) => void;\n}\n```\n\n接收数据时的帧解析流程：\n\n```mermaid\ngraph TD\n    A[接收数据 chunk] --> B[追加到 buffer]\n    B --> C{buffer.length >= 4?}\n    C -->|否| F[等待更多数据]\n    C -->|是| D[读取 size 字段]\n    D --> E{buffer.length >= size?}\n    E -->|否| F\n    E -->|是| G[提取完整帧]\n    G --> H[出队匹配]\n    H --> I[resolve/reject]\n    I --> B\n```\n\n每个请求包含 10 秒超时，超时后自动 reject，防止请求永久挂起。资料来源：[src/pine.ts:100-140]()\n\n### 4.3 批量读取实现\n\n`readRange()` 方法实现了高效的批量内存读取：\n\n```mermaid\ngraph TD\n    A[输入: 地址 + 长度] --> B[计算最优分块]\n    B --> C{地址对齐检查}\n    C -->|8字节对齐| D[使用 read64]\n    C -->|4字节对齐| E[使用 read32]\n    C -->|2字节对齐| F[使用 read16]\n    C -->|其他| G[使用 read8]\n    D --> H[按 PIPELINE_BATCH 分批]\n    E --> H\n    F --> H\n    G --> H\n    H --> I[Promise.all 并行]\n    I --> J[合并结果到 Buffer]\n    J --> K[返回字节数组]\n```\n\n**关键参数：**\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| `PINE_PIPELINE_BATCH` | 1 | 每批并发请求数 |\n\n默认完全串行执行以避免 PCSX2 PINE 服务器请求队列丢失问题。资料来源：[src/pine.ts:180-240]()\n\n## 5. 配置系统\n\n### 5.1 环境变量配置\n\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，用于 Unix socket 文件路径前缀 |\n| `PINE_SLOT` | `28011` | PINE 槽位号/端口号 |\n| `PINE_HOST` | `127.0.0.1` | TCP 主机地址 |\n| `PINE_SOCKET_PATH` | - | 自定义 Unix socket 路径 |\n| `PINE_PIPELINE_BATCH` | 1 | 批量读取并发数 |\n\n### 5.2 Socket 路径解析\n\n```mermaid\ngraph TD\n    A[resolveSocket] --> B{平台判断}\n    B -->|Windows| C[TCP: 127.0.0.1:PINE_SLOT]\n    B -->|Linux/macOS| D{检查 PINE_SOCKET_PATH}\n    D -->|已设置| E[使用自定义路径]\n    D -->|未设置| F{检查 XDG_RUNTIME_DIR}\n    F -->|已设置| G[使用 $XDG_RUNTIME_DIR/<target>.sock.<slot>]\n    F -->|未设置| H[使用 /tmp/<target>.sock.<slot>]\n```\n\n资料来源：[src/pine.ts:50-80]()\n\n## 6. MCP 工具清单\n\n### 6.1 连接与信息工具\n\n| 工具名 | 功能 | 返回值示例 |\n|--------|------|-----------|\n| `pine_ping` | 检测连接，获取模拟器版本 | `OK — emulator: PCSX2 2.6.3` |\n| `pine_get_info` | 获取完整游戏信息 | 标题、序列号、CRC、版本、状态 |\n| `pine_get_status` | 获取运行状态 | `Status: running` |\n\n### 6.2 内存读写工具\n\n| 工具名 | 操作数 | 对齐要求 | 说明 |\n|--------|--------|----------|------|\n| `pine_read8` | 1 字节 | 无 | 读取字节 |\n| `pine_read16` | 2 字节 | 2 字节 | 读取 16 位整数 |\n| `pine_read32` | 4 字节 | 4 字节 | 读取 32 位整数 |\n| `pine_read64` | 8 字节 | 8 字节 | 读取 64 位整数 |\n| `pine_write8` | 1 字节 | 无 | 写入字节 |\n| `pine_write16` | 2 字节 | 2 字节 | 写入 16 位整数 |\n| `pine_write32` | 4 字节 | 4 字节 | 写入 32 位整数 |\n| `pine_write64` | 8 字节 | 8 字节 | 写入 64 位整数 |\n| `pine_read_range` | 1-4096 字节 | 自动适配 | 批量读取内存区域 |\n\n### 6.3 状态管理工具\n\n| 工具名 | 参数 | 说明 |\n|--------|------|------|\n| `pine_save_state` | `slot: 0-255` | 保存游戏状态到指定槽位 |\n| `pine_load_state` | `slot: 0-255` | 从指定槽位加载游戏状态 |\n\n资料来源：[src/tools.ts:150-300]()\n\n## 7. 错误处理\n\n### 7.1 已知错误模式\n\n| 错误类型 | 表现 | 原因与处理 |\n|----------|------|-----------|\n| `Cannot reach PINE server` | 连接失败 | 模拟器未运行或 PINE 未启用 |\n| `PINE FAIL response (0xFF)` | 请求被拒绝 | 无游戏加载或地址未映射 |\n| 读取返回零值 | 返回 0x0 | 地址在未分配内存区域 |\n| 值损坏 | 数据异常 | 字节序或对齐问题 |\n| `PINE call timed out (10s)` | 超时 | PCSX2 PINE 服务器请求队列错位，需完全重启模拟器 |\n\n### 7.2 PCSX2 PINE 服务器限制\n\nPCSX2 的 PINE 服务器存在已知的请求队列脆弱性问题：\n\n- 约 7-9 个在途请求时开始出现丢包\n- 丢包后服务器回复管道永久错位\n- 任何后续请求都会超时\n- 仅重启模拟器可恢复\n\n资料来源：[README.md:60-80]()\n\n## 8. 数据模型\n\n### 8.1 模拟器状态枚举\n\n```typescript\ntype EmuStatus = \"running\" | \"paused\" | \"shutdown\" | \"unknown\";\n```\n\n状态值映射：\n\n| 原始值 | 枚举值 | 含义 |\n|--------|--------|------|\n| 0 | `running` | 游戏正在运行 |\n| 1 | `paused` | 游戏已暂停 |\n| 2 | `shutdown` | 模拟器已关闭 |\n| 其他 | `unknown` | 未知状态 |\n\n### 8.2 64 位值处理\n\n由于 JavaScript Number 类型精度限制（最大安全整数 2^53），64 位值通过字符串格式传输：\n\n```typescript\n// 返回值格式\n\"12345678901234567890 (0xB54A3E8F9A4D6E2)\"\n\n// 使用 BigInt 内部处理\nconst n = v as bigint;\nfor (let j = 0; j < 8; j++) {\n  out[off + j] = Number((n >> BigInt(8 * j)) & 0xFFn);\n}\n```\n\n资料来源：[src/pine.ts:200-220]()\n\n## 9. 依赖关系\n\n```mermaid\ngraph TD\n    A[package.json] --> B[dependencies]\n    A --> C[devDependencies]\n    \n    B --> D[\"@modelcontextprotocol/sdk ^1.12.0\"]\n    \n    C --> E[\"@types/node ^22.0.0\"]\n    C --> F[\"typescript ^5.5.0\"]\n```\n\n项目使用 TypeScript 开发，通过 `npm run dev` 启动监听模式进行开发调试。资料来源：[package.json:10-20]()\n\n## 10. 总结\n\nmcp-pine 的架构设计体现了几个关键原则：\n\n1. **分层解耦**：MCP 协议层、工具定义层、PINE 客户端层完全分离\n2. **传输透明**：根据平台自动选择 TCP 或 Unix Domain Socket\n3. **安全优先**：默认串行请求避免模拟器 PINE 服务丢包\n4. **跨平台兼容**：Windows/Linux/macOS 全平台支持\n5. **超时保护**：10 秒超时防止请求永久挂起\n\n---\n\n<a id='page-pine-protocol'></a>\n\n## PINE 协议详解\n\n### 相关页面\n\n相关主题：[系统架构](#page-architecture), [模拟器配置](#page-emulator-setup)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# PINE 协议详解\n\n## 1. 概述\n\nPINE（PlayStation Interactive Network Emulator）是一种用于 PlayStation 系列模拟器的进程间通信（IPC）协议。它允许外部工具直接读取和写入模拟器进程的内存空间，实现游戏状态检查、作弊修改、存档管理等高级功能。\n\nmcp-pine 项目是一个 PINE 协议的 MCP（Model Context Protocol）服务端实现，使 AI 助手（如 Claude）能够通过标准化的工具接口与运行中的模拟器交互。\n\n### 1.1 支持的模拟器\n\n| 模拟器 | 协议实现 | 连接方式 | 备注 |\n|--------|----------|----------|------|\n| PCSX2 | 原生 PINE | Unix Socket / TCP | 推荐使用 v1.7.x 及以上版本 |\n| RPCS3 | 镜像 PINE | TCP | 兼容性未完全测试 |\n| Duckstation | 原生 PINE | Unix Socket / TCP | 部分构建版本支持 |\n\n资料来源：[README.md:1-50]()\n\n## 2. 架构设计\n\n### 2.1 系统架构图\n\n```mermaid\ngraph TB\n    subgraph \"主机系统\"\n        A[Claude / MCP 客户端] --> B[mcp-pine 服务端]\n        B --> C[PineClient]\n        C --> D{连接类型}\n        D -->|Linux/macOS| E[Unix Socket]\n        D -->|Windows| F[TCP 127.0.0.1]\n    end\n    \n    subgraph \"模拟器进程\"\n        E --> G[PCSX2 PINE Server]\n        F --> G\n    end\n    \n    G --> H[EE 主内存 0x00100000-0x01FFFFFF]\n    G --> I[IOP 内存 0x1C000000+]\n    G --> J[Scratchpad]\n```\n\n### 2.2 核心组件\n\n**PineClient** 是协议的核心实现类，负责：\n\n- 底层的 Socket 连接管理\n- PINE 操作码的发送与响应解析\n- 读写请求的批量处理\n- 超时控制与错误处理\n\n资料来源：[src/pine.ts:60-100]()\n\n## 3. PINE 操作码定义\n\n### 3.1 操作码表\n\n| 操作码名称 | 数值 | 功能描述 | 返回类型 |\n|------------|------|----------|----------|\n| `Op.Version` | 0x01 | 获取模拟器版本 | UTF-8 字符串 |\n| `Op.Title` | 0x02 | 获取游戏标题 | UTF-8 字符串 |\n| `Op.ID` | 0x03 | 获取游戏序列号 | UTF-8 字符串 |\n| `Op.UUID` | 0x04 | 获取光盘 CRC | UTF-8 字符串 |\n| `Op.GameVersion` | 0x05 | 获取游戏版本 | UTF-8 字符串 |\n| `Op.Status` | 0x0F | 获取模拟器运行状态 | 32 位整数 |\n| `Op.SaveState` | 0x10 | 保存当前状态到指定槽位 | 无 |\n| `Op.LoadState` | 0x11 | 从指定槽位加载状态 | 无 |\n| `Op.Read8` | 0x20 | 读取 8 位数据 | 字节 |\n| `Op.Read16` | 0x21 | 读取 16 位数据 | 小端整数 |\n| `Op.Read32` | 0x22 | 读取 32 位数据 | 小端整数 |\n| `Op.Read64` | 0x23 | 读取 64 位数据 | 小端整数 |\n| `Op.Write8` | 0x30 | 写入 8 位数据 | 无 |\n| `Op.Write16` | 0x31 | 写入 16 位数据 | 无 |\n| `Op.Write32` | 0x32 | 写入 32 位数据 | 无 |\n| `Op.Write64` | 0x33 | 写入 64 位数据 | 无 |\n\n资料来源：[src/pine.ts:1-30]()\n\n### 3.2 状态码定义\n\n模拟器运行状态通过 32 位小端整数返回：\n\n| 状态值 | 含义 |\n|--------|------|\n| 0 | 运行中 (running) |\n| 1 | 暂停 (paused) |\n| 2 | 已关闭 (shutdown) |\n| 其他 | 未知 (unknown) |\n\n资料来源：[src/pine.ts:40-45]()\n\n## 4. 协议帧格式\n\n### 4.1 请求帧结构\n\n```\n+----------------+----------------+----------------+\n|  Frame Size    |  Opcode (1B)   |  Arguments...  |\n|  (UInt32 LE)   |                |                |\n+----------------+----------------+----------------+\n```\n\n- **Frame Size**: 4 字节，小端无符号整数，表示整个帧的字节数（包括自身）\n- **Opcode**: 1 字节，操作码标识符\n- **Arguments**: 可选参数数据\n\n### 4.2 响应帧结构\n\n```\n+----------------+----------------+----------------+\n|  Frame Size    |  Status (1B)   |  Payload...    |\n|  (UInt32 LE)   |  0x00=OK 0xFF=FAIL              |\n+----------------+----------------+----------------+\n```\n\n- **Status**: `0x00` 表示成功，`0xFF` 表示失败\n- **Payload**: 成功时包含返回数据，失败时可能为空\n\n### 4.3 帧解析流程\n\n```mermaid\ngraph TD\n    A[接收数据块] --> B{缓冲区长度 >= 4?}\n    B -->|否| C[等待更多数据]\n    B -->|是| D[读取 Frame Size]\n    D --> E{缓冲区长度 >= Frame Size?}\n    E -->|否| F[等待更多数据]\n    E -->|是| G[提取完整帧]\n    G --> H[解析 Status 字节]\n    H --> I{Status == 0x00?}\n    I -->|是| J[解析 Payload]\n    I -->|否| K[抛出 PINE FAIL 错误]\n    J --> L[匹配 Pending 请求]\n    K --> L\n    L --> M[返回结果给调用者]\n```\n\n资料来源：[src/pine.ts:100-150]()\n\n## 5. 连接管理\n\n### 5.1 连接参数\n\n| 参数 | 环境变量 | 默认值 | 说明 |\n|------|----------|--------|------|\n| 模拟器名称 | `PINE_TARGET` | `pcsx2` | Unix Socket 文件名前缀 |\n| 槽位/端口 | `PINE_SLOT` | `28011` | Unix Socket 序号或 TCP 端口 |\n\n### 5.2 连接路径解析\n\n```typescript\n// Linux/macOS: Unix Socket\n$XDG_RUNTIME_DIR/<target>.sock.<slot>\n$TMPDIR/<target>.sock.<slot>\n/tmp/<target>.sock.<slot>\n\n// Windows: TCP\n127.0.0.1:<slot>\n```\n\n资料来源：[src/pine.ts:50-80]()\n\n### 5.3 超时控制\n\n每个 PINE 调用都设置了 **10 秒超时**。如果模拟器未响应，请求将自动拒绝，防止无限等待。\n\n资料来源：[CHANGELOG.md:30-40]()\n\n## 6. 内存读写机制\n\n### 6.1 地址空间\n\nPS2 模拟器的主要内存区域：\n\n| 区域 | 地址范围 | 大小 | 说明 |\n|------|----------|------|------|\n| EE 主内存 | 0x00100000 - 0x01FFFFFF | ~31 MB | 游戏状态主要存储区 |\n| IOP 内存 | 0x1C000000+ | 可变 | I/O 处理器内存 |\n| Scratchpad | 特定区域 | 较小 | 高速缓存 |\n\n资料来源：[src/tools.ts:20-30]()\n\n### 6.2 数据编码\n\n所有多字节数据均使用 **小端序**（Little Endian）编码：\n\n```\n地址:     [0x00] [0x01] [0x02] [0x03]\n数据:     LSB    ...    ...    MSB\n```\n\n字符串使用 **UTF-8 编码**，以空字符 (`\\0`) 结尾，读取时自动去除尾部空字符。\n\n资料来源：[src/pine.ts:25-35]()\n\n### 6.3 对齐要求\n\n| 操作宽度 | 对齐要求 | 未对齐时的行为 |\n|----------|----------|----------------|\n| 8 位 | 无 | 正常工作 |\n| 16 位 | 2 字节对齐 | 返回对齐地址下方的数据，静默损坏 |\n| 32 位 | 4 字节对齐 | 返回对齐地址下方的数据，静默损坏 |\n| 64 位 | 8 字节对齐 | 返回对齐地址下方的数据，静默损坏 |\n\n**重要警告**: PCSX2 的 PINE 服务端**不强制**对齐访问，未对齐的地址会静默返回错误数据而无任何错误提示。\n\n资料来源：[src/tools.ts:30-45]()\n\n### 6.4 批量读取实现\n\n由于 PINE 协议本身不提供原生批量读取功能，`read_range` 工具通过客户端实现的序列读取实现：\n\n```mermaid\ngraph LR\n    A[请求: 4096 字节] --> B{计算最优步长}\n    B --> C[起始地址 % 8 == 0 且剩余 >= 8?]\n    C -->|是| D[read64]\n    C -->|否| E{起始地址 % 4 == 0 且剩余 >= 4?}\n    E -->|是| F[read32]\n    E -->|否| G{起始地址 % 2 == 0?}\n    G -->|是| H[read16]\n    G -->|否| I[read8]\n    D --> J[移动游标]\n    F --> J\n    H --> J\n    I --> J\n    J --> K{还有剩余?}\n    K -->|是| B\n    K -->|否| L[组装 Buffer 返回]\n```\n\n资料来源：[src/pine.ts:50-80]()\n\n## 7. PCSX2 已知限制\n\n### 7.1 请求队列脆弱性\n\nPCSX2 的 PINE 服务端存在一个关键缺陷：\n\n- 当 **同时发送约 7-9 个未完成请求**时，服务端可能静默丢弃某些请求\n- 一旦发生请求丢失，响应管道将与客户端失去同步\n- 之后**所有**请求都会超时，包括 `pine_ping`\n- **唯一恢复方法**: 完全重启 PCSX2\n\n### 7.2 性能数据\n\n| 操作 | 耗时 | 说明 |\n|------|------|------|\n| 单次 read64 | ~0.1 ms | 单次往返延迟 |\n| 完整 4096 字节读取 | ~52 ms | 串行执行，约两帧 |\n\n### 7.3 流水线配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_PIPELINE_BATCH` | 1 | 每批发送的请求数，增大可降低延迟但有同步风险 |\n\n资料来源：[CHANGELOG.md:40-60]()\n\n## 8. 错误处理\n\n### 8.1 错误类型\n\n| 错误现象 | 可能原因 | 解决方案 |\n|----------|----------|----------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 | 检查 `PINE_SLOT` 设置 |\n| `PINE FAIL response (0xFF)` | 无游戏加载、地址未映射 | 确认游戏已加载，尝试 0x00100000 |\n| 读取返回全零 | 地址在未分配区域 | 尝试 EE 主内存起始地址 |\n| 数据看起来损坏 | 字节序误解 | PINE 返回小端序 |\n| `PINE call timed out (10s)` | PCSX2 队列同步失败 | 完全重启 PCSX2 |\n\n资料来源：[README.md:80-100]()\n\n## 9. API 参考\n\n### 9.1 核心方法签名\n\n```typescript\nclass PineClient {\n  // 元数据查询\n  async getVersion(): Promise<string>\n  async getTitle(): Promise<string>\n  async getId(): Promise<string>\n  async getUuid(): Promise<string>\n  async getGameVersion(): Promise<string>\n  async getStatus(): Promise<EmuStatus>\n\n  // 内存读取\n  async read8(addr: number): Promise<number>\n  async read16(addr: number): Promise<number>\n  async read32(addr: number): Promise<number>\n  async read64(addr: number): Promise<bigint>\n  async readRange(addr: number, length: number): Promise<Buffer>\n\n  // 内存写入\n  async write8(addr: number, value: number): Promise<void>\n  async write16(addr: number, value: number): Promise<void>\n  async write32(addr: number, value: number): Promise<void>\n  async write64(addr: number, value: bigint): Promise<void>\n\n  // 存档管理\n  async saveState(slot: number): Promise<void>\n  async loadState(slot: number): Promise<void>\n}\n```\n\n### 9.2 64 位值处理\n\n由于 JavaScript 的 `number` 类型只能安全表示 2^53 以内的整数，`read64` 和 `write64` 方法使用 `bigint` 类型：\n\n```typescript\n// 读取\nconst value: bigint = await pine.read64(0x12345678)\n\n// 写入\nawait pine.write64(0x12345678, 12345678901234n)\n```\n\n资料来源：[src/pine.ts:40-50]()\n\n## 10. 与 MCP 工具的映射\n\n| MCP 工具名称 | 底层 PINE 操作 | 功能 |\n|--------------|----------------|------|\n| `pine_ping` | Version | 连接测试 |\n| `pine_get_info` | Title + ID + UUID + GameVersion + Status | 批量获取游戏信息 |\n| `pine_get_status` | Status | 获取运行状态 |\n| `pine_read8/16/32/64` | Read8/16/32/64 | 单值读取 |\n| `pine_read_range` | 串行调用 Read* | 批量读取 |\n| `pine_write8/16/32/64` | Write8/16/32/64 | 单值写入 |\n| `pine_save_state` | SaveState | 保存存档 |\n| `pine_load_state` | LoadState | 加载存档 |\n\n资料来源：[src/tools.ts:100-200]()\n\n## 11. 项目信息\n\n| 项目元数据 | 值 |\n|------------|-----|\n| 项目名称 | mcp-pine |\n| 许可证 | MIT |\n| 主要依赖 | @modelcontextprotocol/sdk ^1.12.0 |\n| 运行时 | Node.js / TypeScript |\n\n资料来源：[package.json:1-30]()\n\n---\n\n<a id='page-tools-reference'></a>\n\n## 工具参考\n\n### 相关页面\n\n相关主题：[内存操作指南](#page-memory-operations), [存档状态管理](#page-savestate)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n</details>\n\n# 工具参考\n\nmcp-pine 提供了一套完整的 MCP 工具，用于与支持 PINE（Platform Independent Network Environment）协议的模拟器进行交互通信。通过这些工具，用户可以实现对模拟器运行状态的监控、内存读写操作以及存档管理等功能。\n\n## 工具分类概览\n\nmcp-pine 的工具集按照功能可分为四大类别：\n\n| 类别 | 工具数量 | 用途 |\n|------|----------|------|\n| 连接与自检 | 2 | 连接验证、模拟器信息获取 |\n| 内存读取 | 5 | 单字节到64位值的读取，支持范围读取 |\n| 内存写入 | 4 | 8/16/32/64位值写入 |\n| 存档管理 | 2 | 游戏状态保存与加载 |\n\n资料来源：[src/tools.ts:90-140]()\n\n## 连接与自检工具\n\n### pine_ping\n\n**用途**：验证与模拟器 PINE 服务器的连接状态，并获取模拟器版本信息。\n\n**参数**：无\n\n**返回格式**：`OK — emulator: <version>`\n\n**使用场景**：在执行其他操作前验证连接是否正常。如果返回\"Cannot reach PINE server\"错误，表明模拟器未运行、PINE 未启用或端口配置不匹配。资料来源：[src/tools.ts:95-98]()\n\n### pine_get_info\n\n**用途**：获取当前运行游戏的完整信息摘要，包括游戏标题、序列号、Disc CRC、游戏版本和运行状态。\n\n**参数**：无\n\n**返回格式**：\n\n```\nTitle:        <游戏标题>\nSerial:       <序列号>\nDisc CRC:     <CRC校验值>\nGame version: <游戏版本>\nStatus:       <运行状态>\n```\n\n**使用场景**：快速确认当前加载的游戏及其状态，适用于多游戏环境下的上下文切换。资料来源：[src/tools.ts:100-115]()\n\n### pine_get_status\n\n**用途**：获取模拟器当前的运行状态。\n\n**参数**：无\n\n**返回格式**：`Status: <running|paused|shutdown|unknown>`\n\n**使用场景**：在执行存档操作前确认游戏状态，或监控长时间运行任务的状态变化。资料来源：[src/tools.ts:117-119]()\n\n## 内存读取工具\n\n所有内存读取工具均操作 PS2 主机的 EE（Emotion Engine）主地址空间，采用小端字节序。地址参数支持十六进制字面量（如 `0x00200000`）。\n\n### 地址参数通用说明\n\n| 字段 | 描述 |\n|------|------|\n| 有效范围 | `0x00100000-0x01FFFFFF`（EE 主 RAM，99%的游戏状态在此区域）|\n| 对齐要求 | 多字节访问必须按对应字节数对齐；PCSX2 的 PINE 不强制对齐，未对齐访问会静默返回损坏数据 |\n| 错误处理 | 未映射或无效地址返回 PINE FAIL 响应 |\n\n> **重要**：如果需要读取未对齐的多字节数据，应使用 `pine_read_range` 并自行组装字节。\n\n资料来源：[src/tools.ts:30-50]()\n\n### pine_read8\n\n**用途**：读取单个字节。\n\n**对齐要求**：无对齐要求。\n\n**返回格式**：`ADDR_HEX: VAL_DEC (0xVAL_HEX)`\n\n### pine_read16\n\n**用途**：读取16位无符号小端值，适用于字符编码、游戏事件标志等。\n\n**对齐要求**：2字节对齐。\n\n**返回格式**：与 `pine_read8` 格式相同。\n\n### pine_read32\n\n**用途**：读取32位无符号小端值，适用于 PS2 指针、计时器、分数等常见游戏状态字段。\n\n**对齐要求**：4字节对齐。\n\n**返回格式**：与 `pine_read8` 格式相同。\n\n### pine_read64\n\n**用途**：读取64位无符号值，适用于完整的 PS2 指针、大型 ID、压缩双字状态。PS2 EE 是128位 MIPS 处理器，大量游戏状态确实存在于64位槽位中。\n\n**对齐要求**：8字节对齐。\n\n**返回值说明**：由于 JavaScript 无法精确表示超过 2^53 的整数，64位值以十进制字符串形式返回。资料来源：[src/tools.ts:120-145]()\n\n### pine_read_range\n\n**用途**：批量读取最多4096字节的连续内存区域。\n\n**参数**：\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| address | integer | 起始地址 |\n| length | integer | 要读取的字节数（最大4096）|\n\n**实现原理**：PINE 协议本身没有原生批量读取功能，`pine_read_range` 在客户端通过序列化调用序列实现。每次调用选择最大对齐宽度（从8到1递减）。资料来源：[src/pine.ts:90-130]()\n\n**性能指标**：\n\n- 完整4096字节读取耗时约52毫秒（PCSX2 v2.6.3，loopback TCP）\n- 少于两个模拟帧，适合大多数工作负载\n\n**注意事项**：PCSX2 的 PINE 服务器存在请求队列脆弱性问题。超过约7个飞行中请求时会静默丢弃请求，导致回复管道错位，后续所有请求超时，直至模拟器重启。因此默认情况下调用完全序列化执行。可通过环境变量 `PINE_PIPELINE_BATCH` 调整批处理大小（默认为1）。资料来源：[src/pine.ts:95-110]()\n\n## 内存写入工具\n\n所有写入工具均具有破坏性，会覆盖指定地址的现有数据。\n\n### pine_write8 / pine_write16 / pine_write32 / pine_write64\n\n**用途**：向模拟器内存写入指定宽度的值。\n\n**参数**：\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| address | integer | 目标地址（必须符合对应宽度对齐要求）|\n| value | integer/bigint | 要写入的值 |\n\n**返回格式**：`Wrote VAL_HEX → ADDR_HEX`\n\n**对齐要求**：与对应的读取工具相同。未对齐写入可能导致静默数据损坏。\n\n**错误场景**：\n\n- 地址未对齐：数据写入错误位置\n- 地址未映射：PINE FAIL 响应\n- 写入只读区域：行为取决于模拟器实现\n\n资料来源：[src/tools.ts:145-170]()\n\n## 存档管理工具\n\n### pine_save_state\n\n**用途**：将当前游戏状态保存到指定槽位。\n\n**参数**：\n\n| 参数 | 类型 | 范围 | 描述 |\n|------|------|------|------|\n| slot | integer | 0-255 | 存档槽位编号 |\n\n**槽位约定**：PCSX2 图形界面通常使用 F1-F10 对应槽位0-9，但 PINE 协议支持完整的 0-255 范围。存档文件存储在模拟器的游戏专属目录中：\n\n- Windows：`%USERPROFILE%\\Documents\\PCSX2\\sstates`\n- Linux/macOS：`~/.config/PCSX2/sstates`\n\n**文件命名格式**：`<serial> (<crc>).<slot>.p2s`\n\n**警告**：保存到已有存档的槽位会覆盖原有数据，此操作不可逆。资料来源：[src/tools.ts:70-85]()\n\n### pine_load_state\n\n**用途**：从指定槽位加载游戏状态。\n\n**参数**：与 `pine_save_state` 相同。\n\n**返回格式**：`Loaded state from slot <n>`\n\n**使用场景**：快速恢复之前的游戏进度，适用于：\n\n- 尝试不同游戏决策前的快照\n- 回归测试\n- 调试时的状态重现\n\n**前置条件**：需要先加载对应游戏的 ISO 文件，否则存档可能不兼容。\n\n## 工具调用流程\n\n以下流程图展示了典型工具调用序列的执行路径：\n\n```mermaid\ngraph TD\n    A[MCP 客户端发起调用] --> B{工具类型}\n    \n    B -->|查询类<br/>ping/get_info/get_status| C[构建请求帧]\n    B -->|读取类<br/>read8/16/32/64/range| C\n    B -->|写入类<br/>write8/16/32/64| C\n    B -->|存档类<br/>save/load_state| C\n    \n    C --> D[加入待处理队列]\n    D --> E[PINE 协议编码]\n    E --> F{连接状态}\n    \n    F -->|已连接| G[发送请求]\n    F -->|未连接| H[建立连接<br/>TCP Unix Socket]\n    H --> G\n    \n    G --> I{等待响应}\n    I -->|超时 10s| J[抛出错误]\n    I -->|收到响应| K{响应码}\n    \n    K -->|成功 0x00| L[解码响应]\n    K -->|失败 0xFF| M[返回 PINE FAIL]\n    \n    L --> N[返回格式化结果]\n    M --> O[错误处理]\n```\n\n## 环境变量配置\n\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器标识名，用于 Unix socket 文件路径前缀（Linux/macOS）或 TCP 连接标识 |\n| `PINE_SLOT` | `28011` | PINE 槽位/端口号 |\n| `PINE_HOST` | `127.0.0.1` | TCP 连接主机地址 |\n| `PINE_SOCKET_PATH` | 自动解析 | Unix socket 路径，覆盖其他 socket 相关配置 |\n| `PINE_PIPELINE_BATCH` | `1` | 批量请求数量，仅在了解 PCSX2 PINE 限制时调整 |\n\n**Socket 路径解析逻辑**（Linux/macOS）：\n\n1. 优先使用 `XDG_RUNTIME_DIR`\n2. 其次尝试 `TMPDIR`\n3. 最后回退到 `/tmp`\n\n资料来源：[README.md:40-55]()\n\n## 错误处理与故障排除\n\n| 错误现象 | 可能原因 | 解决方案 |\n|----------|----------|----------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 | 检查 `PINE_SLOT` 配置，确认模拟器设置中已启用 PINE |\n| `PINE FAIL response` (0xFF) | 未加载游戏或地址未映射 | 确保游戏已加载，尝试地址 `0x00100000` |\n| 读取返回全零 | 地址在未分配区域 | 从 EE RAM 常用区域开始（`0x00100000`）|\n| 值看起来损坏 | 字节序误解 | PINE 返回小端序；字符串使用 `read_range` 逐字节读取 |\n| `PINE call timed out (10s)` ping 后频繁使用 | PCSX2 PINE 请求队列错位 | 完全重启 PCSX2（仅重新连接无效）|\n\n### PCSX2 PINE 服务器已知限制\n\nPCSX2 的 PINE 服务器存在一个已知的脆弱性问题：当飞行中请求超过约6个时，服务器会静默丢弃请求，导致回复管道错位。一旦发生这种情况，即使 `pine_ping` 也会超时，唯一恢复方法是完全重启模拟器。\n\n为避免此问题：\n\n- 默认情况下 `mcp-pine` 完全序列化所有请求\n- Loopback TCP 速度足够快，完整4KB读取仅需约52毫秒\n- 如需更低延迟且可容忍偶发的模拟器重启，可设置 `PINE_PIPELINE_BATCH=2` 或更高\n\n资料来源：[src/pine.ts:95-110]()\n\n## 工具描述质量标准\n\nmcp-pine 的每个工具描述都遵循 Glama 的工具定义质量评分（TDQS）标准，确保以下方面完整：\n\n1. **目的明确性**：每个工具一句话说明其操作\n2. **使用指南**：何时使用此工具而非其兄弟工具\n3. **行为透明**：副作用、错误条件、破坏性操作说明\n4. **参数语义**：超出 JSON Schema 的上下文信息\n5. **简洁性**：无冗余描述\n6. **上下文完整性**：错误模式、对齐要求、返回值格式\n\n资料来源：[CHANGELOG.md:20-35]()\n\n## 快速参考表\n\n| 工具名 | 参数 | 返回类型 | 破坏性 |\n|--------|------|----------|--------|\n| `pine_ping` | - | string | 否 |\n| `pine_get_info` | - | string | 否 |\n| `pine_get_status` | - | string | 否 |\n| `pine_read8` | address | string | 否 |\n| `pine_read16` | address | string | 否 |\n| `pine_read32` | address | string | 否 |\n| `pine_read64` | address | string | 否 |\n| `pine_read_range` | address, length | string | 否 |\n| `pine_write8` | address, value | string | 是 |\n| `pine_write16` | address, value | string | 是 |\n| `pine_write32` | address, value | string | 是 |\n| `pine_write64` | address, value | string | 是 |\n| `pine_save_state` | slot | string | 是 |\n| `pine_load_state` | slot | string | 是 |\n\n---\n\n<a id='page-memory-operations'></a>\n\n## 内存操作指南\n\n### 相关页面\n\n相关主题：[工具参考](#page-tools-reference), [使用范例](#page-recipes)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 内存操作指南\n\n## 概述\n\nmcp-pine 提供的核心功能之一是通过 PINE（PlayStation Interface for Networked Entertainment）协议对运行中的模拟器进行实时内存读写操作。该功能允许用户直接访问 PS2/PS3/PSP 等平台的内存地址空间，实现游戏状态检测、作弊修改、运行时数据分析等高级操作。\n\n内存操作由 8 个 MCP 工具组成，分为**读取**和**写入**两大类：\n\n| 类别 | 工具 | 数据宽度 |\n|------|------|----------|\n| 读取 | `pine_read8` | 1 字节 |\n| 读取 | `pine_read16` | 2 字节 |\n| 读取 | `pine_read32` | 4 字节 |\n| 读取 | `pine_read64` | 8 字节 |\n| 读取 | `pine_read_range` | 批量（最大 4096 字节） |\n| 写入 | `pine_write8` | 1 字节 |\n| 写入 | `pine_write16` | 2 字节 |\n| 写入 | `pine_write32` | 4 字节 |\n| 写入 | `pine_write64` | 8 字节 |\n\n资料来源：[src/tools.ts:56-130]()\n\n## 地址空间与内存布局\n\n### PS2 EE 主内存\n\nPS2 的 Emotion Engine（EE）主内存地址空间是最常用的访问区域：\n\n| 地址范围 | 说明 |\n|----------|------|\n| `0x00100000` - `0x01FFFFFF` | EE 主 RAM（游戏状态主要存储区） |\n| `0x1C000000`+ | IOP RAM（声音/输入子系统） |\n| 其他 | 预留/映射区域 |\n\n> 💡 建议从 `0x00100000` 开始探测，该地址几乎所有游戏都会加载到 EE RAM 中。\n\n资料来源：[src/tools.ts:20-25]()\n\n### 连接传输方式\n\n| 平台 | 传输方式 | 地址格式 |\n|------|----------|----------|\n| Linux/macOS | Unix Domain Socket | `$XDG_RUNTIME_DIR/<PINE_TARGET>.sock.<PINE_SLOT>` |\n| Windows | TCP | `127.0.0.1:<PINE_SLOT>` |\n\n资料来源：[README.md:45-50]()\n\n## 读取操作\n\n### 单值读取工具\n\n| 工具 | 对齐要求 | 返回格式 |\n|------|----------|----------|\n| `pine_read8` | 无 | `ADDR: VAL_DEC (0xVAL_HEX)` |\n| `pine_read16` | 2 字节对齐 | `ADDR: VAL_DEC (0xVAL_HEX)` |\n| `pine_read32` | 4 字节对齐 | `ADDR: VAL_DEC (0xVAL_HEX)` |\n| `pine_read64` | 8 字节对齐 | 字符串格式（JS 无法原生表示完整 u64） |\n\n#### 64 位值处理\n\n由于 JavaScript Number 类型最大只能精确表示到 `2^53`，`pine_read64` 和 `pine_write64` 采用**十进制字符串**作为值编码，避免精度丢失。\n\n```typescript\n// 资料来源：src/pine.ts:55-60\nasync read64(addr: number): Promise<bigint> {\n  const r = await this.call(Op.Read64, this._addr(addr));\n  return r.readBigUInt64LE(0);\n}\n```\n\n资料来源：[src/tools.ts:100-105]()\n\n### 批量读取：pine_read_range\n\n`pine_read_range` 是最高效的批量读取工具，单次调用最多读取 4096 字节：\n\n```typescript\n// 资料来源：src/pine.ts:75-95\nasync readRange(start: number, length: number): Promise<Buffer> {\n  // 计算最优读取步骤：优先使用最大对齐宽度\n  let n: 1 | 2 | 4 | 8;\n  if      (cursor % 8 === 0 && remaining >= 8) n = 8;\n  else if (cursor % 4 === 0 && remaining >= 4) n = 4;\n  else if (cursor % 2 === 0 && remaining >= 2) n = 2;\n  else                                          n = 1;\n}\n```\n\n#### 读取策略\n\n工具内部采用**自适应分块策略**，在每个步骤选择最大可用对齐宽度：\n\n```mermaid\ngraph TD\n    A[开始读取] --> B{地址 % 8 === 0 ?}\n    B -->|是 且 剩余 ≥ 8| C[read64 - 8字节]\n    B -->|否| D{地址 % 4 === 0 ?}\n    D -->|是 且 剩余 ≥ 4| E[read32 - 4字节]\n    D -->|否| F{地址 % 2 === 0 ?}\n    F -->|是 且 剩余 ≥ 2| G[read16 - 2字节]\n    F -->|否| H[read8 - 1字节]\n    C --> I[移动指针]\n    E --> I\n    G --> I\n    H --> I\n    I --> J{还有数据?}\n    J -->|是| B\n    J -->|否| K[组装结果 Buffer]\n```\n\n#### 流水线控制\n\nPINE 协议本身**没有原生批量读取指令**，`pine_read_range` 通过发送多个单次读取请求实现。默认配置为**完全串行**执行以避免 PCSX2 请求队列错位：\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_PIPELINE_BATCH` | `1` | 每批发送请求数；`1` = 完全串行（安全） |\n\n> ⚠️ PCSX2 的 PINE 服务器存在已知缺陷：当流水线中有约 7-9 个请求时，会静默丢弃请求，导致后续所有回复与客户端错位，此时即使 `pine_ping` 也会超时，只能重启模拟器恢复。\n\n实测性能（PCSX2 v2.6.3，localhost）：\n\n| 操作 | 耗时 |\n|------|------|\n| 完整 4096 字节读取 | ~52 ms |\n| 单次 read32 | ~0.1 ms |\n\n资料来源：[src/pine.ts:100-115]()\n\n## 写入操作\n\n### 写入工具\n\n| 工具 | 对齐要求 | 参数类型 |\n|------|----------|----------|\n| `pine_write8` | 无 | `number` |\n| `pine_write16` | 2 字节对齐 | `number` |\n| `pine_write32` | 4 字节对齐 | `number` |\n| `pine_write64` | 8 字节对齐 | `number`（JS 会损失精度，模拟器端可能截断） |\n\n> ⚠️ **破坏性操作**：写入会直接修改游戏内存，可能导致游戏崩溃或存档损坏。\n\n```typescript\n// 资料来源：src/tools.ts:62-70\ncase \"pine_write8\": {\n  await pine.write8(addr(), p.value as number);\n  return ok(`Wrote ${fmtHex(p.value as number)} → ${addrHex(addr())}`);\n}\n```\n\n## 对齐要求与边界处理\n\n### PCSX2 对齐特性\n\n**关键警告**：PCSX2 的 PINE 实现**不强制对齐检查**。对未对齐地址的多字节访问会静默返回对齐地址的数据，造成数据损坏。\n\n| 访问宽度 | 对齐要求 | 错误行为 |\n|----------|----------|----------|\n| 8 位 (read8/write8) | 无 | 无 |\n| 16 位 (read16/write16) | 地址 % 2 === 0 | 未对齐时返回对齐地址数据 |\n| 32 位 (read32/write32) | 地址 % 4 === 0 | 未对齐时返回对齐地址数据 |\n| 64 位 (read64/write64) | 地址 % 8 === 0 | 未对齐时返回对齐地址数据 |\n\n### 未对齐访问方案\n\n如需读取未对齐地址的数据，建议：\n\n1. 使用 `pine_read_range` 读取足够宽的字节范围\n2. 在客户端自行组装字节序\n\n```typescript\n// 示例：读取未对齐的 32 位值\nconst bytes = await pine.readRange(0x00102001, 4);  // 从 0x00102000 开始读 4 字节\nconst value = bytes.readUInt32LE(1);  // 从偏移 1 开始解释\n```\n\n资料来源：[src/tools.ts:10-20]()\n\n## 字节序\n\nPINE 协议使用 **小端序（Little-Endian）** 编码多字节值：\n\n- LSB 存储在起始地址\n- MSB 存储在起始地址 + 宽度 - 1\n\n```mermaid\ngraph LR\n    subgraph \"32 位值 0x12345678 在地址 0x00100000\"\n        A0[\"0x00100000: 0x78 (LSB)\"]\n        A1[\"0x00100001: 0x56\"]\n        A2[\"0x00100002: 0x34\"]\n        A3[\"0x00100003: 0x78 (MSB)\"]\n    end\n```\n\n> 💡 字符串读取（`getTitle`、`getId` 等）使用 UTF-8 编码，通过 `readString` 方法处理截断空字节。\n\n资料来源：[src/pine.ts:35-40]()\n\n## 超时与错误处理\n\n### 超时机制\n\n每个 PINE 调用都有 **10 秒超时**。超时后抛出 `PINE call timed out` 错误：\n\n```\n原因：\n1. 模拟器未运行\n2. PINE 服务器未启用（PCSX2: Settings → Advanced → Enable PINE Server）\n3. PINE_SLOT 与模拟器配置不匹配\n4. PCSX2 PINE 请求队列错位（需重启模拟器）\n```\n\n资料来源：[README.md:70-80]()\n\n### 常见错误\n\n| 错误信息 | 原因 | 解决方案 |\n|----------|------|----------|\n| `Cannot reach PINE server` | 连接失败 | 检查模拟器运行状态和 PINE_SLOT |\n| `PINE FAIL response (0xFF)` | 地址无映射或无游戏加载 | 确认游戏已加载，使用 `0x00100000` 探测 |\n| 返回全零 | 地址未分配 | 尝试 `0x00100000` |\n| 数据异常 | 字节序误判或对齐错误 | 检查对齐，使用 `read_range` 手动组装 |\n\n## 完整使用流程\n\n```mermaid\ngraph TD\n    A[启动模拟器] --> B[启用 PINE 服务器]\n    B --> C[运行 mcp-pine]\n    C --> D[调用 pine_ping 验证连接]\n    D --> E{连接成功?}\n    E -->|否| F[检查配置和模拟器状态]\n    F --> B\n    E -->|是| G[调用 pine_get_info 获取游戏信息]\n    G --> H[选择目标地址]\n    H --> I[调用 read/write 工具]\n    I --> J{操作成功?}\n    J -->|否| K[检查对齐/地址/超时]\n    K --> I\n    J -->|是| L[处理返回值]\n```\n\n## 工具调用示例\n\n### 读取玩家分数（假设在 0x00201000）\n\n```\n工具: pine_read32\n参数: { \"address\": 2113536 }\n返回值: \"0x00201000: 9500 (0x0000251c)\"\n```\n\n### 批量扫描内存\n\n```\n工具: pine_read_range\n参数: { \"address\": 1048576, \"length\": 4096 }\n返回值: <Buffer: 4096 bytes>\n```\n\n### 修改生命值\n\n```\n工具: pine_write32\n参数: { \"address\": 2097152, \"value\": 999 }\n返回值: \"Wrote 0x000003e7 → 0x00200000\"\n```\n\n## 环境变量配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称前缀（socket 文件名） |\n| `PINE_SLOT` | `28011` | PINE 槽位号（Linux/macOS 为 socket 后缀，Windows 为 TCP 端口） |\n| `PINE_HOST` | `127.0.0.1` | 主机地址（可覆盖） |\n| `PINE_SOCKET_PATH` | 自动 | 完整 socket 路径（完全覆盖自动解析） |\n| `PINE_PIPELINE_BATCH` | `1` | 批量请求数（建议仅在非 PCSX2 模拟器上增加） |\n\n资料来源：[README.md:45-55]()\n\n## 安全注意事项\n\n1. **写入操作不可逆**：修改内存会导致游戏状态永久改变，可能造成存档损坏\n2. **不要过度流水线**：PCSX2 在超过 ~6 个并行请求时会静默失败\n3. **定期保存状态**：使用 `pine_save_state` 在修改前备份当前游戏状态\n4. **验证对齐**：未对齐写入会产生静默数据损坏\n\n## 相关工具\n\n| 工具 | 功能 |\n|------|------|\n| `pine_ping` | 验证连接（会话开始时调用） |\n| `pine_get_info` | 获取游戏元数据（标题、序列号、CRC） |\n| `pine_get_status` | 获取运行状态（running/paused/shutdown） |\n| `pine_save_state` | 保存当前游戏状态到槽位 |\n| `pine_load_state` | 从槽位加载游戏状态 |\n\n---\n\n*最后更新：基于 mcp-pine v0.2.1*\n\n---\n\n<a id='page-savestate'></a>\n\n## 存档状态管理\n\n### 相关页面\n\n相关主题：[工具参考](#page-tools-reference), [使用范例](#page-recipes)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 存档状态管理\n\n## 概述\n\n存档状态管理（Save State Management）是 mcp-pine 项目为 PlayStation 2/3 模拟器提供的核心功能之一。该模块通过 PINE（Plugin Interface for Networked Emulation）协议实现模拟器内存状态的保存与恢复，允许 MCP 客户端在不中断游戏进程的情况下快速保存和加载游戏进度。\n\nmcp-pine 暴露了两个主要工具：\n\n| 工具名称 | 功能 |\n|---------|------|\n| `pine_save_state` | 将当前模拟器状态保存到指定槽位 |\n| `pine_load_state` | 从指定槽位加载模拟器状态 |\n\n资料来源：[src/tools.ts:工具定义区域]()\n\n## 系统架构\n\n### 组件层次\n\n```\n┌─────────────────────────────────────────────┐\n│           MCP 客户端 (Claude Code)          │\n└─────────────────────┬───────────────────────┘\n                      │ 标准 MCP 协议 (stdio)\n┌─────────────────────▼───────────────────────┐\n│              mcp-pine 桥接服务               │\n│  ┌─────────────────────────────────────┐    │\n│  │        tools.ts - 工具定义层        │    │\n│  │  • pine_save_state                  │    │\n│  │  • pine_load_state                  │    │\n│  └──────────────┬──────────────────────┘    │\n│  ┌──────────────▼──────────────────────┐    │\n│  │      pine.ts - PINE 客户端实现       │    │\n│  │  • saveState(slot)                  │    │\n│  │  • loadState(slot)                  │    │\n│  └──────────────┬──────────────────────┘    │\n└─────────────────┼───────────────────────────┘\n                  │ TCP / Unix Socket\n┌─────────────────▼───────────────────────────┐\n│           模拟器 PINE 服务器                 │\n│  • PCSX2 (Qt 版本 ≥ 1.7.x)                 │\n│  • RPCS3 (IPC 服务器)                       │\n│  • Duckstation (部分版本)                   │\n└─────────────────────────────────────────────┘\n```\n\n### 数据流\n\n```mermaid\nsequenceDiagram\n    participant Client as MCP 客户端\n    participant Bridge as mcp-pine 桥接\n    participant Pine as PINE 服务器\n    participant Emu as 模拟器核心\n\n    Client->>Bridge: pine_save_state { slot: 5 }\n    Bridge->>Pine: Op.SaveState (0x09) + slot=5\n    Pine->>Emu: 触发状态保存\n    Emu-->>Pine: 保存完成确认\n    Pine-->>Bridge: PINE 回复帧\n    Bridge-->>Client: \"Saved state → Slot 5\"\n\n    Client->>Bridge: pine_load_state { slot: 5 }\n    Bridge->>Pine: Op.LoadState (0x0A) + slot=5\n    Pine->>Emu: 触发状态加载\n    Emu-->>Pine: 加载完成确认\n    Pine-->>Bridge: PINE 回复帧\n    Bridge-->>Client: \"Loaded state from Slot 5\"\n```\n\n## API 实现\n\n### PineClient 类方法\n\n`src/pine.ts` 中定义了 `PineClient` 类的两个核心异步方法：\n\n```typescript\nasync saveState(slot: number): Promise<void> {\n  const args = Buffer.alloc(1); args.writeUInt8(slot, 0);\n  await this.call(Op.SaveState, args);\n}\n\nasync loadState(slot: number): Promise<void> {\n  const args = Buffer.alloc(1); args.writeUInt8(slot, 0);\n  await this.call(Op.LoadState, args);\n}\n```\n\n**参数说明：**\n\n| 参数 | 类型 | 范围 | 说明 |\n|------|------|------|------|\n| `slot` | `number` | 0-255 | 存档槽位编号 |\n\n**协议细节：**\n\n- 槽位参数写入 1 字节 Buffer\n- 使用 `Op.SaveState`（0x09）和 `Op.LoadState`（0x0A）操作码\n- 调用通过 `this.call()` 统一请求方法，携带 10 秒超时\n- 返回 `void`，操作成功时静默完成\n\n资料来源：[src/pine.ts:saveState方法定义]()\n\n### 协议层交互\n\n```mermaid\ngraph LR\n    A[saveState/loadState] --> B[构造 1 字节参数 Buffer]\n    B --> C[call Op.SaveState/Op.LoadState]\n    C --> D{请求发送}\n    D -->|成功| E[PINE 服务器处理]\n    E --> F[模拟器核心执行]\n    F --> G[返回确认帧]\n    D -->|超时| H[抛出 TimeoutError]\n    G --> I[解析响应 - void]\n```\n\n## 工具定义\n\n### pine_save_state\n\n```json\n{\n  \"name\": \"pine_save_state\",\n  \"description\": \"PURPOSE: Save the current emulator memory and execution state to a numbered slot...\\nBEHAVIOR: DESTRUCTIVE: overwrites any existing state in the target slot without prompting...\",\n  \"inputSchema\": {\n    \"type\": \"object\",\n    \"required\": [\"slot\"],\n    \"properties\": {\n      \"slot\": {\n        \"type\": \"integer\",\n        \"minimum\": 0,\n        \"maximum\": 255,\n        \"description\": \"Save state slot number (0-255)...\"\n      }\n    }\n  }\n}\n```\n\n**用途说明：**\n\n- 保存当前模拟器的完整运行状态到指定槽位\n- 包括 CPU 寄存器、内存快照、硬件状态等\n- 覆盖操作不可逆，无确认提示\n\n### pine_load_state\n\n```json\n{\n  \"name\": \"pine_load_state\",\n  \"description\": \"PURPOSE: Load and restore the emulator to a previously saved state in the given slot...\",\n  \"inputSchema\": {\n    \"type\": \"object\",\n    \"required\": [\"slot\"],\n    \"properties\": {\n      \"slot\": {\n        \"type\": \"integer\",\n        \"minimum\": 0,\n        \"maximum\": 255,\n        \"description\": \"Save state slot number (0-255)...\"\n      }\n    }\n  }\n}\n```\n\n**用途说明：**\n\n- 从指定槽位恢复之前保存的模拟器状态\n- 加载后模拟器立即进入加载的运行状态\n- 不存在的槽位会返回 PINE FAIL 响应\n\n资料来源：[src/tools.ts:工具定义完整内容]()\n\n## 槽位系统\n\n### 槽位编号规范\n\n| 槽位范围 | 典型用途 | 说明 |\n|---------|---------|------|\n| 0-9 | 快捷键映射 | PCSX2 GUI 中 F1-F10 对应槽位 0-9 |\n| 10-99 | 常规存档 | 用户手动保存位置 |\n| 100-255 | 扩展槽位 | 自动化脚本、批量实验使用 |\n\n### 存档文件位置\n\n| 平台 | 路径 |\n|------|------|\n| Windows | `%USERPROFILE%\\Documents\\PCSX2\\sstates` |\n| Linux | `~/.config/PCSX2/sstates` |\n| macOS | `~/.config/PCSX2/sstates` |\n\n**文件名格式：**\n\n```\n<游戏序列号> (<Disc CRC>).<slot>.p2s\n```\n\n例如：`SLUS-21274 (ABCD1234).5.p2s` 表示序列号为 SLUS-21274、CRC 为 ABCD1234 的游戏存档在第 5 槽位。\n\n资料来源：[src/tools.ts:SLOT_PARAM_DESC常量定义]()\n\n## 配置参数\n\n存档状态管理涉及以下环境变量配置：\n\n| 环境变量 | 默认值 | 说明 |\n|---------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，用于 Unix socket 文件路径前缀 |\n| `PINE_SLOT` | `28011` | PINE 通信槽位/端口号 |\n\n### 连接配置差异\n\n| 平台 | 连接方式 | 地址格式 |\n|------|---------|---------|\n| Linux/macOS | Unix Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>`，回退到 `$TMPDIR` 或 `/tmp` |\n| Windows | TCP | `127.0.0.1:<slot>` |\n\n## 工作流程示例\n\n### 基础保存-加载循环\n\n```mermaid\ngraph TD\n    A[启动模拟器] --> B[加载游戏]\n    B --> C[正常游戏]\n    C --> D[关键时刻]\n    D --> E[pine_save_state slot=5]\n    E --> F[继续游戏]\n    F --> G[出错/想重来]\n    G --> H[pine_load_state slot=5]\n    H --> I[恢复到存档点]\n    I --> F\n```\n\n### 自动化实验工作流\n\n```\n1. pine_get_info          # 确认当前游戏\n2. pine_save_state 0      # 保存基准状态\n3. [执行多次实验]\n   3a. 修改内存\n   3b. 测试假设\n   3c. pine_load_state 0  # 快速重置到基准\n4. pine_save_state 99    # 最终保存\n```\n\n## 已知问题与限制\n\n### PCSX2 PINE 服务器稳定性\n\n根据项目发现并记录的问题：\n\n| 问题 | 原因 | 解决方式 |\n|------|------|---------|\n| 请求队列脆弱 | PINE 服务器对过多请求处理不稳定 | 限制并发请求数量 |\n| 请求丢失静默 | 服务器丢弃请求时不报错 | 重启模拟器恢复 |\n| 超时后状态不一致 | 错误响应与正确响应混淆 | 确保单一请求链 |\n\n资料来源：[CHANGELOG.md:PCSX2 pipeline drop bug说明]()\n\n### 常见错误响应\n\n| 错误信息 | 可能原因 |\n|---------|---------|\n| `PINE FAIL response (0xFF)` | 游戏未加载、地址无映射、槽位不存在 |\n| `PINE call timed out (10s)` | 服务器无响应或队列错位 |\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 |\n\n## 与其他工具的配合\n\n存档状态管理通常与以下工具配合使用：\n\n| 工具 | 配合场景 |\n|------|---------|\n| `pine_get_info` | 保存前确认游戏和 CRC |\n| `pine_get_status` | 加载前确认模拟器状态 |\n| `pine_read_*` | 分析内存结构，决定保存时机 |\n| `pine_write_*` | 修改状态后保存为实验快照 |\n\n## 技术规格\n\n| 规格项 | 值 |\n|-------|-----|\n| 槽位范围 | 0-255（16 位无符号） |\n| 单次调用超时 | 10 秒 |\n| 协议操作码 | SaveState=0x09, LoadState=0x0A |\n| 参数编码 | 单字节小端序 |\n\n资料来源：[src/pine.ts:协议操作码定义]()\n\n## 总结\n\nmcp-pine 的存档状态管理模块通过 PINE 协议与模拟器深度集成，提供了简洁但功能完整的保存/加载接口。开发者可以通过 MCP 客户端在 Claude Code 等工具中直接调用 `pine_save_state` 和 `pine_load_state`，实现自动化测试、内存分析、实验回溯等工作流程。\n\n---\n\n<a id='page-installation'></a>\n\n## 安装指南\n\n### 相关页面\n\n相关主题：[快速开始](#page-quickstart), [配置参考](#page-configuration)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [src/index.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/index.ts)\n</details>\n\n# 安装指南\n\n## 概述\n\nmcp-pine 是一个基于 Model Context Protocol (MCP) 的服务器工具，用于连接 PlayStation 模拟器（PCSX2、RPCS3、Duckstation）的 PINE IPC 接口。通过该工具，AI 助手（如 Claude）可以直接与运行中的模拟器交互，执行内存读取、写入、保存状态等操作。\n\n本指南涵盖三种安装方式、MCP 客户端配置以及各模拟器的 PINE 服务启用步骤。\n\n---\n\n## 前置要求\n\n| 组件 | 版本要求 | 说明 |\n|------|----------|------|\n| Node.js | ≥ 22.0.0 | npm 包管理器内置 |\n| npm | 最新版 | 用于安装 mcp-pine |\n| PlayStation 模拟器 | 参见下方 | PCSX2 1.7.x Qt 或更高版本推荐 |\n\n资料来源：[package.json:24-26]()\n\n---\n\n## 安装方式\n\n### 方式一：npm 全局安装（推荐）\n\n```bash\nnpm install -g mcp-pine\n```\n\n全局安装后，`mcp-pine` 命令可直接在终端运行。\n\n资料来源：[README.md:40]()\n\n### 方式二：npx 免安装运行\n\n```bash\nnpx -y mcp-pine\n```\n\nnpx 会临时下载并执行包，无需本地安装，适合一次性使用场景。\n\n资料来源：[README.md:43-45]()\n\n### 方式三：源码克隆开发\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install        # 同时运行 build（通过 prepare hook）\n```\n\n适用于需要修改代码或参与开发的场景。\n\n资料来源：[README.md:47-51]()\n\n---\n\n## MCP 客户端配置\n\nmcp-pine 通过标准 stdio 协议与 MCP 客户端通信。以下是各平台的配置方法。\n\n### Claude Code (CLI)\n\n添加 MCP 服务器到用户级配置：\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\n验证连接状态：\n\n```bash\nclaude mcp list\n# 输出示例: pine: mcp-pine - ✓ Connected\n```\n\n资料来源：[README.md:13-19]()\n\n### Claude Desktop\n\n编辑配置文件 `claude_desktop_config.json`，路径因平台而异：\n\n| 平台 | 配置文件路径 |\n|------|-------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n在 `mcpServers` 下添加 pine 配置：\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\n配置完成后需重启 Claude Desktop。\n\n资料来源：[README.md:22-37]()\n\n### 其他 MCP 客户端\n\nmcp-pine 兼容任何支持 stdio 传输的标准 MCP 客户端：\n\n```bash\nmcp-pine\n```\n\n直接运行即可，客户端通过标准输入/输出与其通信。\n\n资料来源：[README.md:38-40]()\n\n---\n\n## 环境变量配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，用于 Unix socket 文件路径前缀（`<target>.sock.<slot>`）。Windows 平台忽略此变量，仅使用 TCP 连接。 |\n| `PINE_SLOT` | `28011` | PINE 端口号/槽位，连接 PCSX2/RPCS3 时指定端口 |\n| `PINE_PIPELINE_BATCH` | `1` | 批量请求数，用于控制内存读取的并发程度。默认值为 1（完全串行）以避免 PCSX2 PINE 服务请求队列崩溃 |\n\n### 连接方式差异\n\n| 平台 | 连接方式 | 地址格式 |\n|------|----------|----------|\n| Linux/macOS | Unix Domain Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>`，备用 `$TMPDIR` 或 `/tmp` |\n| Windows | TCP | `127.0.0.1:<slot>` |\n\n资料来源：[README.md:42-50]()\n\n---\n\n## 模拟器 PINE 服务配置\n\n### PCSX2（推荐）\n\n1. 启动 PCSX2（1.7.x Qt 或更新版本）\n2. 进入 **Settings → Advanced → Enable PINE Server**\n3. 默认槽位为 **28011**，如需更改同步修改 `PINE_SLOT` 环境变量\n4. 加载任意游戏\n\n> **注意**：PINE 服务启用后始终处于运行状态，无需额外脚本或控制台命令。\n\n资料来源：[README.md:53-64]()\n\n### Duckstation\n\n1. 确认 Duckstation 构建版本包含 PINE 服务器（并非所有版本都有）\n2. 如包含，设置环境变量：\n   ```bash\n   PINE_TARGET=duckstation PINE_SLOT=<port> mcp-pine\n   ```\n\n资料来源：[README.md:66-69]()\n\n### RPCS3\n\nRPCS3 使用独立 IPC 实现，兼容 PINE 操作码集，但线级兼容性尚未全面测试。\n\n1. 进入 **Configuration → Advanced → Enable IPC server**\n2. 记下配置的端口\n3. 启动命令：\n   ```bash\n   PINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine\n   ```\n\n资料来源：[README.md:71-78]()\n\n---\n\n## 验证安装\n\n### 快速测试脚本\n\n克隆仓库后可运行冒烟测试：\n\n```bash\nnode .scratch/smoke.cjs\n```\n\n该脚本会连接运行中的模拟器并执行基础调用。\n\n### MCP 工具列表\n\n安装成功后，通过 MCP 客户端可调用以下工具：\n\n| 工具名称 | 功能 |\n|----------|------|\n| `pine_ping` | 检测连接，获取模拟器版本 |\n| `pine_get_info` | 获取游戏元数据（标题、序列号、CRC、版本、运行状态） |\n| `pine_get_status` | 获取模拟器运行状态（running/paused/shutdown） |\n| `pine_read8/16/32/64` | 读取内存（按字节宽度） |\n| `pine_read_range` | 批量读取内存（最多 4096 字节） |\n| `pine_write8/16/32/64` | 写入内存 |\n| `pine_save_state` | 保存状态到指定槽位 |\n| `pine_load_state` | 从指定槽位加载状态 |\n\n资料来源：[src/tools.ts:1-200]()\n\n---\n\n## 架构概览\n\n```mermaid\ngraph TD\n    subgraph \"MCP 客户端\"\n        A[Claude Code / Claude Desktop]\n    end\n    \n    subgraph \"mcp-pine 服务器\"\n        B[index.ts - 主入口]\n        C[tools.ts - 工具定义]\n        D[pine.ts - PINE 客户端]\n    end\n    \n    subgraph \"底层通信\"\n        E[StdioTransport]\n        F[net.Socket]\n    end\n    \n    subgraph \"目标模拟器\"\n        G[PCSX2 / RPCS3 / Duckstation]\n        H[PINE Server]\n    end\n    \n    A -->|stdio| B\n    B --> C\n    C --> D\n    D -->|StdioServerTransport| E\n    D -->|TCP / Unix Socket| F\n    F -->|PINE Protocol| G\n    G --> H\n    \n    style A fill:#e1f5fe\n    style G fill:#fff3e0\n    style H fill:#f3e5f5\n```\n\n---\n\n## 故障排查\n\n| 问题 | 可能原因 | 解决方案 |\n|------|----------|----------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 | 检查 `PINE_SLOT` 设置，确认模拟器 PINE 服务已开启 |\n| `PINE FAIL response` (0xFF) | 未加载游戏或地址未映射 | 确保已加载游戏，尝试地址 `0x00100000` |\n| 读取返回全零 | 地址在未分配区域 | 优先尝试 `0x00100000`（EE 主内存几乎总是映射） |\n| `PINE call timed out (10s)` | PCSX2 PINE 请求队列崩溃 | 需完全重启 PCSX2，重连无效 |\n\n> **重要提示**：PCSX2 的 PINE 服务请求队列脆弱，当飞行中请求超过约 6 个时会静默丢弃请求，导致回复错位。一旦发生此问题，即使 `pine_ping` 也会超时，只能通过重启模拟器恢复。\n\n资料来源：[README.md:83-101]()\n\n---\n\n## 开发相关\n\n### 本地开发\n\n```bash\nnpm install\nnpm run dev      # tsc --watch\n```\n\n### 依赖关系\n\n```mermaid\ngraph LR\n    A[mcp-pine] --> B[@modelcontextprotocol/sdk]\n    A --> C[@types/node]\n    \n    style A fill:#e8f5e9\n    style B fill:#c8e6c9\n    style C fill:#c8e6c9\n```\n\n资料来源：[package.json:16-22]()\n\n---\n\n## 许可证\n\n本项目采用 MIT 许可证。\n\n资料来源：[README.md:122]()\n\n---\n\n## 相关项目\n\n| 项目 | 平台 | 特性 |\n|------|------|------|\n| [mcp-mgba](https://github.com/dmang-dev/mcp-mgba) | mGBA (Game Boy Advance) | 含按钮输入、截图功能 |\n\n资料来源：[README.md:124-126]()\n\n---\n\n<a id='page-emulator-setup'></a>\n\n## 模拟器配置\n\n### 相关页面\n\n相关主题：[配置参考](#page-configuration), [故障排除](#page-troubleshooting)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 模拟器配置\n\n## 概述\n\nmcp-pine 是一个基于 Model Context Protocol (MCP) 的桥接工具，用于连接 Claude 等 AI 助手与支持 PINE 协议的 PS2/PS3/PSP 模拟器。通过标准化的 MCP 工具接口，用户可以读取/写入模拟器内存、保存/加载存档状态以及获取游戏元数据。\n\n当前项目支持的模拟器包括 **PCSX2**、**RPCS3** 和 **Duckstation**，每种模拟器在 PINE 功能的实现和配置方式上存在差异。\n\n## 支持的模拟器\n\n| 模拟器 | 平台 | PINE 状态 | 备注 |\n|--------|------|-----------|------|\n| PCSX2  | Qt 1.7.x+ | ✅ 原生支持 | 主要测试平台，协议实现最完整 |\n| RPCS3  | 最新版 | ⚠️ 部分兼容 | 使用自定义 IPC 实现，兼容性未充分测试 |\n| Duckstation | 特定构建 | ⚠️ 需检查 | 部分构建版本包含 PINE 服务器 |\n\n资料来源：[README.md:1-60]()\n\n## 环境变量配置\n\nmcp-pine 通过环境变量控制连接行为，无需配置文件。\n\n### 核心参数\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，用于构建 Unix socket 文件路径（Linux/macOS）或 TCP 连接标识（Windows） |\n| `PINE_SLOT` | `28011` | PINE 槽位编号，对应模拟器中配置的端口号 |\n| `PINE_PIPELINE_BATCH` | `1` | 请求流水线批次大小，控制并发请求数量 |\n\n资料来源：[README.md:40-45]()\n\n### 连接地址解析\n\n连接目标根据操作系统和配置的 `PINE_TARGET` 值自动确定：\n\n```mermaid\ngraph TD\n    A[启动 mcp-pine] --> B{操作系统}\n    B -->|Linux/macOS| C{连接类型}\n    B -->|Windows| D[TCP 连接]\n    C -->|Unix Socket| E[使用 Unix Socket]\n    C -->|TCP| D\n    D --> F[127.0.0.1:{PINE_SLOT}]\n    E --> G[{$XDG_RUNTIME_DIR}/{PINE_TARGET}.sock.{PINE_SLOT}]\n    G --> H{fallback: TMPDIR}\n    H -->|失败| I[/tmp/{PINE_TARGET}.sock.{PINE_SLOT}]\n```\n\n- **Unix Socket 路径**：`{PINE_TARGET}.sock.{PINE_SLOT}`\n  - 优先使用 `$XDG_RUNTIME_DIR`\n  - 降级使用 `$TMPDIR`\n  - 最终降级到 `/tmp`\n\n资料来源：[src/pine.ts:1-150]()\n\n## PCSX2 配置指南\n\nPCSX2 是项目的主要测试平台，提供最完整的 PINE 支持。\n\n### 启用 PINE 服务器\n\n1. 启动 PCSX2（Qt 版本 1.7.x 或更高）\n2. 进入 **Settings → Advanced → Enable PINE Server**\n3. 默认槽位为 **28011**，如需更改则同步设置 `PINE_SLOT` 环境变量\n4. 加载任意游戏\n\n> 注意：PINE 服务器启用后始终保持运行，无需额外脚本或控制台命令。\n\n资料来源：[README.md:50-60]()\n\n### 连接配置\n\n**Linux/macOS：**\n```bash\nPINE_TARGET=pcsx2 PINE_SLOT=28011 mcp-pine\n```\n\n**Windows（TCP 强制）：**\n```bash\nset PINE_SLOT=28011\nmcp-pine\n```\n\n## RPCS3 配置指南\n\nRPCS3 使用自有的 IPC 实现，其操作码集合与 PINE 类似，但线级兼容性尚未经过充分测试。\n\n### 启用 IPC 服务器\n\n1. 进入 **Configuration → Advanced → Enable IPC server**（菜单位置可能因版本而异）\n2. 记录配置的端口号\n3. 使用以下命令运行：\n\n```bash\nPINE_TARGET=rpcs3 PINE_SLOT=<端口号> mcp-pine\n```\n\n资料来源：[README.md:65-72]()\n\n## Duckstation 配置指南\n\nDuckstation 的 PINE 支持因构建版本而异，并非所有发行版都包含该功能。\n\n### 检查 PINE 支持\n\n确认你的 Duckstation 构建版本包含 PINE 服务器后，使用以下配置：\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=<端口号> mcp-pine\n```\n\n其中 `<端口号>` 需要与 Duckstation 中配置的槽位端口一致。\n\n资料来源：[README.md:35-38]()\n\n## MCP 客户端集成\n\n### Claude Code (CLI)\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\n验证连接：\n```bash\nclaude mcp list\n# 输出: pine: mcp-pine - ✓ Connected\n```\n\n资料来源：[README.md:15-22]()\n\n### Claude Desktop\n\n编辑配置文件：\n\n| 操作系统 | 配置文件路径 |\n|----------|--------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\n修改配置后需重启 Claude Desktop。\n\n资料来源：[README.md:24-35]()\n\n## 性能调优\n\n### 批量读取配置\n\n`PINE_PIPELINE_BATCH` 环境变量控制并发请求数量：\n\n| 值 | 行为 | 延迟 | 风险 |\n|----|------|------|------|\n| `1` | 完全串行（默认） | ~52ms/4KB | 无 |\n| `2` 或更高 | 流水线并发 | 降低 | PCSX2 可能丢包 |\n\n> ⚠️ PCSX2 的 PINE 服务器请求队列脆弱，约 7-9 个飞行中请求即可导致无声丢包，进而使回复管道永久失步。\n\n资料来源：[src/pine.ts:80-100]()\n\n### 测量结果\n\n在 PCSX2 v2.6.3 上通过 loopback TCP 测量：\n\n- 完整 4096 字节读取：约 52ms\n- 相当于不到两个模拟帧的时间\n\n资料来源：[CHANGELOG.md:30-35]()\n\n## 故障排除\n\n| 症状 | 原因 | 解决方案 |\n|------|------|----------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 | 检查 `PINE_SLOT` 设置 |\n| `PINE FAIL response` (0xFF) | 模拟器拒绝请求，通常因为未加载游戏或地址未映射 | 确保已加载游戏，使用有效地址 |\n| 读取返回零值 | 地址在未分配区域 | 尝试 `0x00100000`（EE 主 RAM） |\n| 数值看起来损坏 | 字节序问题 | PINE 返回小端序 |\n| `pine_ping` 超时（10s） | PCSX2 PINE 服务器卡死 | **完全重启 PCSX2**，重连无效 |\n\n### PCSX2 PINE 服务器卡死问题\n\n**现象**：即使 ping 也超时\n\n**原因**：请求管道失步，回复与等待客户端错位\n\n**恢复**：必须完全重启 PCSX2，仅重连无法解决问题\n\n资料来源：[README.md:90-100]()\n\n## 可用工具一览\n\n配置完成后，以下 MCP 工具可用于与模拟器交互：\n\n| 工具名称 | 功能 | PINE 调用次数 |\n|----------|------|---------------|\n| `pine_ping` | 获取模拟器版本 | 1 |\n| `pine_get_info` | 获取游戏标题、序列号、CRC、版本、状态 | 5（并行） |\n| `pine_get_status` | 获取运行状态（running/paused/shutdown） | 1 |\n| `pine_read8/16/32/64` | 读取指定宽度的内存值 | 1 |\n| `pine_read_range` | 批量读取最多 4096 字节 | N（串行） |\n| `pine_write8/16/32/64` | 写入指定宽度的内存值 | 1 |\n| `pine_save_state` | 保存游戏状态到槽位 | 1 |\n| `pine_load_state` | 从槽位加载游戏状态 | 1 |\n\n资料来源：[src/tools.ts:1-200]()\n\n## 地址空间参考\n\n### PS2 (PCSX2) 地址区域\n\n| 地址范围 | 描述 |\n|----------|------|\n| `0x00100000 - 0x01FFFFFF` | EE 主内存（99% 游戏状态所在） |\n| `0x1C000000+` | IOP 内存 |\n| 特定区域 | Scratchpad 等 |\n\n> ⚠️ 多字节读写（16/32/64 位）必须对齐地址。PCSX2 的 PINE 不强制对齐，非对齐访问会静默返回损坏数据。\n\n资料来源：[src/tools.ts:50-80]()\n\n## 安装方式\n\n### 方式 A：npm 全局安装\n\n```bash\nnpm install -g mcp-pine\n```\n\n### 方式 B：npx 临时运行\n\n```bash\nnpx -y mcp-pine\n```\n\n### 方式 C：源码开发\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install\n```\n\n资料来源：[README.md:42-50]()\n\n## 开发调试\n\n运行开发模式（TypeScript 监视编译）：\n\n```bash\nnpm run dev\n```\n\n针对运行中的 PCSX2 进行冒烟测试：\n\n```bash\nnode .scratch/smoke.cjs\n```\n\n资料来源：[README.md:105-112]()\n\n---\n\n<a id='page-configuration'></a>\n\n## 配置参考\n\n### 相关页面\n\n相关主题：[模拟器配置](#page-emulator-setup), [安装指南](#page-installation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 配置参考\n\n本文档详细说明 mcp-pine 的所有配置选项，包括环境变量、连接参数、运行时行为调优，以及不同平台下的连接机制差异。\n\n## 概述\n\nmcp-pine 通过 PINE（PlayStation Interactive Networked Entertainment）协议与模拟器进行 IPC 通信。项目采用零配置默认值设计，用户只需在模拟器中启用 PINE 服务即可开箱即用。高级用户可通过环境变量或代码级配置自定义连接目标、传输方式及请求管道行为。\n\n配置分为三个层级：\n\n| 层级 | 来源 | 优先级 | 适用场景 |\n|------|------|--------|----------|\n| 环境变量 | `process.env` | 最高 | 容器化部署、CLI 用户 |\n| 代码选项 | `PineConnectOptions` | 中 | SDK 集成开发者 |\n| 编译默认值 | 源码硬编码 | 最低 | 快速尝鲜 |\n\n## 环境变量配置\n\n环境变量是用户最常用的配置方式，适用于所有运行场景。\n\n### 完整配置表\n\n| 环境变量 | 默认值 | 类型 | 说明 |\n|----------|--------|------|------|\n| `PINE_TARGET` | `pcsx2` | string | 模拟器标识名，用于 Unix socket 文件路径前缀 |\n| `PINE_SLOT` | `28011` | number | PINE 槽位号，TCP 模式下作为端口号 |\n| `PINE_HOST` | `127.0.0.1` | string | TCP 连接模式下的目标主机（覆盖自动检测） |\n| `PINE_SOCKET_PATH` | 自动解析 | string | Unix socket 文件路径（覆盖自动检测） |\n| `PINE_PIPELINE_BATCH` | `1` | number | 请求管道批大小，1=完全串行 |\n\n资料来源：[README.md:38-45]()\n\n### PINE_TARGET\n\n指定目标模拟器名称，该值作为 Unix socket 文件路径的前缀部分。\n\n```bash\n# 连接到 PCSX2（默认）\nPINE_TARGET=pcsx2 mcp-pine\n\n# 连接到 Duckstation\nPINE_TARGET=duckstation PINE_SLOT=28013 mcp-pine\n\n# 连接到 RPCS3\nPINE_TARGET=rpcs3 PINE_SLOT=28014 mcp-pine\n```\n\n在 Linux/macOS 上，socket 路径格式为 `<socket_dir>/<target>.sock.<slot>`。\n\n### PINE_SLOT\n\nPINE 槽位号，映射到模拟器内部的 PINE 服务端口或 Unix socket 编号。\n\n```bash\n# 使用非标准槽位\nPINE_SLOT=28015 mcp-pine\n```\n\n槽位必须与模拟器 PINE 设置中的配置一致。PCSX2 默认槽位为 `28011`，RPCS3 可能因版本而异。\n\n### PINE_HOST 与 PINE_SOCKET_PATH\n\n这两个变量用于覆盖自动检测的连接方式：\n\n```bash\n# 强制使用 TCP 连接到指定主机\nPINE_HOST=192.168.1.100 PINE_SLOT=28011 mcp-pine\n\n# 强制使用指定的 Unix socket 路径\nPINE_SOCKET_PATH=/var/run/pcsx2.sock.28011 mcp-pine\n```\n\n通常无需手动设置，除非需要连接非本机模拟器或使用非标准 socket 位置。\n\n### PINE_PIPELINE_BATCH\n\n控制 `pine_read_range` 等批量读取操作的并行请求数。\n\n```bash\n# 完全串行（默认，最安全）\nPINE_PIPELINE_BATCH=1 mcp-pine\n\n# 允许 2 个请求并行（中等风险）\nPINE_PIPELINE_BATCH=2 mcp-pine\n\n# 允许 N 个请求并行（高风险）\nPINE_PIPELINE_BATCH=8 mcp-pine\n```\n\n> **警告**：PCSX2 的 PINE 服务器请求队列存在已知缺陷，当在飞请求超过约 6-7 个时会静默丢弃请求，导致回复管道永久错位。详情见故障排除章节。\n\n资料来源：[src/pine.ts:87-94]()\n\n## 连接选项接口\n\n对于通过 SDK 集成的开发者，`PineClient` 构造函数接受 `PineConnectOptions` 对象：\n\n```typescript\ninterface PineConnectOptions {\n  target?: string;      // 模拟器标识，默认为 \"pcsx2\"\n  slot?: number;        // 槽位号，默认为 28011\n  host?: string;        // 覆盖 TCP 主机\n  socketPath?: string;  // 覆盖 Unix socket 路径\n}\n```\n\n使用示例：\n\n```typescript\nimport { PineClient } from \"mcp-pine\";\n\nconst pine = new PineClient({\n  target: \"pcsx2\",\n  slot: 28011,\n});\n\n// 或指定自定义连接\nconst pine2 = new PineClient({\n  host: \"192.168.1.100\",\n  slot: 28011,\n});\n```\n\n## 传输层架构\n\n### 平台自动检测\n\nmcp-pine 根据运行平台自动选择最优传输方式：\n\n```mermaid\ngraph TD\n    A[启动 mcp-pine] --> B{平台检测}\n    B -->|Windows| C[TCP 连接]\n    B -->|Linux/macOS| D[Unix Domain Socket]\n    \n    C --> E[127.0.0.1:PINE_SLOT]\n    D --> F{XDG_RUNTIME_DIR}\n    F -->|存在| G[XDG_RUNTIME_DIR/target.sock.slot]\n    F -->|不存在| H{TMPDIR}\n    H -->|存在| I[TMPDIR/target.sock.slot]\n    H -->|不存在| J[/tmp/target.sock.slot]\n    \n    style C fill:#e1f5fe\n    style D fill:#fff3e0\n    style E fill:#e1f5fe\n    style G fill:#e8f5e9\n    style I fill:#e8f5e9\n    style J fill:#e8f5e9\n```\n\n### Socket 路径解析优先级\n\n在 Linux/macOS 上，Unix socket 路径按以下优先级确定：\n\n| 优先级 | 环境变量 | 示例路径 |\n|--------|----------|----------|\n| 1 | `PINE_SOCKET_PATH`（显式覆盖） | 用户指定 |\n| 2 | `$XDG_RUNTIME_DIR` | `/run/user/1000/pcsx2.sock.28011` |\n| 3 | `$TMPDIR` | `/tmp/pcsx2.sock.28011` |\n| 4 | `/tmp`（最终回退） | `/tmp/pcsx2.sock.28011` |\n\n资料来源：[src/pine.ts:30-48]()\n\n### TCP 连接模式\n\n在 Windows 或显式指定 `PINE_HOST` 时，mcp-pine 使用标准 TCP 连接：\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP 客户端\n    participant Bridge as mcp-pine\n    participant PCSX2 as PCSX2 PINE\n    \n    Note over Bridge: TCP 模式初始化\n    MCP->>Bridge: 连接请求\n    Bridge->>PCSX2: net.createConnection<br/>host: 127.0.0.1\n    PCSX2-->>Bridge: 连接成功\n    Bridge-->>MCP: 就绪\n```\n\n连接地址格式：`127.0.0.1:<PINE_SLOT>`\n\n## 请求处理机制\n\n### PINE 协议帧格式\n\nmcp-pine 使用二进制 PINE 协议进行通信，帧格式如下：\n\n```mermaid\ngraph LR\n    subgraph 发送帧\n        A[uint32<br/>总长度] --> B[uint8<br/>操作码] --> C[可变长度<br/>载荷数据]\n    end\n    \n    subgraph 接收帧\n        D[uint32<br/>总长度] --> E[uint8<br/>状态] --> F[可变长度<br/>响应数据]\n    end\n```\n\n所有多字节整数均采用小端序（Little-Endian）编码。\n\n### 操作码映射\n\n| 操作码 | 名称 | 方向 | 说明 |\n|--------|------|------|------|\n| 0x01 | Version | R | 获取模拟器版本 |\n| 0x02 | Title | R | 获取游戏标题 |\n| 0x03 | ID | R | 获取游戏序列号 |\n| 0x04 | UUID | R | 获取光盘 CRC |\n| 0x05 | GameVersion | R | 获取游戏版本 |\n| 0x06 | Status | R | 获取运行状态 |\n| 0x10 | SaveState | W | 保存状态到槽位 |\n| 0x11 | LoadState | W | 从槽位加载状态 |\n| 0x20-0x23 | Read8/16/32/64 | R | 读取内存 |\n| 0x30-0x33 | Write8/16/32/64 | W | 写入内存 |\n\n资料来源：[src/pine.ts:1-28]()\n\n### 批量读取实现\n\n`pine_read_range` 通过组合多种宽度的读取操作实现高效批量读取：\n\n```mermaid\nflowchart TD\n    A[pine_read_range<br/>length=4096] --> B{对齐检测}\n    \n    B -->|cursor%8==0 且 remaining>=8| C[read64]\n    B -->|cursor%4==0 且 remaining>=4| D[read32]\n    B -->|cursor%2==0 且 remaining>=2| E[read16]\n    B -->|其他情况| F[read8]\n    \n    C --> G{下一个字节}\n    D --> G\n    E --> G\n    F --> G\n    \n    G -->|remaining>0| B\n    G -->|remaining=0| H[组装结果缓冲区]\n    \n    I{PIPELINE_BATCH}\n    I -->|=1| J[串行执行<br/>每批1个请求]\n    I -->|>1| K[并行执行<br/>每批N个请求]\n    \n    J --> L[安全但延迟较高]\n    K --> M[低延迟但可能丢包]\n    \n    style J fill:#c8e6c9\n    style K fill:#ffcdd2\n```\n\n默认 `PIPELINE_BATCH=1` 表示完全串行执行，避免 PCSX2 PINE 服务器的队列问题。\n\n资料来源：[src/pine.ts:58-86]()\n\n## 模拟器配置要求\n\n### PCSX2 设置\n\n1. 启动 PCSX2 1.7.x 或更新版本\n2. 进入 **Settings → Advanced → Enable PINE Server**\n3. 默认槽位为 **28011**，如需更改同步修改环境变量\n\n无需额外脚本或控制台命令，PINE 启用后始终可用。\n\n### RPCS3 设置\n\nRPCS3 实现了兼容 PINE 的 IPC 接口，但线级兼容性尚未完全测试：\n\n1. 进入 **Configuration → Advanced → Enable IPC server**\n2. 记下配置的端口\n3. 使用 `PINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine` 运行\n\n### Duckstation 设置\n\n部分 Duckstation 构建包含 PINE 服务器：\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=<port> mcp-pine\n```\n\n## 故障排除\n\n### 连接问题诊断\n\n```mermaid\nflowchart TD\n    A[连接失败] --> B{PING 工具测试}\n    \n    B -->|超时| C{模拟器运行中?}\n    C -->|否| D[启动模拟器并加载游戏]\n    C -->|是| E[PINE 已启用?]\n    E -->|否| F[在模拟器设置中启用 PINE]\n    E -->|是| G{端口匹配?}\n    G -->|否| H[对齐 PINE_SLOT 和模拟器设置]\n    \n    B -->|FAIL 响应| I{是否有游戏加载?}\n    I -->|否| J[加载游戏后重试]\n    I -->|是| K[地址无效或未映射]\n    \n    K --> L[从 0x00100000 开始尝试]\n    \n    style D fill:#c8e6c9\n    style F fill:#c8e6c9\n    style H fill:#c8e6c9\n    style J fill:#c8e6c9\n    style L fill:#c8e6c9\n```\n\n### PCSX2 PINE 服务器卡死\n\nPCSX2 的 PINE 服务器在收到约 7 个以上并行请求时会静默丢弃请求，导致回复管道永久错位。\n\n**症状**：即使 `pine_ping` 也超时（10秒后）。\n\n**解决方案**：完全重启 PCSX2。重新连接无效，损坏发生在模拟器端。\n\n**预防措施**：\n- 保持 `PINE_PIPELINE_BATCH=1`\n- 如需更高性能，确保请求数量不超过 6 个\n\n资料来源：[README.md:98-115]()\n\n### 内存读取问题\n\n| 症状 | 可能原因 | 解决方案 |\n|------|----------|----------|\n| 返回全零 | 地址未分配 | 从 `0x00100000` 开始尝试 |\n| 数据损坏 | 未对齐访问 | 使用 `pine_read_range` 自行组装 |\n| 值不符合预期 | 大端序误解 | PINE 返回小端序 |\n\n## 配置示例\n\n### 基本用法（默认 PCSX2）\n\n```bash\n# 使用所有默认值\nmcp-pine\n```\n\n等价于：\n```bash\nPINE_TARGET=pcsx2 PINE_SLOT=28011 mcp-pine\n```\n\n### 连接远程模拟器\n\n```bash\nPINE_HOST=192.168.1.50 PINE_SLOT=28011 mcp-pine\n```\n\n### 自定义 Unix Socket 路径\n\n```bash\nPINE_SOCKET_PATH=/home/user/my-socket mcp-pine\n```\n\n### 性能调优（风险自负）\n\n```bash\n# 允许 2 个并行请求\nPINE_PIPELINE_BATCH=2 mcp-pine\n```\n\n### NPM 方式运行\n\n```bash\nnpx -y mcp-pine\n```\n\n## 环境变量速查表\n\n```\nPINE_TARGET          默认: pcsx2        模拟器标识名\nPINE_SLOT            默认: 28011        槽位号/端口\nPINE_HOST            默认: 127.0.0.1    TCP 主机\nPINE_SOCKET_PATH     默认: 自动解析     Unix socket 路径\nPINE_PIPELINE_BATCH  默认: 1            并行请求批大小\n```\n\n## 相关文档\n\n- [快速开始指南](README.md) — 安装与基础使用\n- [工具参考](src/tools.ts) — MCP 工具完整列表\n- [PINE 协议规范](https://github.com/GovanifY/pine) — 底层 IPC 标准\n- [mcp-mgba](https://github.com/dmang-dev/mcp-mgba) — 同系 Game Boy Advance 客户端\n\n---\n\n<a id='page-recipes'></a>\n\n## 使用范例\n\n### 相关页面\n\n相关主题：[内存操作指南](#page-memory-operations), [存档状态管理](#page-savestate), [故障排除](#page-troubleshooting)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 使用范例\n\n## 概述\n\nmcp-pine 是一个基于 Model Context Protocol (MCP) 的桥接工具，用于连接 Claude 等 AI 助手与支持 PINE（PlayStation 2 Inter-Process Communication）协议的模拟器（如 PCSX2、RPCS3、Duckstation）。通过 mcp-pine，用户可以让 AI 直接读取和写入模拟器的内存、获取游戏状态信息、保存和加载存档。\n\n该项目的主要功能包括：\n\n- **内存读写**：支持 8/16/32/64 位数值读取以及批量内存读取\n- **游戏状态查询**：获取游戏标题、序列号、CRC、版本信息\n- **存档管理**：保存和加载指定槽位的存档\n- **跨模拟器支持**：兼容 PCSX2、RPCS3、Duckstation 等主流模拟器\n\n资料来源：[README.md:1-5](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 系统架构\n\n```mermaid\ngraph TD\n    A[\"Claude / MCP 客户端\"] -->|MCP stdio| B[\"mcp-pine 桥接工具\"]\n    B -->|PINE 协议| C[\"PCSX2 PINE Server\"]\n    B -->|PINE 协议| D[\"RPCS3 IPC Server\"]\n    B -->|PINE 协议| E[\"Duckstation PINE Server\"]\n    \n    F[\"EE 主内存 0x00100000-0x01FFFFFF\"] --> C\n    G[\"IOP 内存 0x1C000000+\"] --> C\n    H[\"PS3 主内存\"] --> D\n```\n\nmcp-pine 作为中间层，将 MCP 协议请求转换为 PINE 协议调用，与模拟器的内置 PINE 服务器通信。不同模拟器使用不同的连接方式：Unix 域套接字（Linux/macOS）或 TCP（Windows）。\n\n资料来源：[src/pine.ts:1-50](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## 安装方式\n\n### 方式一：npm 全局安装\n\n```bash\nnpm install -g mcp-pine\n```\n\n### 方式二：npx 直接运行\n\n```bash\nnpx -y mcp-pine\n```\n\n### 方式三：源码安装\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install\n```\n\n资料来源：[README.md:40-50](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## MCP 客户端配置\n\n### Claude Code (CLI)\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\n验证连接：\n\n```bash\nclaude mcp list\n# 输出: pine: mcp-pine - ✓ Connected\n```\n\n### Claude Desktop\n\n根据操作系统编辑配置文件：\n\n| 平台 | 配置文件路径 |\n|------|-------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n配置内容：\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\n修改配置后需重启 Claude Desktop。\n\n资料来源：[README.md:18-38](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 环境变量配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，用于构建 Unix 套接字文件路径（`<target>.sock.<slot>`）。Windows 系统忽略此变量，仅使用 TCP 连接。 |\n| `PINE_SLOT` | `28011` | PINE 槽位号，对应 PCSX2 中的端口或槽位号。 |\n| `PINE_PIPELINE_BATCH` | `1` | 批量流水线深度。默认为 1（完全串行），设为更高值可降低延迟但可能导致 PCSX2 请求队列错位。 |\n\n资料来源：[README.md:42-48](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 模拟器配置\n\n### PCSX2 配置步骤\n\n1. 启动 PCSX2（1.7.x Qt 或更高版本）\n2. 进入 **Settings → Advanced → Enable PINE Server**\n3. 默认槽位为 **28011**，如需更改则在启动 mcp-pine 时设置 `PINE_SLOT`\n4. 加载任意游戏\n\n> 注意：PINE 服务启用后始终处于开启状态，无需脚本或控制台命令。\n\n资料来源：[README.md:52-60](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### RPCS3 配置步骤\n\n1. 进入 **Configuration → Advanced → Enable IPC server**\n2. 记下配置的端口号\n3. 运行命令：`PINE_TARGET=rpcs3 PINE_SLOT=<端口> mcp-pine`\n\n> 注意：RPCS3 的 IPC 实现参考了 PINE 操作码，但协议层面的兼容性尚未经过充分测试。\n\n资料来源：[README.md:62-68](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Duckstation 配置步骤\n\n检查当前构建的 Duckstation 是否包含 PINE 服务器（如有则设置 `PINE_TARGET=duckstation PINE_SLOT=<端口>`）。\n\n资料来源：[README.md:70-71](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 工具清单\n\nmcp-pine 提供以下 MCP 工具：\n\n| 工具名称 | 功能 | 用途场景 |\n|----------|------|----------|\n| `pine_ping` | 检测连接状态 | 验证模拟器 PINE 服务是否可用 |\n| `pine_get_info` | 获取游戏元数据 | 获取游戏标题、序列号、CRC、版本、运行状态 |\n| `pine_get_status` | 获取运行状态 | 快速检查模拟器是运行中、暂停还是已关闭 |\n| `pine_read8/16/32/64` | 定点内存读取 | 按指定字节宽度读取单个值 |\n| `pine_read_range` | 批量内存读取 | 一次性读取最多 4096 字节的连续内存区域 |\n| `pine_write8/16/32/64` | 定点内存写入 | 向指定地址写入数值 |\n| `pine_save_state` | 保存存档 | 将当前状态保存到指定槽位 |\n| `pine_load_state` | 加载存档 | 从指定槽位恢复存档 |\n\n资料来源：[src/tools.ts:1-150](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## 典型使用流程\n\n```mermaid\ngraph TD\n    A[启动 PCSX2 并加载游戏] --> B[启动 mcp-pine]\n    B --> C{连接成功?}\n    C -->|是| D[调用 pine_ping 验证]\n    D --> E[调用 pine_get_info 获取游戏信息]\n    E --> F{需要读取内存?}\n    F -->|是| G[使用 pine_read_range 批量读取]\n    G --> H[分析内存数据]\n    F -->|否| I[使用 pine_read8/16/32/64 定点读取]\n    I --> H\n    H --> J{需要修改状态?}\n    J -->|是| K[使用 pine_write* 写入]\n    J -->|否| L[完成]\n    K --> L\n    C -->|否| M[检查 PINE_SLOT 配置]\n    M --> C\n```\n\n## 内存地址说明\n\n### PS2 内存布局（PCSX2）\n\n| 地址范围 | 说明 |\n|----------|------|\n| `0x00100000` - `0x01FFFFFF` | EE 主内存（99% 的游戏状态位于此处） |\n| `0x1C000000`+ | IOP 内存 |\n| 0x10000000 区域 | Scratchpad（高速缓存） |\n\n> 重要提示：对于 16/32/64 位读取，地址**必须对齐**（即地址值能被读写宽度整除）。PCSX2 的 PINE 服务**不强制对齐**，未对齐的地址会静默返回错误数据。如需读取未对齐的数据，请使用 `pine_read_range` 并自行组装字节。\n\n资料来源：[src/tools.ts:40-55](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## 工具使用详解\n\n### 连接验证\n\n```typescript\n// 调用 pine_ping\n工具输入: {}\n预期输出: \"OK — emulator: <版本号>\"\n```\n\n### 获取游戏信息\n\n```typescript\n// 调用 pine_get_info\n工具输入: {}\n预期输出:\n\"Title:        <游戏标题>\nSerial:       <序列号>\nDisc CRC:     <CRC值>\nGame version: <版本号>\nStatus:       <运行状态>\"\n```\n\n此工具并行发送 5 个 PINE 操作码（Title、ID、UUID、GameVersion、Status），任一字段失败时返回 `(unavailable)` 而不影响其他字段。\n\n资料来源：[src/tools.ts:75-95](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### 内存读取示例\n\n#### 定点读取\n\n```typescript\n// 读取 32 位无符号整数\n工具输入: { \"address\": 0x00100000 }\n预期输出: \"0x00100000: 12345 (0x3039)\"\n\n// 读取 64 位值（返回字符串形式的十进制数，因为 JS 无法精确表示超过 2^53 的整数）\n工具输入: { \"address\": 0x00200000 }\n预期输出: \"0x00200000: 18446744073709551615 (0xFFFFFFFFFFFFFFFF)\"\n```\n\n#### 批量读取\n\n`pine_read_range` 是最高效的批量读取方式，内部实现为串行调用最大对齐宽度的读取操作。实测 PCSX2 v2.6.3 下读取 4096 字节约需 52ms。\n\n```typescript\n工具输入: { \"address\": 0x00100000, \"length\": 256 }\n预期输出: \"0x00100000: <256字节的十六进制数据>\"\n```\n\n> 默认情况下请求完全串行执行，以避免 PCSX2 请求队列错位。可通过设置 `PINE_PIPELINE_BATCH` 环境变量调整流水线深度。\n\n资料来源：[src/pine.ts:80-130](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n### 内存写入示例\n\n```typescript\n// 写入 8 位值\n工具输入: { \"address\": 0x00100000, \"value\": 255 }\n\n// 写入 32 位值\n工具输入: { \"address\": 0x00100004, \"value\": 12345678 }\n预期输出: \"Wrote 12345678 (0xBC614E) → 0x00100004\"\n```\n\n> 注意：内存写入是**破坏性操作**，会覆盖原有数据。\n\n资料来源：[src/tools.ts:96-110](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### 存档管理\n\n```typescript\n// 保存到槽位 3\n工具输入: { \"slot\": 3 }\n预期输出: \"Saved state to slot 3\"\n\n// 从槽位 5 加载\n工具输入: { \"slot\": 5 }\n预期输出: \"Loaded state from slot 5\"\n```\n\nPCSX2 存档文件通常位于：\n- Windows: `%USERPROFILE%\\Documents\\PCSX2\\sstates`\n- Linux: `~/.config/PCSX2/sstates`\n\n文件名格式：`<序列号> (<CRC>).<槽位号>.p2s`\n\n资料来源：[src/tools.ts:130-140](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## 常见问题排查\n\n| 问题症状 | 原因与解决方案 |\n|----------|---------------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、或槽位号不匹配。检查 `PINE_SLOT` 配置。 |\n| `PINE FAIL response` (0xFF) | 模拟器拒绝请求，通常是因为未加载游戏或地址未映射。 |\n| 读取返回零值 | 地址位于未分配区域，尝试从 `0x00100000` 开始（几乎总是在 EE RAM 范围内）。 |\n| 数据看起来损坏 | 检查字节序，PINE 返回小端序；字符串应使用 `read_range` 风格的字节读取。 |\n| `pine_ping` 超时（10秒） | **PCSX2 PINE 服务器可能卡死**。请求队列在超过约 6 个飞行中请求时会静默丢包，导致后续所有回复错位。**解决方案：完全重启 PCSX2**，仅重新连接无效。 |\n\n资料来源：[README.md:100-115](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 开发相关\n\n### 本地开发\n\n```bash\nnpm install\nnpm run dev      # 启动 tsc --watch 监听文件变化\n```\n\n### 快速测试\n\n在运行 PCSX2 的环境下执行冒烟测试：\n\n```bash\nnode .scratch/smoke.cjs\n```\n\n资料来源：[README.md:118-125](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 版本历史\n\n| 版本 | 日期 | 主要变更 |\n|------|------|----------|\n| 0.2.1 | 2026-05-15 | 工具描述质量改进，符合 Glama Tool Definition Quality Score 规范 |\n| 0.2.0 | 2026-05-10 | 新增 `pine_read_range` 批量读取、10秒超时机制 |\n| 0.1.x | 早期版本 | 基础功能实现 |\n\n资料来源：[CHANGELOG.md:1-50](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n## 相关项目\n\n- [mcp-mgba](https://github.com/dmang-dev/mcp-mgba) — mcp-pine 的姊妹项目，支持 mGBA 模拟器（Game Boy Advance），额外包含按键输入和截图功能\n- [PINE 协议规范](https://github.com/GovanifY/pine) — 底层 IPC 标准文档\n\n资料来源：[README.md:128-131](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n---\n\n<a id='page-troubleshooting'></a>\n\n## 故障排除\n\n### 相关页面\n\n相关主题：[模拟器配置](#page-emulator-setup), [配置参考](#page-configuration), [使用范例](#page-recipes)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 故障排除\n\n本文档提供 mcp-pine 与 PINE 协议模拟器通信时遇到的常见问题诊断与解决方案。\n\n## 连接问题\n\n### 无法连接 PINE 服务器\n\n**症状**: 调用任何工具时返回 `Cannot reach PINE server` 错误。\n\n**可能原因**:\n\n| 原因 | 检查方法 | 解决方案 |\n|------|----------|----------|\n| 模拟器未运行 | 检查模拟器进程是否启动 | 启动 PCSX2/RPCS3/Duckstation |\n| PINE 功能未启用 | 模拟器设置中搜索 \"PINE\" | Settings → Advanced → Enable PINE Server |\n| 端口/插槽号不匹配 | 检查 `PINE_SLOT` 环境变量 | 设置 `PINE_SLOT=28011` (PCSX2 默认值) |\n| 模拟器未加载游戏 | 确认游戏已加载 | 加载任意游戏后再尝试 |\n\n**排查步骤**:\n\n```mermaid\ngraph TD\n    A[连接失败] --> B{模拟器运行中?}\n    B -->|否| C[启动模拟器]\n    B -->|是| D{PINE已启用?}\n    D -->|否| E[启用PINE Server]\n    D -->|是| F{游戏已加载?}\n    F -->|否| G[加载游戏]\n    F -->|是| H{端口匹配?}\n    H -->|否| I[设置PINE_SLOT]\n    H -->|是| J[检查防火墙/权限]\n```\n\n资料来源：[README.md:1]() [README.md:52]()\n\n### 连接方式差异\n\n| 操作系统 | 连接方式 | 路径/地址格式 |\n|----------|----------|---------------|\n| Linux/macOS | Unix Domain Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>` 或 `$TMPDIR/<target>.sock.<slot>` |\n| Windows | TCP | `127.0.0.1:<slot>` |\n| 默认目标 | PCSX2 | `PINE_TARGET=pcsx2` |\n| 替代目标 | RPCS3/Duckstation | `PINE_TARGET=rpcs3` 或 `PINE_TARGET=duckstation` |\n\n资料来源：[src/pine.ts:88-100]()\n\n## PINE 协议错误响应\n\n### PINE FAIL 响应 (0xFF)\n\n**症状**: 返回 `PINE FAIL response` (0xFF) 错误。\n\n**可能原因**:\n\n| 原因 | 诊断方法 | 解决方案 |\n|------|----------|----------|\n| 未加载游戏 | 检查模拟器状态 | 加载游戏后重试 |\n| 地址未映射 | 尝试 `0x00100000` (EE RAM) | 使用已确认有效的地址 |\n| 只读区域写入 | 检查目标区域类型 | BIOS/IOP ROM 写入会被静默丢弃 |\n\n**地址空间参考**:\n\n| 区域 | 地址范围 | 说明 |\n|------|----------|------|\n| EE Main RAM | `0x00100000` - `0x01FFFFFF` | 99% 的游戏状态在此区域 |\n| IOP RAM | `0x1C000000+` | IOP 处理器内存 |\n| Scratchpad | 特定区域 | 高速缓存区域 |\n\n资料来源：[README.md:54]() [src/tools.ts:35-39]()\n\n## 内存读取问题\n\n### 读取返回全零\n\n**症状**: `pine_read8/16/32/64` 返回值全为 0。\n\n**诊断流程**:\n\n```mermaid\ngraph LR\n    A[读取返回0] --> B{地址有效?}\n    B -->|尝试0x00100000| C{仍然返回0?}\n    C -->|是| D[游戏未正确加载]\n    C -->|否| E[原地址在未分配区域]\n    B -->|无效地址| F[使用有效地址重试]\n```\n\n**解决方案**: 首先尝试 `0x00100000`，这是 EE 主 RAM 的起始地址，几乎总是可访问的。\n\n### 数据损坏/值看起来不正确\n\n**症状**: 读取的值看起来错误或损坏。\n\n**可能原因**: 字节序问题。PINE 协议返回小端序数据。\n\n| 操作类型 | 字节序 | 处理方式 |\n|----------|--------|----------|\n| 字符串读取 | UTF-8 | 使用 `read_range` 逐字节读取 |\n| 数值读取 | Little-Endian | LSB 在低位地址，MSB 在高位地址 |\n\n**解决方案**: 对于字符串，使用 `pine_read_range` 进行字节级读取。对于数值，确认解析时使用小端序。\n\n## 超时问题\n\n### PINE 调用超时 (10秒)\n\n**症状**: `pine_ping` 在某些高频使用后开始超时。\n\n**根本原因**: PCSX2 的 PINE 服务器请求队列存在已知问题。\n\n```mermaid\ngraph TD\n    A[PCSX2 PINE Server] --> B[请求队列]\n    B --> C{请求数量 <= 6}\n    C -->|是| D[正常处理]\n    C -->|否| E[请求被静默丢弃]\n    E --> F[回复流水线失步]\n    F --> G[所有后续请求超时]\n    G --> H[甚至ping也超时]\n```\n\n**已知限制**:\n\n- PCSX2 的 PINE 服务器请求队列脆弱\n- 同时有超过约 6 个进行中的请求时会静默丢弃请求\n- 一旦失步，即使 `pine_ping` 也会超时\n- **重新连接无法恢复，必须完全重启 PCSX2**\n\n资料来源：[README.md:55-56]() [CHANGELOG.md:45-52]() [src/pine.ts:60-68]()\n\n**恢复步骤**:\n\n1. 完全关闭 PCSX2（不只是暂停）\n2. 重新启动 PCSX2\n3. 重新加载游戏\n4. 重新连接 mcp-pine\n\n## 性能问题\n\n### `pine_read_range` 速度较慢\n\n**现象**: 大范围内存读取比 mGBA 的 `read_range` 慢。\n\n**原因分析**:\n\n| 特性 | PINE | mGBA |\n|------|------|------|\n| 原生批量读取 | ❌ 无 | ✅ 有 |\n| 实现方式 | 串行发送多个 read64/32/16/8 | 单次批量请求 |\n| 4096字节读取耗时 | ~52ms (PCSX2 v2.6.3) | 显著更快 |\n\n**延迟基准**:\n\n| 操作 | 耗时 | 说明 |\n|------|------|------|\n| 完整 4096 字节读取 | ~52ms | 循环回程 TCP 性能 |\n| 相当于模拟帧数 | < 2 帧 | 60fps 下约 33ms/帧 |\n\n资料来源：[README.md:57-58]() [CHANGELOG.md:37-40]()\n\n### 流水线批处理选项\n\n**环境变量**: `PINE_PIPELINE_BATCH`\n\n| 值 | 行为 | 风险 |\n|----|------|------|\n| 1 (默认) | 完全串行请求 | 无 |\n| >= 2 | 启用流水线 | 可能导致 PCSX2 失步 |\n\n```typescript\n// src/pine.ts 中的实现逻辑\nconst PIPELINE_BATCH = Number.parseInt(process.env.PINE_PIPELINE_BATCH ?? \"1\", 10) || 1;\n\nfor (let i = 0; i < steps.length; i += PIPELINE_BATCH) {\n    const batch = steps.slice(i, i + PIPELINE_BATCH);\n    const promises = batch.map((s) => /* ... */);\n    const results = await Promise.all(promises);\n}\n```\n\n**警告**: 启用流水线可能导致 PCSX2 PINE 服务器失步。仅在能够容忍偶尔模拟器重启的情况下使用。\n\n资料来源：[src/pine.ts:70-73]() [src/pine.ts:95-100]()\n\n## 对齐问题\n\n### 未对齐地址访问\n\n**症状**: 多字节读取返回值看起来错误或损坏。\n\n**根本原因**: PINE on PCSX2 **不强制对齐要求**。\n\n| 操作 | 对齐要求 | 未对齐行为 |\n|------|----------|------------|\n| `pine_read8` / `pine_write8` | 无 | 正常工作 |\n| `pine_read16` / `pine_write16` | 2字节对齐 | 返回对齐地址以下的字节 |\n| `pine_read32` / `pine_write32` | 4字节对齐 | 返回对齐地址以下的字节 |\n| `pine_read64` / `pine_write64` | 8字节对齐 | 返回对齐地址以下的字节 |\n\n**解决方案**:\n\n1. 确保传入对齐的地址\n2. 如需未对齐访问，使用 `pine_read_range` 逐字节读取后自行组装\n\n```mermaid\ngraph LR\n    A[需要读取0x1003] --> B{可接受的访问方式?}\n    B --> C[使用read_range读取0x1000-0x1007]\n    B --> D[忽略不对齐的write64]\n    C --> E[自行组装字节]\n```\n\n资料来源：[src/tools.ts:11-15]()\n\n## 工具调用错误\n\n### 各工具的错误条件汇总\n\n| 工具 | 失败模式 | 错误信息 |\n|------|----------|----------|\n| `pine_ping` | 连接失败/PINE 失步 | `Cannot reach PINE server` / 超时 |\n| `pine_get_info` | 连接失败/部分字段不可用 | 返回 `(unavailable)` |\n| `pine_get_status` | 连接失败 | `PINE FAIL response` |\n| `pine_read*` | 无效地址/未对齐 | PINE FAIL 或错误值 |\n| `pine_write*` | 只读区域/无效地址 | PINE FAIL (静默丢弃) |\n| `pine_save_state` | 插槽超出范围 | Schema 拒绝 (0-255) |\n| `pine_load_state` | 插槽无存档 | PINE FAIL |\n\n### 存档状态槽位\n\n| 槽位范围 | 约定 | 实际协议支持 |\n|----------|------|--------------|\n| 0-255 | 完整协议支持 | ✅ |\n| 0-9 | PCSX2 GUI 映射到 F1-F10 | 推荐使用 |\n\n资料来源：[src/tools.ts:58-63]()\n\n## 环境变量参考\n\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，决定 Unix socket 文件前缀 |\n| `PINE_SLOT` | `28011` | PINE 插槽号，也是 TCP 端口号 |\n| `PINE_PIPELINE_BATCH` | `1` | 流水线批处理大小，1=完全串行 |\n\n资料来源：[README.md:29-32]() [src/pine.ts:70]()\n\n## 调试技巧\n\n### 快速冒烟测试\n\n```bash\n# 确保模拟器运行且 PINE 已启用\nnode .scratch/smoke.cjs\n```\n\n### 推荐的调试工作流\n\n1. **首先验证连接**: 使用 `pine_ping`\n2. **获取基本信息**: 使用 `pine_get_info` 确认游戏加载\n3. **检查状态**: 使用 `pine_get_status`\n4. **从已知地址开始**: 尝试 `0x00100000` 验证读取功能\n5. **逐步深入**: 确认基础功能后再访问特定内存区域\n\n### 连接质量检查\n\n```mermaid\ngraph TD\n    A[开始调试] --> B[ping成功?]\n    B -->|否| C[检查模拟器/网络]\n    B -->|是| D[get_info成功?]\n    D -->|否| E[无游戏加载]\n    D -->|是| F[测试已知地址]\n    F --> G{0x00100000返回非零?}\n    G -->|否| H[EE RAM未映射]\n    G -->|是| I[基础连接正常]\n```\n\n## 已知限制\n\n| 限制 | 描述 | 状态 |\n|------|------|------|\n| PCSX2 请求队列脆弱 | >6 流水线请求会导致失步 | 已知问题，无法自动恢复 |\n| 无原生批量读取 | `read_range` 串行实现 | 设计限制，性能可接受 |\n| 未对齐访问静默损坏 | PCSX2 不强制对齐 | 需客户端保证 |\n| RPCS3 兼容性未充分测试 | Wire-level 兼容性待验证 | 实验性支持 |\n\n资料来源：[README.md:45-51]() [CHANGELOG.md:48-54]()\n\n## 获取帮助\n\n如遇到本文档未覆盖的问题，请：\n\n1. 确认问题可重现\n2. 记录模拟器版本、PINE 设置、错误信息\n3. 在 [GitHub Issues](https://github.com/dmang-dev/mcp-pine/issues) 创建 Issue\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：dmang-dev/mcp-pine\n\n摘要：发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：安装坑 - 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers。\n\n## 1. 安装坑 · 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Submit listing PR to punkpeye/awesome-mcp-servers\n- 对用户的影响：可能阻塞安装或首次运行。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_540ae479012f437fb2cb5e7d33636f1f | https://github.com/dmang-dev/mcp-pine/issues/2 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 2. 配置坑 · 可能修改宿主 AI 配置\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 防护动作：涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- 证据：capability.host_targets | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | host_targets=mcp_host, claude\n\n## 3. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | README/documentation is current enough for a first validation pass.\n\n## 4. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | last_activity_observed missing\n\n## 5. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 6. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 7. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | issue_or_pr_quality=unknown\n\n## 8. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | release_recency=unknown\n\n<!-- canonical_name: dmang-dev/mcp-pine; human_manual_source: deepwiki_human_wiki -->\n",
      "markdown_key": "mcp-pine",
      "pages": "draft",
      "source_refs": [
        {
          "evidence_id": "github_repo:1234265030",
          "kind": "repo",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/dmang-dev/mcp-pine"
        },
        {
          "evidence_id": "art_40bf33c618b744a98095322c8cf4a7ea",
          "kind": "docs",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/dmang-dev/mcp-pine#readme"
        }
      ],
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "mcp-pine 说明书",
      "toc": [
        "https://github.com/dmang-dev/mcp-pine 项目说明书",
        "目录",
        "项目介绍",
        "概述",
        "项目背景与目标",
        "支持的模拟器",
        "系统架构",
        "MCP 工具集详解",
        "Doramagic 踩坑日志"
      ]
    }
  },
  "quality_gate": {
    "blocking_gaps": [],
    "category_confidence": "medium",
    "compile_status": "ready_for_review",
    "five_assets_present": true,
    "install_sandbox_verified": true,
    "missing_evidence": [],
    "next_action": "publish to Doramagic.ai project surfaces",
    "prompt_preview_boundary_ok": true,
    "publish_status": "publishable",
    "quick_start_verified": true,
    "repo_clone_verified": false,
    "repo_commit": null,
    "repo_inspection_error": null,
    "repo_inspection_files": [],
    "repo_inspection_verified": false,
    "review_reasons": [
      "community_discussion_evidence_below_public_threshold"
    ],
    "tag_count_ok": true,
    "unsupported_claims": []
  },
  "schema_version": "0.1",
  "user_assets": {
    "ai_context_pack": {
      "asset_id": "ai_context_pack",
      "filename": "AI_CONTEXT_PACK.md",
      "markdown": "# mcp-pine - Doramagic AI Context Pack\n\n> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。\n\n## 充分原则\n\n- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。\n- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。\n\n## 给宿主 AI 的使用方式\n\n你正在读取 Doramagic 为 mcp-pine 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。\n\n## Claim 消费规则\n\n- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。\n- **事实最低状态**：`supported`\n- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。\n- `weak`：只能作为低置信度线索，必须要求用户继续核实。\n- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。\n- `unverified`：不得作为事实使用，应明确说证据不足。\n- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。\n\n## 它最适合谁\n\n- **正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**：README 或插件配置提到多个宿主 AI。 证据：`README.md` Claim：`clm_0002` supported 0.86\n\n## 它能做什么\n\n- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n## 怎么开始\n\n- `npm install -g mcp-pine` 证据：`README.md` Claim：`clm_0003` supported 0.86\n- `npx -y mcp-pine` 证据：`README.md` Claim：`clm_0004` supported 0.86\n- `git clone https://github.com/dmang-dev/mcp-pine` 证据：`README.md` Claim：`clm_0005` supported 0.86\n- `npm install        # also runs the build via the` 证据：`README.md` Claim：`clm_0006` supported 0.86\n- `claude mcp add pine --scope user mcp-pine` 证据：`README.md` Claim：`clm_0007` supported 0.86\n\n## 继续前判断卡\n\n- **当前建议**：先做权限沙盒试用\n- **为什么**：项目存在安装命令、宿主配置或本地写入线索，不建议直接进入主力环境，应先在隔离环境试装。\n\n### 30 秒判断\n\n- **现在怎么做**：先做权限沙盒试用\n- **最小安全下一步**：先跑 Prompt Preview；若仍要安装，只在隔离环境试装\n- **先别相信**：工具权限边界不能在安装前相信。\n- **继续会触碰**：命令执行、本地环境或项目文件、宿主 AI 上下文\n\n### 现在可以相信\n\n- **适合人群线索：正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86\n- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0003` supported 0.86\n\n### 现在还不能相信\n\n- **工具权限边界不能在安装前相信。**（unverified）：MCP/tool 类项目通常会触碰文件、网络、浏览器或外部 API，必须真实检查权限和日志。\n- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。\n- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。\n- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。\n- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。\n- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。\n- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。\n- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`README.md`\n\n### 继续会触碰什么\n\n- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`\n- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`\n- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。\n\n### 最小安全下一步\n\n- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）\n- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）\n- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）\n\n### 退出方式\n\n- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。\n- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。\n- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。\n\n## 哪些只能预览\n\n- 解释项目适合谁和能做什么\n- 基于项目文档演示典型对话流程\n- 帮助用户判断是否值得安装或继续研究\n\n## 哪些必须安装后验证\n\n- 真实安装 Skill、插件或 CLI\n- 执行脚本、修改本地文件或访问外部服务\n- 验证真实输出质量、性能和兼容性\n\n## 边界与风险判断卡\n\n- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0008` inferred 0.45\n- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0009` supported 0.86\n- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。\n- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。\n- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。\n\n## 开工前工作上下文\n\n### 加载顺序\n\n- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。\n- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。\n- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。\n- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。\n- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。\n\n### 任务路由\n\n- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n### 上下文规模\n\n- 文件总数：14\n- 重要文件覆盖：13/14\n- 证据索引条目：13\n- 角色 / Skill 条目：4\n\n### 证据不足时的处理\n\n- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。\n- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。\n- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。\n- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。\n\n## Prompt Recipes\n\n### 适配判断\n\n- 目标：判断这个项目是否适合用户当前任务。\n- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。\n\n```text\n请基于 mcp-pine 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。\n```\n\n### 安装前体验\n\n- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。\n- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。\n\n```text\n请把 mcp-pine 当作安装前体验资产，而不是已安装工具或真实运行环境。\n\n请严格输出四段：\n1. 先问我 3 个必要问题。\n2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。\n3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。\n4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。\n\n硬性边界：\n- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。\n- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。\n- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。\n- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。\n- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。\n- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。\n\n```\n\n### 角色 / Skill 选择\n\n- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。\n- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。\n\n```text\n请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。\n```\n\n### 风险预检\n\n- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。\n- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。\n\n```text\n请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。\n```\n\n### 宿主 AI 开工指令\n\n- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。\n- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。\n\n```text\n请基于 mcp-pine 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。\n```\n\n\n## 角色 / Skill 索引\n\n- 共索引 4 个角色 / Skill / 项目文档条目。\n\n- **mcp-pine**（project_doc）：! npm version https://img.shields.io/npm/v/mcp-pine.svg https://www.npmjs.com/package/mcp-pine ! npm downloads https://img.shields.io/npm/dm/mcp-pine.svg https://www.npmjs.com/package/mcp-pine ! CI https://github.com/dmang-dev/mcp-pine/actions/workflows/ci.yml/badge.svg https://github.com/dmang-dev/mcp-pine/actions/workflows/ci.yml ! License: MIT https://img.shields.io/npm/l/mcp-pine.svg LICENSE 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`\n- **mcp-pine recipes**（project_doc）：Practical examples of driving a PINE-speaking emulator PCSX2 et al. through Claude or any MCP client. Each recipe is self-contained. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/RECIPES.md`\n- **mcp-pcsx2 — scope document**（project_doc）：Status: planning. No code yet. Companion to mcp-mgba ../mcp-mgba — same architectural pattern, different transport. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/SCOPE.md`\n- **Changelog**（project_doc）：All notable changes to this project will be documented in this file. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CHANGELOG.md`\n\n## 证据索引\n\n- 共索引 13 条证据。\n\n- **mcp-pine**（documentation）：! npm version https://img.shields.io/npm/v/mcp-pine.svg https://www.npmjs.com/package/mcp-pine ! npm downloads https://img.shields.io/npm/dm/mcp-pine.svg https://www.npmjs.com/package/mcp-pine ! CI https://github.com/dmang-dev/mcp-pine/actions/workflows/ci.yml/badge.svg https://github.com/dmang-dev/mcp-pine/actions/workflows/ci.yml ! License: MIT https://img.shields.io/npm/l/mcp-pine.svg LICENSE 证据：`README.md`\n- **Package**（package_manifest）：{ \"name\": \"mcp-pine\", \"version\": \"0.2.1\", \"description\": \"MCP server for emulators that speak PINE PCSX2, and other PINE-compatible emulators — exposes memory read/write and savestate control\", \"license\": \"MIT\", \"type\": \"module\", \"bin\": { \"mcp-pine\": \"dist/index.js\" }, \"files\": \"dist/\", \"docs/\", \"README.md\", \"LICENSE\" , \"scripts\": { \"build\": \"tsc && node -e \\\"import 'node:fs' .then fs = fs.chmodSync 'dist/index.js', 0o755 \\\"\", \"dev\": \"tsc --watch\", \"start\": \"node dist/index.js\", \"prepare\": \"npm run build\", \"inspector\": \"npx @modelcontextprotocol/inspector node dist/index.js\" }, \"engines\": { \"node\": \" =18\" }, \"repository\": { \"type\": \"git\", \"url\": \"git+https://github.com/dmang-dev/mcp-pine.gi… 证据：`package.json`\n- **License**（source_file）：Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files the \"Software\" , to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 证据：`LICENSE`\n- **mcp-pine recipes**（documentation）：Practical examples of driving a PINE-speaking emulator PCSX2 et al. through Claude or any MCP client. Each recipe is self-contained. 证据：`docs/RECIPES.md`\n- **mcp-pcsx2 — scope document**（documentation）：Status: planning. No code yet. Companion to mcp-mgba ../mcp-mgba — same architectural pattern, different transport. 证据：`docs/SCOPE.md`\n- **Changelog**（documentation）：All notable changes to this project will be documented in this file. 证据：`CHANGELOG.md`\n- **Glama**（structured_config）：{ \"$schema\": \"https://glama.ai/mcp/schemas/server.json\", \"maintainers\": \"dmang-dev\" } 证据：`glama.json`\n- **Tsconfig**（structured_config）：{ \"compilerOptions\": { \"target\": \"ES2022\", \"module\": \"NodeNext\", \"moduleResolution\": \"NodeNext\", \"outDir\": \"./dist\", \"rootDir\": \"./src\", \"strict\": true, \"esModuleInterop\": true, \"skipLibCheck\": true, \"declaration\": true, \"declarationMap\": true, \"sourceMap\": true }, \"include\": \"src/ / \" , \"exclude\": \"node modules\", \"dist\" } 证据：`tsconfig.json`\n- **.gitignore**（source_file）：node modules/ dist/ .js.map .claude/ .rstk/ .scratch/ .png homebrew games/ \"PlayStation 2 BIOS\"/ 证据：`.gitignore`\n- **Dockerfile — primarily for the Glama MCP registry https://glama.ai/mcp/servers .**（source_file）：Dockerfile — primarily for the Glama MCP registry https://glama.ai/mcp/servers . Builds the MCP server and runs it over stdio. The server starts cleanly WITHOUT a PINE-speaking emulator present: it logs a note that the bridge is unreachable and still serves tools/list. That's exactly what Glama's \"start + respond to introspection\" check needs. For actual use you don't need Docker — npm install -g mcp-pine and point it at a running PCSX2 or other PINE emulator . See README.md. 证据：`Dockerfile`\n- **!/usr/bin/env node**（source_file）：!/usr/bin/env node import { Server } from \"@modelcontextprotocol/sdk/server/index.js\"; import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\"; import { PineClient } from \"./pine.js\"; import { registerTools } from \"./tools.js\"; 证据：`src/index.ts`\n- **Pine**（source_file）：// PINE protocol client // ───────────────────── // Wire format per the PINE standard : // // Request: uint32 t total size with prefix uint8 t opcode args LE // Reply: uint32 t total size with prefix uint8 t result code return data LE // // result code: 0x00 = OK, 0xFF = FAIL // // Transport per the PINE spec : // - Linux: Unix domain socket at $XDG RUNTIME DIR/ .sock. fallback /tmp // - macOS: Unix domain socket at $TMPDIR/ .sock. fallback /tmp // - Windows: TCP on 127.0.0.1: // // Target naming convention the bit before .sock. : // - PCSX2: \"pcsx2\" // - RPCS3: \"rpcs3\" // - Duckstation: \"duckstation\" // // Stateless: every request gets exactly one reply. 证据：`src/pine.ts`\n- **Tools**（source_file）：import { CallToolRequestSchema, ListToolsRequestSchema, Tool, } from \"@modelcontextprotocol/sdk/types.js\"; import type { Server } from \"@modelcontextprotocol/sdk/server/index.js\"; import { PineClient } from \"./pine.js\"; 证据：`src/tools.ts`\n\n## 宿主 AI 必须遵守的规则\n\n- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`README.md`, `package.json`, `LICENSE`\n- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`README.md`, `package.json`, `LICENSE`\n\n## 用户开工前应该回答的问题\n\n- 你准备在哪个宿主 AI 或本地环境中使用它？\n- 你只是想先体验工作流，还是准备真实安装？\n- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？\n\n## 验收标准\n\n- 所有能力声明都能回指到 evidence_refs 中的文件路径。\n- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。\n- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。\n\n---\n\n## Doramagic Context Augmentation\n\n下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。\n\n## Human Manual 骨架\n\n使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。\n\n宿主 AI 硬性规则：\n- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。\n- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。\n- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。\n\n- **项目介绍**：importance `high`\n  - source_paths: README.md\n- **快速开始**：importance `high`\n  - source_paths: README.md, package.json\n- **系统架构**：importance `high`\n  - source_paths: README.md, src/index.ts, src/pine.ts\n- **PINE 协议详解**：importance `medium`\n  - source_paths: src/pine.ts\n- **工具参考**：importance `high`\n  - source_paths: src/tools.ts, README.md\n- **内存操作指南**：importance `high`\n  - source_paths: src/tools.ts, README.md\n- **存档状态管理**：importance `medium`\n  - source_paths: src/tools.ts\n- **安装指南**：importance `high`\n  - source_paths: package.json, Dockerfile, README.md\n\n## Repo Inspection Evidence / 源码检查证据\n\n- repo_clone_verified: false\n- repo_inspection_verified: false\n- repo_commit: `unknown`\n\n宿主 AI 硬性规则：\n- 没有 repo_clone_verified=true 时，不得声称已经读过源码。\n- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。\n- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。\n\n## Doramagic Pitfall Constraints / 踩坑约束\n\n这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。\n\n### Constraint 1: 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers\n\n- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Submit listing PR to punkpeye/awesome-mcp-servers\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能阻塞安装或首次运行。\n- Evidence: community_evidence:github | cevd_540ae479012f437fb2cb5e7d33636f1f | https://github.com/dmang-dev/mcp-pine/issues/2 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 2: 可能修改宿主 AI 配置\n\n- Trigger: 项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- Host AI rule: 列出会写入的配置文件、目录和卸载/回滚步骤。\n- Why it matters: 安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- Evidence: capability.host_targets | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | host_targets=mcp_host, claude\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 3: 能力判断依赖假设\n\n- Trigger: README/documentation is current enough for a first validation pass.\n- Host AI rule: 将假设转成下游验证清单。\n- Why it matters: 假设不成立时，用户拿不到承诺的能力。\n- Evidence: capability.assumptions | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | README/documentation is current enough for a first validation pass.\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 4: 维护活跃度未知\n\n- Trigger: 未记录 last_activity_observed。\n- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Evidence: evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | last_activity_observed missing\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 5: 下游验证发现风险项\n\n- Trigger: no_demo\n- Host AI rule: 进入安全/权限治理复核队列。\n- Why it matters: 下游已经要求复核，不能在页面中弱化。\n- Evidence: downstream_validation.risk_items | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 6: 存在评分风险\n\n- Trigger: no_demo\n- Host AI rule: 把风险写入边界卡，并确认是否需要人工复核。\n- Why it matters: 风险会影响是否适合普通用户安装。\n- Evidence: risks.scoring_risks | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 7: issue/PR 响应质量未知\n\n- Trigger: issue_or_pr_quality=unknown。\n- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。\n- Why it matters: 用户无法判断遇到问题后是否有人维护。\n- Evidence: evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | issue_or_pr_quality=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 8: 发布节奏不明确\n\n- Trigger: release_recency=unknown。\n- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。\n- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Evidence: evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | release_recency=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n",
      "summary": "给宿主 AI 的上下文和工作边界。",
      "title": "AI Context Pack / 带给我的 AI"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card / 安装前决策卡\n\n项目：dmang-dev/mcp-pine\n\n## Doramagic 试用结论\n\n当前结论：可以进入发布前推荐检查；首次使用仍应从最小权限、临时目录和可回滚配置开始。\n\n## 用户现在可以做\n\n- 可以先阅读 Human Manual，理解项目目的和主要工作流。\n- 可以复制 Prompt Preview 做安装前体验；这只验证交互感，不代表真实运行。\n- 可以把官方 Quick Start 命令放到隔离环境中验证，不要直接进主力环境。\n\n## 现在不要做\n\n- 不要把 Prompt Preview 当成项目实际运行结果。\n- 不要把 metadata-only validation 当成沙箱安装验证。\n- 不要把未验证能力写成“已支持、已跑通、可放心安装”。\n- 不要在首次试用时交出生产数据、私人文件、真实密钥或主力配置目录。\n\n## 安装前检查\n\n- 宿主 AI 是否匹配：mcp_host, claude\n- 官方安装入口状态：已发现官方入口\n- 是否在临时目录、临时宿主或容器中验证：必须是\n- 是否能回滚配置改动：必须能\n- 是否需要 API Key、网络访问、读写文件或修改宿主配置：未确认前按高风险处理\n- 是否记录了安装命令、实际输出和失败日志：必须记录\n\n## 当前阻塞项\n\n- review_required: community_discussion_evidence_below_public_threshold\n\n## 项目专属踩坑\n\n- 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers（medium）：可能阻塞安装或首次运行。 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 可能修改宿主 AI 配置（medium）：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 能力判断依赖假设（medium）：假设不成立时，用户拿不到承诺的能力。 建议检查：将假设转成下游验证清单。\n- 维护活跃度未知（medium）：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 下游验证发现风险项（medium）：下游已经要求复核，不能在页面中弱化。 建议检查：进入安全/权限治理复核队列。\n\n## 风险与权限提示\n\n- no_demo: medium\n\n## 证据缺口\n\n- 暂未发现结构化证据缺口。\n",
      "summary": "安装、权限、验证和推荐前风险。",
      "title": "Boundary & Risk Card / 边界与风险卡"
    },
    "human_manual": {
      "asset_id": "human_manual",
      "filename": "HUMAN_MANUAL.md",
      "markdown": "# https://github.com/dmang-dev/mcp-pine 项目说明书\n\n生成时间：2026-05-17 20:22:23 UTC\n\n## 目录\n\n- [项目介绍](#page-introduction)\n- [快速开始](#page-quickstart)\n- [系统架构](#page-architecture)\n- [PINE 协议详解](#page-pine-protocol)\n- [工具参考](#page-tools-reference)\n- [内存操作指南](#page-memory-operations)\n- [存档状态管理](#page-savestate)\n- [安装指南](#page-installation)\n- [模拟器配置](#page-emulator-setup)\n- [配置参考](#page-configuration)\n- [使用范例](#page-recipes)\n- [故障排除](#page-troubleshooting)\n\n<a id='page-introduction'></a>\n\n## 项目介绍\n\n### 相关页面\n\n相关主题：[系统架构](#page-architecture), [快速开始](#page-quickstart)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 项目介绍\n\n## 概述\n\nmcp-pine 是一个基于 **Model Context Protocol (MCP)** 的桥接服务器，用于连接 MCP 客户端（如 Claude Code、Claude Desktop）与支持 PINE 协议的 PlayStation 系列模拟器。该项目使 AI 助手能够直接读取和写入模拟器内存、保存/加载游戏状态，从而实现自动化游戏调试、内存修改、状态快照实验等高级功能。\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 项目背景与目标\n\n在传统的游戏逆向工程和模拟器调试中，开发者需要手动使用调试工具或编写专用脚本与模拟器交互。mcp-pine 的出现旨在将这种能力抽象为一个标准化的 MCP 工具集，使 AI 助手能够：\n\n- 实时查询游戏运行状态和元数据\n- 读取任意内存地址的数据\n- 写入内存实现游戏修改（Cheats/Pokes）\n- 保存和恢复游戏快照\n- 执行自动化的内存搜索和结构解码\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 支持的模拟器\n\nmcp-pine 目前支持以下模拟器：\n\n| 模拟器 | 状态 | 说明 |\n|--------|------|------|\n| **PCSX2** | 完整支持 | 1.7.x Qt 或更高版本，支持 PINE Server |\n| **RPCS3** | 实验性支持 | 有独立的 IPC 实现，与 PINE 操作码兼容 |\n| **Duckstation** | 部分支持 | 取决于具体编译版本是否包含 PINE Server |\n\n对于 PCSX2，用户只需在 `Settings → Advanced → Enable PINE Server` 中启用即可，无需脚本或控制台命令。默认插槽为 **28011**。\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 系统架构\n\nmcp-pine 采用典型的客户端-服务器分层架构：\n\n```mermaid\ngraph TD\n    A[MCP 客户端<br/>Claude Code/Desktop] -->|MCP 协议<br/>stdio| B[mcp-pine<br/>桥接服务器]\n    B -->|PINE 协议<br/>Unix Socket| C[PCSX2 PINE Server]\n    B -->|PINE 协议<br/>TCP| D[RPCS3 IPC Server]\n    B -->|PINE 协议<br/>Socket| E[Duckstation PINE]\n    \n    F[EE 主内存<br/>0x00100000-0x01FFFFFF] --> C\n    G[IOP RAM<br/>0x1C000000+] --> C\n```\n\n### 核心组件\n\n| 组件 | 文件位置 | 职责 |\n|------|----------|------|\n| **PineClient** | `src/pine.ts` | 底层 PINE 协议通信，处理 socket 连接、请求队列、响应解析 |\n| **工具注册器** | `src/tools.ts` | 定义 MCP 工具 schema，实现工具调用路由 |\n| **入口点** | `src/index.ts` | MCP 服务器初始化，工具注册，stdin/stdout 管道 |\n\n资料来源：[src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)，[src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## MCP 工具集详解\n\nmcp-pine 提供以下 MCP 工具，分为四个类别：\n\n### 连接与自检\n\n| 工具名 | 功能描述 | 返回值 |\n|--------|----------|--------|\n| `pine_ping` | 检查与模拟器的连接，获取模拟器版本 | `OK — emulator: VERSION` |\n\n### 游戏信息查询\n\n| 工具名 | 功能描述 | 返回值示例 |\n|--------|----------|------------|\n| `pine_get_info` | 批量获取游戏元数据（标题、序列号、CRC、版本、状态） | `Title: GameName\\nSerial: SLUS-12345\\nDisc CRC: ABCD1234\\nGame version: 1.00\\nStatus: running` |\n| `pine_get_status` | 获取模拟器运行状态 | `Status: running/paused/shutdown/unknown` |\n\n### 内存读取\n\n| 工具名 | 数据宽度 | 对齐要求 | 说明 |\n|--------|----------|----------|------|\n| `pine_read8` | 8 位 | 无 | 单字节读取 |\n| `pine_read16` | 16 位 | 2 字节 | 小端序 |\n| `pine_read32` | 32 位 | 4 字节 | 小端序，用于指针、RGBA 颜色 |\n| `pine_read64` | 64 位 | 8 字节 | 完整 PS2 EE 指针、大 ID |\n| `pine_read_range` | 可变 | 自动选择最大对齐 | 批量读取最多 4096 字节 |\n\n### 内存写入\n\n| 工具名 | 数据宽度 | 对齐要求 | 风险提示 |\n|--------|----------|----------|----------|\n| `pine_write8` | 8 位 | 无 | 直接写入，无撤销 |\n| `pine_write16` | 16 位 | 2 字节 | 覆盖式写入，绕过 TLB |\n| `pine_write32` | 32 位 | 4 字节 | 32 位 Cheats/Pokes |\n| `pine_write64` | 64 位 | 8 字节 | 完整 64 位值写入 |\n\n### 状态管理\n\n| 工具名 | 功能描述 | 参数 |\n|--------|----------|------|\n| `pine_save_state` | 保存当前游戏状态到指定槽位 | `slot: 0-255` |\n| `pine_load_state` | 从指定槽位加载游戏状态 | `slot: 0-255` |\n\n资料来源：[src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## 配置与环境变量\n\nmcp-pine 通过环境变量进行配置：\n\n| 环境变量 | 默认值 | 用途 |\n|----------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 指定模拟器名称，用于 Unix socket 文件路径前缀 |\n| `PINE_SLOT` | `28011` | PINE 插槽号（Linux/macOS）或 TCP 端口（Windows） |\n| `PINE_PIPELINE_BATCH` | `1` | 批量请求数，控制性能与稳定性权衡 |\n\n### 连接路径说明\n\n| 操作系统 | 连接方式 | 路径格式 |\n|----------|----------|----------|\n| Linux | Unix Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>` 或 `$TMPDIR/<target>.sock.<slot>` 或 `/tmp/<target>.sock.<slot>` |\n| macOS | Unix Socket | 同 Linux |\n| Windows | TCP | `127.0.0.1:<slot>` |\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 安装与部署\n\n### 方式一：npm 全局安装\n\n```bash\nnpm install -g mcp-pine\n```\n\n### 方式二：npx 临时运行\n\n```bash\nnpx -y mcp-pine\n```\n\n### 方式三：源码开发\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install\n```\n\n### Claude Code 集成\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\n验证连接：\n\n```bash\nclaude mcp list\n# pine: mcp-pine - ✓ Connected\n```\n\n### Claude Desktop 集成\n\n编辑配置文件：\n\n| 平台 | 路径 |\n|------|------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 已知问题与限制\n\n### PCSX2 PINE 服务器脆弱性\n\nPCSX2 的 PINE 服务器请求队列非常脆弱。当有超过约 **6-7 个飞行中的请求**时，服务器会静默丢弃请求，导致回复管道失同步。一旦失同步，即使新的 `pine_ping` 也会超时，只能通过完全重启 PCSX2 恢复。\n\n**缓解措施**：\n- `pine_read_range` 默认以完全串行方式发出请求\n- 使用 `PINE_PIPELINE_BATCH=2` 或更高值可提升延迟，但有失同步风险\n\n### 内存访问注意事项\n\n| 问题 | 原因 | 解决方案 |\n|------|------|----------|\n| 读取返回零值 | 地址在未分配区域 | 尝试 `0x00100000`（几乎总在 EE RAM 内） |\n| 数值看起来损坏 | 对齐问题 | PINE 不强制对齐，未对齐的多字节读取会返回对齐地址下的数据 |\n| 字符串解析错误 | 字节序问题 | PINE 返回小端序，字符串应使用 `read_range` 按字节读取 |\n| 写入 IOP ROM 无效 | 只读区域 | BIOS、IOP ROM 区域写入会被静默丢弃 |\n\n### 性能基准\n\n| 操作 | 耗时 | 说明 |\n|------|------|------|\n| 完整 4096 字节读取 | ~52 ms | PCSX2 v2.6.3，loopback TCP |\n| 单次 `pine_ping` | <1 ms | 本地连接 |\n| 状态保存/加载 | 取决于存档大小 | 通过 PINE 协议传输 |\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)，[CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n## 项目依赖\n\nmcp-pine 的核心依赖非常精简：\n\n| 依赖 | 版本 | 用途 |\n|------|------|------|\n| `@modelcontextprotocol/sdk` | ^1.12.0 | MCP 协议 SDK，处理 stdio 通信 |\n\n开发依赖：\n\n| 依赖 | 版本 | 用途 |\n|------|------|------|\n| `typescript` | ^5.5.0 | TypeScript 编译 |\n| `@types/node` | ^22.0.0 | Node.js 类型定义 |\n\n资料来源：[package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n\n## 开发指南\n\n### 本地开发\n\n```bash\nnpm install\nnpm run dev      # tsc --watch 监听文件变化\n```\n\n### 冒烟测试\n\n在运行 PCSX2 并启用 PINE Server 后：\n\n```bash\nnode .scratch/smoke.cjs\n```\n\n### 相关项目\n\n- **[mcp-mgba](https://github.com/dmang-dev/mcp-mgba)** — 姐妹项目，支持 mGBA Game Boy Advance 模拟器，包含按钮输入和截图功能（mcp-pine 不支持）\n- **[PINE 协议规范](https://github.com/GovanifY/pine)** — 底层 IPC 标准文档\n\n资料来源：[README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 版本历史\n\n| 版本 | 日期 | 主要变更 |\n|------|------|----------|\n| 0.2.1 | 2026-05-15 | 工具描述质量改进，完整 TDQS 模板重构 |\n| 0.2.0 | 2026-05-10 | 新增 `pine_read_range`，10 秒超时，文档化 PCSX2 管道问题 |\n| 0.1.0 | 初始版本 | 基础 MCP 工具集 |\n\n资料来源：[CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n## 许可证\n\n本项目采用 **MIT** 许可证开源。\n\n---\n\n*最后更新：基于 mcp-pine 仓库当前主分支内容生成*\n\n---\n\n<a id='page-quickstart'></a>\n\n## 快速开始\n\n### 相关页面\n\n相关主题：[安装指南](#page-installation), [模拟器配置](#page-emulator-setup), [配置参考](#page-configuration)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [src/index.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/index.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n</details>\n\n# 快速开始\n\n本页面介绍如何快速部署和配置 **mcp-pine**，这是一个基于 Model Context Protocol (MCP) 的桥接工具，用于连接 Claude 等 AI 助手与支持 PINE 协议的模拟器（PCSX2、RPCS3、Duckstation），从而实现对 PlayStation 模拟器的内存读取、写入和状态管理。\n\n## 架构概览\n\n```mermaid\ngraph TD\n    subgraph \"MCP 客户端\"\n        A[Claude Desktop / Claude Code]\n    end\n    \n    subgraph \"mcp-pine 桥接层\"\n        B[MCP Server<br/>stdio 传输]\n        C[PINE Client<br/>网络通信]\n    end\n    \n    subgraph \"目标模拟器\"\n        D[PCSX2 / RPCS3 / Duckstation]\n        E[PINE Server]\n    end\n    \n    A -->|\"MCP 协议\"| B\n    B -->|\"工具调用\"| C\n    C -->|\"PINE 协议\"| E\n    E -->|\"游戏状态\"| D\n    \n    style B fill:#e1f5fe\n    style C fill:#fff3e0\n    style E fill:#f3e5f5\n```\n\n**工作原理**：mcp-pine 作为 MCP 服务器运行在 stdio 管道上，将 MCP 工具调用转换为 PINE 协议的二进制请求，通过 TCP 或 Unix 域套接字发送至模拟器的 PINE Server，从而实现对模拟器内存空间的读写操作。\n\n## 前置要求\n\n| 组件 | 要求 | 说明 |\n|------|------|------|\n| Node.js | ≥ 18.0.0 | 用于运行 mcp-pine |\n| 包管理器 | npm / npx | 安装和执行 |\n| 模拟器 | PCSX2 1.7.x+ / RPCS3 / Duckstation | 支持 PINE 协议 |\n| MCP 客户端 | Claude Desktop / Claude Code | AI 助手界面 |\n| 操作系统 | Windows / macOS / Linux | 跨平台支持 |\n\n## 安装方式\n\n### 方式一：全局安装（推荐）\n\n```bash\nnpm install -g mcp-pine\n```\n\n安装完成后，`mcp-pine` 命令将全局可用：\n\n```bash\nmcp-pine\n```\n\n资料来源：[README.md:安装方法]()\n\n### 方式二：npx 免安装运行\n\n如仅需临时使用，无需安装依赖：\n\n```bash\nnpx -y mcp-pine\n```\n\n资料来源：[README.md:npx 安装]()\n\n### 方式三：源码本地开发\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install        # 同时运行 build（prepare hook 触发）\n```\n\n开发模式热重载：\n\n```bash\nnpm run dev        # tsc --watch 监听源码变更\n```\n\n资料来源：[README.md:clone and develop]()\n\n## 环境变量配置\n\nmcp-pine 通过环境变量控制连接目标和通信方式：\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器标识名称，用于生成 Unix 套接字路径 `<target>.sock.<slot>` |\n| `PINE_SLOT` | `28011` | PINE 槽位/端口号 |\n| `PINE_HOST` | `127.0.0.1` | TCP 目标主机（Windows 默认使用 TCP） |\n| `PINE_SOCKET_PATH` | 自动解析 | Unix 套接字路径，优先级最高 |\n| `PINE_PIPELINE_BATCH` | `1` | 请求流水线批次大小，建议保持默认 |\n\n**跨平台套接字路径解析规则**：\n\n```mermaid\ngraph TD\n    A[启动 mcp-pine] --> B{操作系统?}\n    B -->|Windows| C[使用 TCP<br/>127.0.0.1:PINE_SLOT]\n    B -->|Linux/macOS| D[检查 XDG_RUNTIME_DIR]\n    D -->|存在| E[使用 $XDG_RUNTIME_DIR/<target>.sock.<slot>]\n    D -->|不存在| F[检查 TMPDIR]\n    F -->|存在| G[使用 $TMPDIR/<target>.sock.<slot>]\n    F -->|不存在| H[使用 /tmp/<target>.sock.<slot>]\n    \n    style C fill:#ffcdd2\n    style E fill:#c8e6c9\n    style G fill:#c8e6c9\n    style H fill:#c8e6c9\n```\n\n资料来源：[README.md:Configuration]()\n\n## 模拟器配置\n\n### PCSX2 设置\n\n1. 启动 PCSX2（1.7.x Qt 或更高版本）\n2. 进入 **Settings → Advanced**\n3. 启用 **Enable PINE Server** 选项\n4. 默认槽位为 **28011**（如需修改，记下新端口并设置 `PINE_SLOT`）\n5. 加载任意游戏\n\n> **注意**：无需脚本或控制台命令，PINE 启用后始终保持运行状态。\n\n资料来源：[README.md:PCSX2]()\n\n### RPCS3 设置\n\nRPCS3 实现了兼容 PINE 操作码的 IPC 机制，但线级兼容性尚未完全测试：\n\n1. 进入 **Configuration → Advanced**\n2. 启用 **IPC Server**（具体菜单位置请参考当前 RPCS3 文档）\n3. 记录配置的端口号\n4. 运行命令：\n\n```bash\nPINE_TARGET=rpcs3 PINE_SLOT=<端口号> mcp-pine\n```\n\n资料来源：[README.md:RPCS3]()\n\n### Duckstation 设置\n\n1. 确认 Duckstation 构建版本包含 PINE 服务器（并非所有版本都包含）\n2. 如包含，设置环境变量后运行：\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=<端口号> mcp-pine\n```\n\n资料来源：[README.md:Duckstation]()\n\n## MCP 客户端配置\n\n### Claude Code (CLI)\n\n添加 MCP 服务器：\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\n验证连接状态：\n\n```bash\nclaude mcp list\n# 输出示例：pine: mcp-pine - ✓ Connected\n```\n\n资料来源：[README.md:Claude Code (CLI)]()\n\n### Claude Desktop\n\n编辑配置文件 `claude_desktop_config.json`：\n\n| 平台 | 配置文件路径 |\n|------|--------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n添加服务器配置：\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\n修改配置后需重启 Claude Desktop。\n\n资料来源：[README.md:Claude Desktop]()\n\n### 其他 MCP 客户端\n\nmcp-pine 使用标准 MCP over stdio 协议，可连接任何兼容 MCP 的客户端：\n\n```bash\nmcp-pine    # 直接运行，stdin/stdout 用于通信\n```\n\n## 可用工具一览\n\n连接成功后，以下 MCP 工具将自动注册到客户端：\n\n| 工具名称 | 功能描述 | 用途场景 |\n|----------|----------|----------|\n| `pine_ping` | 获取模拟器版本 | 连接验证 |\n| `pine_get_info` | 获取游戏完整信息 | 游戏识别 |\n| `pine_get_status` | 获取运行状态 | 状态监控 |\n| `pine_read8/16/32/64` | 读取指定地址内存 | 内存读取 |\n| `pine_write8/16/32/64` | 写入指定地址内存 | 内存修改 |\n| `pine_read_range` | 批量读取内存区域 | 大块数据读取 |\n| `pine_save_state` | 保存游戏状态 | 存档快照 |\n| `pine_load_state` | 加载游戏状态 | 恢复存档 |\n\n**地址参数说明**：\n- 地址为 EE 主地址空间的绝对字节地址\n- 多字节访问需对齐（`read16` 需 2 字节对齐，`read32` 需 4 字节对齐）\n- 推荐范围：`0x00100000-0x01FFFFFF`（EE 主内存，99% 游戏状态所在区域）\n- 未映射地址返回 PINE FAIL 响应\n\n资料来源：[src/tools.ts:工具定义]()\n\n## 快速验证流程\n\n```mermaid\nsequenceDiagram\n    participant User as 用户\n    participant MCP as Claude MCP\n    participant Bridge as mcp-pine\n    participant Emu as PCSX2\n\n    User->>Emu: 1. 启动 PCSX2 并启用 PINE Server\n    User->>MCP: 2. 配置并启动 Claude Desktop\n    MCP->>Bridge: 3. 启动 mcp-pine 进程\n    Bridge->>Emu: 4. 建立 PINE 连接\n    User->>MCP: 5. 调用 pine_ping\n    MCP->>Bridge: 6. 转发工具调用\n    Bridge->>Emu: 7. PINE Version 请求\n    Emu-->>Bridge: 8. 返回版本信息\n    Bridge-->>MCP: 9. 返回工具结果\n    MCP-->>User: 10. 显示 \"OK — emulator: PCSX2 v2.x.x\"\n```\n\n首次使用建议按以下顺序测试：\n\n```bash\n# 步骤 1：验证连接\npine_ping\n# 预期输出：OK — emulator: PCSX2 v2.x.x\n\n# 步骤 2：获取游戏信息\npine_get_info\n# 预期输出：Title, Serial, Disc CRC, Game version, Status\n\n# 步骤 3：读取内存（示例：EE RAM 起始地址）\npine_read32 address=0x00100000\n# 预期输出：ADDR_HEX: VAL_DEC (0xVAL_HEX)\n\n# 步骤 4：保存当前状态\npine_save_state slot=0\n# 预期输出：State saved to slot 0\n\n# 步骤 5：测试写入（谨慎操作）\npine_write32 address=0x00100000 value=0\n# 预期输出：Wrote 0 → ADDR_HEX\n```\n\n## 常见问题排查\n\n| 问题现象 | 原因 | 解决方案 |\n|----------|------|----------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 | 检查 `PINE_SLOT` 配置 |\n| `PINE FAIL response (0xFF)` | 模拟器拒绝请求（无游戏加载、地址未映射） | 加载游戏、检查地址有效性 |\n| 读取返回全零 | 地址在未分配区域 | 尝试 `0x00100000`（几乎总是 EE RAM 内部） |\n| 数值看起来损坏 | 字节序错误 | PINE 返回小端序，字符串读取使用 `read_range` |\n| `pine_ping` 超时（10s） | PCSX2 PINE 服务器卡死 | 完全重启 PCSX2（重新连接无效） |\n\n**重要提示**：PCSX2 的 PINE 服务器请求队列较脆弱，当超过约 6 个飞行中请求时会静默丢弃请求，导致回复错位与错误客户端配对。一旦卡死，只能通过完全重启模拟器恢复。mcp-pine 默认使用完全串行请求（`PINE_PIPELINE_BATCH=1`），实测 Loopback TCP 速度足够（4096 字节读取约 52ms）。\n\n资料来源：[README.md:Troubleshooting]()\n\n## 下一步\n\n- 阅读 [工具详细文档](./工具详细文档.md)，了解每个工具的完整参数说明\n- 参考 [内存狩猎指南](./内存狩猎指南.md)，学习定位游戏状态地址\n- 查看 [架构设计](./架构设计.md)，深入理解 PINE 协议实现\n\n---\n\n<a id='page-architecture'></a>\n\n## 系统架构\n\n### 相关页面\n\n相关主题：[PINE 协议详解](#page-pine-protocol), [工具参考](#page-tools-reference)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/index.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/index.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 系统架构\n\n## 1. 概述\n\nmcp-pine 是一个基于 Model Context Protocol (MCP) 的桥接服务器，用于连接 MCP 客户端（如 Claude Desktop、Claude Code）与游戏模拟器的 PINE (Programmable Interface for Networked Emulation) 协议接口。\n\n该项目的核心功能是让 AI 助手能够通过标准化的 MCP 工具接口与运行中的模拟器进行交互，实现内存读取、内存写入、保存/加载游戏状态等操作。资料来源：[README.md]()\n\n## 2. 整体架构\n\nmcp-pine 采用分层架构设计，从上到下依次为：\n\n| 层级 | 组件 | 职责 |\n|------|------|------|\n| MCP 协议层 | MCP Server | 暴露标准化的工具接口，处理 MCP 协议的请求/响应 |\n| 工具定义层 | Tools Registry | 定义所有可用的 MCP 工具及其参数模式 |\n| PINE 客户端层 | PineClient | 实现 PINE 协议的二进制通信 |\n| 传输层 | Socket/TCP | 处理底层网络通信，支持 Unix Domain Socket 和 TCP |\n\n```mermaid\ngraph TD\n    A[MCP 客户端<br/>Claude Desktop/Code] -->|stdio| B[MCP Server]\n    B -->|工具调用| C[Tools Registry]\n    C -->|调用方法| D[PineClient]\n    D -->|TCP/Unix Socket| E[模拟器 PINE Server]\n    \n    F[src/index.ts] --> B\n    G[src/tools.ts] --> C\n    H[src/pine.ts] --> D\n```\n\n资料来源：[src/index.ts:1-50]()\n\n## 3. 核心组件\n\n### 3.1 MCP Server\n\nMCP Server 是整个应用的入口点，负责初始化和启动服务。\n\n```typescript\n// src/index.ts 核心逻辑\nconst server = new Server(\n  { name: \"mcp-pine\", version: \"0.2.0\" },\n  { capabilities: { tools: {} } },\n);\n\nregisterTools(server, pine);\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n```\n\n关键特性：\n- 使用 `@modelcontextprotocol/sdk` 包提供的 Server 类\n- 通过 StdioServerTransport 实现标准输入/输出通信\n- 仅声明 `tools` 能力，不使用资源或提示功能\n- 工具注册由 `registerTools()` 函数完成\n\n资料来源：[src/index.ts:20-35]()\n\n### 3.2 PineClient\n\nPineClient 是 PINE 协议的客户端实现，负责与模拟器的 PINE 服务器进行二进制通信。\n\n**主要职责：**\n\n| 功能 | 方法 | 说明 |\n|------|------|------|\n| 连接管理 | `connect()` | 建立 TCP 或 Unix Socket 连接 |\n| 内存读取 | `read8/16/32/64()` | 按指定宽度读取内存 |\n| 内存写入 | `write8/16/32/64()` | 按指定宽度写入内存 |\n| 批量读取 | `readRange()` | 连续内存区域读取 |\n| 状态管理 | `saveState()` / `loadState()` | 保存/加载游戏状态 |\n| 信息查询 | `getVersion/Tittle/Id/Uuid/Status()` | 获取模拟器和游戏信息 |\n\n**连接传输方式：**\n\n```typescript\n// Unix Domain Socket (Linux/macOS)\nnet.createConnection({ path: this.descriptor.path })\n\n// TCP 连接 (Windows)\nnet.createConnection({ host: this.descriptor.host, port: this.descriptor.port })\n```\n\n资料来源：[src/pine.ts:60-90]()\n\n### 3.3 工具注册系统\n\n工具系统基于 TOOLS 数组定义，每个工具包含完整的元数据：\n\n```typescript\nconst TOOLS: Tool[] = [\n  {\n    name: \"pine_ping\",\n    description: \"PURPOSE: ...\",\n    inputSchema: { ... }\n  },\n  // ... 其他工具\n];\n```\n\n工具处理流程：\n\n```mermaid\ngraph LR\n    A[MCP 请求] -->|name + arguments| B[switch 语句]\n    B -->|匹配工具名| C[执行 PineClient 方法]\n    C -->|结果| D[ok() 格式化]\n    D -->|{content: [...]} | E[MCP 响应]\n```\n\n资料来源：[src/tools.ts:80-150]()\n\n## 4. 通信协议\n\n### 4.1 PINE Wire Protocol\n\nPINE 协议采用二进制格式，消息结构如下：\n\n| 字段 | 大小 | 字节序 | 说明 |\n|------|------|--------|------|\n| Size | 4 字节 | Little-endian | 消息总长度 |\n| Opcode | 1 字节 | - | 操作码 |\n| Payload | N 字节 | Little-endian | 操作数据 |\n\n**Opcode 定义：**\n\n| 操作码 | 值 | 功能 |\n|--------|-----|------|\n| Version | 0x01 | 获取模拟器版本 |\n| Title | 0x02 | 获取游戏标题 |\n| ID | 0x03 | 获取游戏序列号 |\n| UUID | 0x04 | 获取光盘 CRC |\n| GameVersion | 0x05 | 获取游戏版本 |\n| Status | 0x06 | 获取运行状态 |\n| Read8 | 0x10 | 读取 8 位 |\n| Read16 | 0x11 | 读取 16 位 |\n| Read32 | 0x12 | 读取 32 位 |\n| Read64 | 0x13 | 读取 64 位 |\n| Write8 | 0x14 | 写入 8 位 |\n| Write16 | 0x15 | 写入 16 位 |\n| Write32 | 0x16 | 写入 32 位 |\n| Write64 | 0x17 | 写入 64 位 |\n| SaveState | 0x30 | 保存状态 |\n| LoadState | 0x31 | 加载状态 |\n\n资料来源：[src/pine.ts:1-50]()\n\n### 4.2 请求队列管理\n\nPineClient 内部维护一个待处理请求队列：\n\n```typescript\ninterface Pending {\n  size: number;\n  resolve: (data: Buffer) => void;\n  reject: (err: Error) => void;\n}\n```\n\n接收数据时的帧解析流程：\n\n```mermaid\ngraph TD\n    A[接收数据 chunk] --> B[追加到 buffer]\n    B --> C{buffer.length >= 4?}\n    C -->|否| F[等待更多数据]\n    C -->|是| D[读取 size 字段]\n    D --> E{buffer.length >= size?}\n    E -->|否| F\n    E -->|是| G[提取完整帧]\n    G --> H[出队匹配]\n    H --> I[resolve/reject]\n    I --> B\n```\n\n每个请求包含 10 秒超时，超时后自动 reject，防止请求永久挂起。资料来源：[src/pine.ts:100-140]()\n\n### 4.3 批量读取实现\n\n`readRange()` 方法实现了高效的批量内存读取：\n\n```mermaid\ngraph TD\n    A[输入: 地址 + 长度] --> B[计算最优分块]\n    B --> C{地址对齐检查}\n    C -->|8字节对齐| D[使用 read64]\n    C -->|4字节对齐| E[使用 read32]\n    C -->|2字节对齐| F[使用 read16]\n    C -->|其他| G[使用 read8]\n    D --> H[按 PIPELINE_BATCH 分批]\n    E --> H\n    F --> H\n    G --> H\n    H --> I[Promise.all 并行]\n    I --> J[合并结果到 Buffer]\n    J --> K[返回字节数组]\n```\n\n**关键参数：**\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| `PINE_PIPELINE_BATCH` | 1 | 每批并发请求数 |\n\n默认完全串行执行以避免 PCSX2 PINE 服务器请求队列丢失问题。资料来源：[src/pine.ts:180-240]()\n\n## 5. 配置系统\n\n### 5.1 环境变量配置\n\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，用于 Unix socket 文件路径前缀 |\n| `PINE_SLOT` | `28011` | PINE 槽位号/端口号 |\n| `PINE_HOST` | `127.0.0.1` | TCP 主机地址 |\n| `PINE_SOCKET_PATH` | - | 自定义 Unix socket 路径 |\n| `PINE_PIPELINE_BATCH` | 1 | 批量读取并发数 |\n\n### 5.2 Socket 路径解析\n\n```mermaid\ngraph TD\n    A[resolveSocket] --> B{平台判断}\n    B -->|Windows| C[TCP: 127.0.0.1:PINE_SLOT]\n    B -->|Linux/macOS| D{检查 PINE_SOCKET_PATH}\n    D -->|已设置| E[使用自定义路径]\n    D -->|未设置| F{检查 XDG_RUNTIME_DIR}\n    F -->|已设置| G[使用 $XDG_RUNTIME_DIR/<target>.sock.<slot>]\n    F -->|未设置| H[使用 /tmp/<target>.sock.<slot>]\n```\n\n资料来源：[src/pine.ts:50-80]()\n\n## 6. MCP 工具清单\n\n### 6.1 连接与信息工具\n\n| 工具名 | 功能 | 返回值示例 |\n|--------|------|-----------|\n| `pine_ping` | 检测连接，获取模拟器版本 | `OK — emulator: PCSX2 2.6.3` |\n| `pine_get_info` | 获取完整游戏信息 | 标题、序列号、CRC、版本、状态 |\n| `pine_get_status` | 获取运行状态 | `Status: running` |\n\n### 6.2 内存读写工具\n\n| 工具名 | 操作数 | 对齐要求 | 说明 |\n|--------|--------|----------|------|\n| `pine_read8` | 1 字节 | 无 | 读取字节 |\n| `pine_read16` | 2 字节 | 2 字节 | 读取 16 位整数 |\n| `pine_read32` | 4 字节 | 4 字节 | 读取 32 位整数 |\n| `pine_read64` | 8 字节 | 8 字节 | 读取 64 位整数 |\n| `pine_write8` | 1 字节 | 无 | 写入字节 |\n| `pine_write16` | 2 字节 | 2 字节 | 写入 16 位整数 |\n| `pine_write32` | 4 字节 | 4 字节 | 写入 32 位整数 |\n| `pine_write64` | 8 字节 | 8 字节 | 写入 64 位整数 |\n| `pine_read_range` | 1-4096 字节 | 自动适配 | 批量读取内存区域 |\n\n### 6.3 状态管理工具\n\n| 工具名 | 参数 | 说明 |\n|--------|------|------|\n| `pine_save_state` | `slot: 0-255` | 保存游戏状态到指定槽位 |\n| `pine_load_state` | `slot: 0-255` | 从指定槽位加载游戏状态 |\n\n资料来源：[src/tools.ts:150-300]()\n\n## 7. 错误处理\n\n### 7.1 已知错误模式\n\n| 错误类型 | 表现 | 原因与处理 |\n|----------|------|-----------|\n| `Cannot reach PINE server` | 连接失败 | 模拟器未运行或 PINE 未启用 |\n| `PINE FAIL response (0xFF)` | 请求被拒绝 | 无游戏加载或地址未映射 |\n| 读取返回零值 | 返回 0x0 | 地址在未分配内存区域 |\n| 值损坏 | 数据异常 | 字节序或对齐问题 |\n| `PINE call timed out (10s)` | 超时 | PCSX2 PINE 服务器请求队列错位，需完全重启模拟器 |\n\n### 7.2 PCSX2 PINE 服务器限制\n\nPCSX2 的 PINE 服务器存在已知的请求队列脆弱性问题：\n\n- 约 7-9 个在途请求时开始出现丢包\n- 丢包后服务器回复管道永久错位\n- 任何后续请求都会超时\n- 仅重启模拟器可恢复\n\n资料来源：[README.md:60-80]()\n\n## 8. 数据模型\n\n### 8.1 模拟器状态枚举\n\n```typescript\ntype EmuStatus = \"running\" | \"paused\" | \"shutdown\" | \"unknown\";\n```\n\n状态值映射：\n\n| 原始值 | 枚举值 | 含义 |\n|--------|--------|------|\n| 0 | `running` | 游戏正在运行 |\n| 1 | `paused` | 游戏已暂停 |\n| 2 | `shutdown` | 模拟器已关闭 |\n| 其他 | `unknown` | 未知状态 |\n\n### 8.2 64 位值处理\n\n由于 JavaScript Number 类型精度限制（最大安全整数 2^53），64 位值通过字符串格式传输：\n\n```typescript\n// 返回值格式\n\"12345678901234567890 (0xB54A3E8F9A4D6E2)\"\n\n// 使用 BigInt 内部处理\nconst n = v as bigint;\nfor (let j = 0; j < 8; j++) {\n  out[off + j] = Number((n >> BigInt(8 * j)) & 0xFFn);\n}\n```\n\n资料来源：[src/pine.ts:200-220]()\n\n## 9. 依赖关系\n\n```mermaid\ngraph TD\n    A[package.json] --> B[dependencies]\n    A --> C[devDependencies]\n    \n    B --> D[\"@modelcontextprotocol/sdk ^1.12.0\"]\n    \n    C --> E[\"@types/node ^22.0.0\"]\n    C --> F[\"typescript ^5.5.0\"]\n```\n\n项目使用 TypeScript 开发，通过 `npm run dev` 启动监听模式进行开发调试。资料来源：[package.json:10-20]()\n\n## 10. 总结\n\nmcp-pine 的架构设计体现了几个关键原则：\n\n1. **分层解耦**：MCP 协议层、工具定义层、PINE 客户端层完全分离\n2. **传输透明**：根据平台自动选择 TCP 或 Unix Domain Socket\n3. **安全优先**：默认串行请求避免模拟器 PINE 服务丢包\n4. **跨平台兼容**：Windows/Linux/macOS 全平台支持\n5. **超时保护**：10 秒超时防止请求永久挂起\n\n---\n\n<a id='page-pine-protocol'></a>\n\n## PINE 协议详解\n\n### 相关页面\n\n相关主题：[系统架构](#page-architecture), [模拟器配置](#page-emulator-setup)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# PINE 协议详解\n\n## 1. 概述\n\nPINE（PlayStation Interactive Network Emulator）是一种用于 PlayStation 系列模拟器的进程间通信（IPC）协议。它允许外部工具直接读取和写入模拟器进程的内存空间，实现游戏状态检查、作弊修改、存档管理等高级功能。\n\nmcp-pine 项目是一个 PINE 协议的 MCP（Model Context Protocol）服务端实现，使 AI 助手（如 Claude）能够通过标准化的工具接口与运行中的模拟器交互。\n\n### 1.1 支持的模拟器\n\n| 模拟器 | 协议实现 | 连接方式 | 备注 |\n|--------|----------|----------|------|\n| PCSX2 | 原生 PINE | Unix Socket / TCP | 推荐使用 v1.7.x 及以上版本 |\n| RPCS3 | 镜像 PINE | TCP | 兼容性未完全测试 |\n| Duckstation | 原生 PINE | Unix Socket / TCP | 部分构建版本支持 |\n\n资料来源：[README.md:1-50]()\n\n## 2. 架构设计\n\n### 2.1 系统架构图\n\n```mermaid\ngraph TB\n    subgraph \"主机系统\"\n        A[Claude / MCP 客户端] --> B[mcp-pine 服务端]\n        B --> C[PineClient]\n        C --> D{连接类型}\n        D -->|Linux/macOS| E[Unix Socket]\n        D -->|Windows| F[TCP 127.0.0.1]\n    end\n    \n    subgraph \"模拟器进程\"\n        E --> G[PCSX2 PINE Server]\n        F --> G\n    end\n    \n    G --> H[EE 主内存 0x00100000-0x01FFFFFF]\n    G --> I[IOP 内存 0x1C000000+]\n    G --> J[Scratchpad]\n```\n\n### 2.2 核心组件\n\n**PineClient** 是协议的核心实现类，负责：\n\n- 底层的 Socket 连接管理\n- PINE 操作码的发送与响应解析\n- 读写请求的批量处理\n- 超时控制与错误处理\n\n资料来源：[src/pine.ts:60-100]()\n\n## 3. PINE 操作码定义\n\n### 3.1 操作码表\n\n| 操作码名称 | 数值 | 功能描述 | 返回类型 |\n|------------|------|----------|----------|\n| `Op.Version` | 0x01 | 获取模拟器版本 | UTF-8 字符串 |\n| `Op.Title` | 0x02 | 获取游戏标题 | UTF-8 字符串 |\n| `Op.ID` | 0x03 | 获取游戏序列号 | UTF-8 字符串 |\n| `Op.UUID` | 0x04 | 获取光盘 CRC | UTF-8 字符串 |\n| `Op.GameVersion` | 0x05 | 获取游戏版本 | UTF-8 字符串 |\n| `Op.Status` | 0x0F | 获取模拟器运行状态 | 32 位整数 |\n| `Op.SaveState` | 0x10 | 保存当前状态到指定槽位 | 无 |\n| `Op.LoadState` | 0x11 | 从指定槽位加载状态 | 无 |\n| `Op.Read8` | 0x20 | 读取 8 位数据 | 字节 |\n| `Op.Read16` | 0x21 | 读取 16 位数据 | 小端整数 |\n| `Op.Read32` | 0x22 | 读取 32 位数据 | 小端整数 |\n| `Op.Read64` | 0x23 | 读取 64 位数据 | 小端整数 |\n| `Op.Write8` | 0x30 | 写入 8 位数据 | 无 |\n| `Op.Write16` | 0x31 | 写入 16 位数据 | 无 |\n| `Op.Write32` | 0x32 | 写入 32 位数据 | 无 |\n| `Op.Write64` | 0x33 | 写入 64 位数据 | 无 |\n\n资料来源：[src/pine.ts:1-30]()\n\n### 3.2 状态码定义\n\n模拟器运行状态通过 32 位小端整数返回：\n\n| 状态值 | 含义 |\n|--------|------|\n| 0 | 运行中 (running) |\n| 1 | 暂停 (paused) |\n| 2 | 已关闭 (shutdown) |\n| 其他 | 未知 (unknown) |\n\n资料来源：[src/pine.ts:40-45]()\n\n## 4. 协议帧格式\n\n### 4.1 请求帧结构\n\n```\n+----------------+----------------+----------------+\n|  Frame Size    |  Opcode (1B)   |  Arguments...  |\n|  (UInt32 LE)   |                |                |\n+----------------+----------------+----------------+\n```\n\n- **Frame Size**: 4 字节，小端无符号整数，表示整个帧的字节数（包括自身）\n- **Opcode**: 1 字节，操作码标识符\n- **Arguments**: 可选参数数据\n\n### 4.2 响应帧结构\n\n```\n+----------------+----------------+----------------+\n|  Frame Size    |  Status (1B)   |  Payload...    |\n|  (UInt32 LE)   |  0x00=OK 0xFF=FAIL              |\n+----------------+----------------+----------------+\n```\n\n- **Status**: `0x00` 表示成功，`0xFF` 表示失败\n- **Payload**: 成功时包含返回数据，失败时可能为空\n\n### 4.3 帧解析流程\n\n```mermaid\ngraph TD\n    A[接收数据块] --> B{缓冲区长度 >= 4?}\n    B -->|否| C[等待更多数据]\n    B -->|是| D[读取 Frame Size]\n    D --> E{缓冲区长度 >= Frame Size?}\n    E -->|否| F[等待更多数据]\n    E -->|是| G[提取完整帧]\n    G --> H[解析 Status 字节]\n    H --> I{Status == 0x00?}\n    I -->|是| J[解析 Payload]\n    I -->|否| K[抛出 PINE FAIL 错误]\n    J --> L[匹配 Pending 请求]\n    K --> L\n    L --> M[返回结果给调用者]\n```\n\n资料来源：[src/pine.ts:100-150]()\n\n## 5. 连接管理\n\n### 5.1 连接参数\n\n| 参数 | 环境变量 | 默认值 | 说明 |\n|------|----------|--------|------|\n| 模拟器名称 | `PINE_TARGET` | `pcsx2` | Unix Socket 文件名前缀 |\n| 槽位/端口 | `PINE_SLOT` | `28011` | Unix Socket 序号或 TCP 端口 |\n\n### 5.2 连接路径解析\n\n```typescript\n// Linux/macOS: Unix Socket\n$XDG_RUNTIME_DIR/<target>.sock.<slot>\n$TMPDIR/<target>.sock.<slot>\n/tmp/<target>.sock.<slot>\n\n// Windows: TCP\n127.0.0.1:<slot>\n```\n\n资料来源：[src/pine.ts:50-80]()\n\n### 5.3 超时控制\n\n每个 PINE 调用都设置了 **10 秒超时**。如果模拟器未响应，请求将自动拒绝，防止无限等待。\n\n资料来源：[CHANGELOG.md:30-40]()\n\n## 6. 内存读写机制\n\n### 6.1 地址空间\n\nPS2 模拟器的主要内存区域：\n\n| 区域 | 地址范围 | 大小 | 说明 |\n|------|----------|------|------|\n| EE 主内存 | 0x00100000 - 0x01FFFFFF | ~31 MB | 游戏状态主要存储区 |\n| IOP 内存 | 0x1C000000+ | 可变 | I/O 处理器内存 |\n| Scratchpad | 特定区域 | 较小 | 高速缓存 |\n\n资料来源：[src/tools.ts:20-30]()\n\n### 6.2 数据编码\n\n所有多字节数据均使用 **小端序**（Little Endian）编码：\n\n```\n地址:     [0x00] [0x01] [0x02] [0x03]\n数据:     LSB    ...    ...    MSB\n```\n\n字符串使用 **UTF-8 编码**，以空字符 (`\\0`) 结尾，读取时自动去除尾部空字符。\n\n资料来源：[src/pine.ts:25-35]()\n\n### 6.3 对齐要求\n\n| 操作宽度 | 对齐要求 | 未对齐时的行为 |\n|----------|----------|----------------|\n| 8 位 | 无 | 正常工作 |\n| 16 位 | 2 字节对齐 | 返回对齐地址下方的数据，静默损坏 |\n| 32 位 | 4 字节对齐 | 返回对齐地址下方的数据，静默损坏 |\n| 64 位 | 8 字节对齐 | 返回对齐地址下方的数据，静默损坏 |\n\n**重要警告**: PCSX2 的 PINE 服务端**不强制**对齐访问，未对齐的地址会静默返回错误数据而无任何错误提示。\n\n资料来源：[src/tools.ts:30-45]()\n\n### 6.4 批量读取实现\n\n由于 PINE 协议本身不提供原生批量读取功能，`read_range` 工具通过客户端实现的序列读取实现：\n\n```mermaid\ngraph LR\n    A[请求: 4096 字节] --> B{计算最优步长}\n    B --> C[起始地址 % 8 == 0 且剩余 >= 8?]\n    C -->|是| D[read64]\n    C -->|否| E{起始地址 % 4 == 0 且剩余 >= 4?}\n    E -->|是| F[read32]\n    E -->|否| G{起始地址 % 2 == 0?}\n    G -->|是| H[read16]\n    G -->|否| I[read8]\n    D --> J[移动游标]\n    F --> J\n    H --> J\n    I --> J\n    J --> K{还有剩余?}\n    K -->|是| B\n    K -->|否| L[组装 Buffer 返回]\n```\n\n资料来源：[src/pine.ts:50-80]()\n\n## 7. PCSX2 已知限制\n\n### 7.1 请求队列脆弱性\n\nPCSX2 的 PINE 服务端存在一个关键缺陷：\n\n- 当 **同时发送约 7-9 个未完成请求**时，服务端可能静默丢弃某些请求\n- 一旦发生请求丢失，响应管道将与客户端失去同步\n- 之后**所有**请求都会超时，包括 `pine_ping`\n- **唯一恢复方法**: 完全重启 PCSX2\n\n### 7.2 性能数据\n\n| 操作 | 耗时 | 说明 |\n|------|------|------|\n| 单次 read64 | ~0.1 ms | 单次往返延迟 |\n| 完整 4096 字节读取 | ~52 ms | 串行执行，约两帧 |\n\n### 7.3 流水线配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_PIPELINE_BATCH` | 1 | 每批发送的请求数，增大可降低延迟但有同步风险 |\n\n资料来源：[CHANGELOG.md:40-60]()\n\n## 8. 错误处理\n\n### 8.1 错误类型\n\n| 错误现象 | 可能原因 | 解决方案 |\n|----------|----------|----------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 | 检查 `PINE_SLOT` 设置 |\n| `PINE FAIL response (0xFF)` | 无游戏加载、地址未映射 | 确认游戏已加载，尝试 0x00100000 |\n| 读取返回全零 | 地址在未分配区域 | 尝试 EE 主内存起始地址 |\n| 数据看起来损坏 | 字节序误解 | PINE 返回小端序 |\n| `PINE call timed out (10s)` | PCSX2 队列同步失败 | 完全重启 PCSX2 |\n\n资料来源：[README.md:80-100]()\n\n## 9. API 参考\n\n### 9.1 核心方法签名\n\n```typescript\nclass PineClient {\n  // 元数据查询\n  async getVersion(): Promise<string>\n  async getTitle(): Promise<string>\n  async getId(): Promise<string>\n  async getUuid(): Promise<string>\n  async getGameVersion(): Promise<string>\n  async getStatus(): Promise<EmuStatus>\n\n  // 内存读取\n  async read8(addr: number): Promise<number>\n  async read16(addr: number): Promise<number>\n  async read32(addr: number): Promise<number>\n  async read64(addr: number): Promise<bigint>\n  async readRange(addr: number, length: number): Promise<Buffer>\n\n  // 内存写入\n  async write8(addr: number, value: number): Promise<void>\n  async write16(addr: number, value: number): Promise<void>\n  async write32(addr: number, value: number): Promise<void>\n  async write64(addr: number, value: bigint): Promise<void>\n\n  // 存档管理\n  async saveState(slot: number): Promise<void>\n  async loadState(slot: number): Promise<void>\n}\n```\n\n### 9.2 64 位值处理\n\n由于 JavaScript 的 `number` 类型只能安全表示 2^53 以内的整数，`read64` 和 `write64` 方法使用 `bigint` 类型：\n\n```typescript\n// 读取\nconst value: bigint = await pine.read64(0x12345678)\n\n// 写入\nawait pine.write64(0x12345678, 12345678901234n)\n```\n\n资料来源：[src/pine.ts:40-50]()\n\n## 10. 与 MCP 工具的映射\n\n| MCP 工具名称 | 底层 PINE 操作 | 功能 |\n|--------------|----------------|------|\n| `pine_ping` | Version | 连接测试 |\n| `pine_get_info` | Title + ID + UUID + GameVersion + Status | 批量获取游戏信息 |\n| `pine_get_status` | Status | 获取运行状态 |\n| `pine_read8/16/32/64` | Read8/16/32/64 | 单值读取 |\n| `pine_read_range` | 串行调用 Read* | 批量读取 |\n| `pine_write8/16/32/64` | Write8/16/32/64 | 单值写入 |\n| `pine_save_state` | SaveState | 保存存档 |\n| `pine_load_state` | LoadState | 加载存档 |\n\n资料来源：[src/tools.ts:100-200]()\n\n## 11. 项目信息\n\n| 项目元数据 | 值 |\n|------------|-----|\n| 项目名称 | mcp-pine |\n| 许可证 | MIT |\n| 主要依赖 | @modelcontextprotocol/sdk ^1.12.0 |\n| 运行时 | Node.js / TypeScript |\n\n资料来源：[package.json:1-30]()\n\n---\n\n<a id='page-tools-reference'></a>\n\n## 工具参考\n\n### 相关页面\n\n相关主题：[内存操作指南](#page-memory-operations), [存档状态管理](#page-savestate)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n</details>\n\n# 工具参考\n\nmcp-pine 提供了一套完整的 MCP 工具，用于与支持 PINE（Platform Independent Network Environment）协议的模拟器进行交互通信。通过这些工具，用户可以实现对模拟器运行状态的监控、内存读写操作以及存档管理等功能。\n\n## 工具分类概览\n\nmcp-pine 的工具集按照功能可分为四大类别：\n\n| 类别 | 工具数量 | 用途 |\n|------|----------|------|\n| 连接与自检 | 2 | 连接验证、模拟器信息获取 |\n| 内存读取 | 5 | 单字节到64位值的读取，支持范围读取 |\n| 内存写入 | 4 | 8/16/32/64位值写入 |\n| 存档管理 | 2 | 游戏状态保存与加载 |\n\n资料来源：[src/tools.ts:90-140]()\n\n## 连接与自检工具\n\n### pine_ping\n\n**用途**：验证与模拟器 PINE 服务器的连接状态，并获取模拟器版本信息。\n\n**参数**：无\n\n**返回格式**：`OK — emulator: <version>`\n\n**使用场景**：在执行其他操作前验证连接是否正常。如果返回\"Cannot reach PINE server\"错误，表明模拟器未运行、PINE 未启用或端口配置不匹配。资料来源：[src/tools.ts:95-98]()\n\n### pine_get_info\n\n**用途**：获取当前运行游戏的完整信息摘要，包括游戏标题、序列号、Disc CRC、游戏版本和运行状态。\n\n**参数**：无\n\n**返回格式**：\n\n```\nTitle:        <游戏标题>\nSerial:       <序列号>\nDisc CRC:     <CRC校验值>\nGame version: <游戏版本>\nStatus:       <运行状态>\n```\n\n**使用场景**：快速确认当前加载的游戏及其状态，适用于多游戏环境下的上下文切换。资料来源：[src/tools.ts:100-115]()\n\n### pine_get_status\n\n**用途**：获取模拟器当前的运行状态。\n\n**参数**：无\n\n**返回格式**：`Status: <running|paused|shutdown|unknown>`\n\n**使用场景**：在执行存档操作前确认游戏状态，或监控长时间运行任务的状态变化。资料来源：[src/tools.ts:117-119]()\n\n## 内存读取工具\n\n所有内存读取工具均操作 PS2 主机的 EE（Emotion Engine）主地址空间，采用小端字节序。地址参数支持十六进制字面量（如 `0x00200000`）。\n\n### 地址参数通用说明\n\n| 字段 | 描述 |\n|------|------|\n| 有效范围 | `0x00100000-0x01FFFFFF`（EE 主 RAM，99%的游戏状态在此区域）|\n| 对齐要求 | 多字节访问必须按对应字节数对齐；PCSX2 的 PINE 不强制对齐，未对齐访问会静默返回损坏数据 |\n| 错误处理 | 未映射或无效地址返回 PINE FAIL 响应 |\n\n> **重要**：如果需要读取未对齐的多字节数据，应使用 `pine_read_range` 并自行组装字节。\n\n资料来源：[src/tools.ts:30-50]()\n\n### pine_read8\n\n**用途**：读取单个字节。\n\n**对齐要求**：无对齐要求。\n\n**返回格式**：`ADDR_HEX: VAL_DEC (0xVAL_HEX)`\n\n### pine_read16\n\n**用途**：读取16位无符号小端值，适用于字符编码、游戏事件标志等。\n\n**对齐要求**：2字节对齐。\n\n**返回格式**：与 `pine_read8` 格式相同。\n\n### pine_read32\n\n**用途**：读取32位无符号小端值，适用于 PS2 指针、计时器、分数等常见游戏状态字段。\n\n**对齐要求**：4字节对齐。\n\n**返回格式**：与 `pine_read8` 格式相同。\n\n### pine_read64\n\n**用途**：读取64位无符号值，适用于完整的 PS2 指针、大型 ID、压缩双字状态。PS2 EE 是128位 MIPS 处理器，大量游戏状态确实存在于64位槽位中。\n\n**对齐要求**：8字节对齐。\n\n**返回值说明**：由于 JavaScript 无法精确表示超过 2^53 的整数，64位值以十进制字符串形式返回。资料来源：[src/tools.ts:120-145]()\n\n### pine_read_range\n\n**用途**：批量读取最多4096字节的连续内存区域。\n\n**参数**：\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| address | integer | 起始地址 |\n| length | integer | 要读取的字节数（最大4096）|\n\n**实现原理**：PINE 协议本身没有原生批量读取功能，`pine_read_range` 在客户端通过序列化调用序列实现。每次调用选择最大对齐宽度（从8到1递减）。资料来源：[src/pine.ts:90-130]()\n\n**性能指标**：\n\n- 完整4096字节读取耗时约52毫秒（PCSX2 v2.6.3，loopback TCP）\n- 少于两个模拟帧，适合大多数工作负载\n\n**注意事项**：PCSX2 的 PINE 服务器存在请求队列脆弱性问题。超过约7个飞行中请求时会静默丢弃请求，导致回复管道错位，后续所有请求超时，直至模拟器重启。因此默认情况下调用完全序列化执行。可通过环境变量 `PINE_PIPELINE_BATCH` 调整批处理大小（默认为1）。资料来源：[src/pine.ts:95-110]()\n\n## 内存写入工具\n\n所有写入工具均具有破坏性，会覆盖指定地址的现有数据。\n\n### pine_write8 / pine_write16 / pine_write32 / pine_write64\n\n**用途**：向模拟器内存写入指定宽度的值。\n\n**参数**：\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| address | integer | 目标地址（必须符合对应宽度对齐要求）|\n| value | integer/bigint | 要写入的值 |\n\n**返回格式**：`Wrote VAL_HEX → ADDR_HEX`\n\n**对齐要求**：与对应的读取工具相同。未对齐写入可能导致静默数据损坏。\n\n**错误场景**：\n\n- 地址未对齐：数据写入错误位置\n- 地址未映射：PINE FAIL 响应\n- 写入只读区域：行为取决于模拟器实现\n\n资料来源：[src/tools.ts:145-170]()\n\n## 存档管理工具\n\n### pine_save_state\n\n**用途**：将当前游戏状态保存到指定槽位。\n\n**参数**：\n\n| 参数 | 类型 | 范围 | 描述 |\n|------|------|------|------|\n| slot | integer | 0-255 | 存档槽位编号 |\n\n**槽位约定**：PCSX2 图形界面通常使用 F1-F10 对应槽位0-9，但 PINE 协议支持完整的 0-255 范围。存档文件存储在模拟器的游戏专属目录中：\n\n- Windows：`%USERPROFILE%\\Documents\\PCSX2\\sstates`\n- Linux/macOS：`~/.config/PCSX2/sstates`\n\n**文件命名格式**：`<serial> (<crc>).<slot>.p2s`\n\n**警告**：保存到已有存档的槽位会覆盖原有数据，此操作不可逆。资料来源：[src/tools.ts:70-85]()\n\n### pine_load_state\n\n**用途**：从指定槽位加载游戏状态。\n\n**参数**：与 `pine_save_state` 相同。\n\n**返回格式**：`Loaded state from slot <n>`\n\n**使用场景**：快速恢复之前的游戏进度，适用于：\n\n- 尝试不同游戏决策前的快照\n- 回归测试\n- 调试时的状态重现\n\n**前置条件**：需要先加载对应游戏的 ISO 文件，否则存档可能不兼容。\n\n## 工具调用流程\n\n以下流程图展示了典型工具调用序列的执行路径：\n\n```mermaid\ngraph TD\n    A[MCP 客户端发起调用] --> B{工具类型}\n    \n    B -->|查询类<br/>ping/get_info/get_status| C[构建请求帧]\n    B -->|读取类<br/>read8/16/32/64/range| C\n    B -->|写入类<br/>write8/16/32/64| C\n    B -->|存档类<br/>save/load_state| C\n    \n    C --> D[加入待处理队列]\n    D --> E[PINE 协议编码]\n    E --> F{连接状态}\n    \n    F -->|已连接| G[发送请求]\n    F -->|未连接| H[建立连接<br/>TCP Unix Socket]\n    H --> G\n    \n    G --> I{等待响应}\n    I -->|超时 10s| J[抛出错误]\n    I -->|收到响应| K{响应码}\n    \n    K -->|成功 0x00| L[解码响应]\n    K -->|失败 0xFF| M[返回 PINE FAIL]\n    \n    L --> N[返回格式化结果]\n    M --> O[错误处理]\n```\n\n## 环境变量配置\n\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器标识名，用于 Unix socket 文件路径前缀（Linux/macOS）或 TCP 连接标识 |\n| `PINE_SLOT` | `28011` | PINE 槽位/端口号 |\n| `PINE_HOST` | `127.0.0.1` | TCP 连接主机地址 |\n| `PINE_SOCKET_PATH` | 自动解析 | Unix socket 路径，覆盖其他 socket 相关配置 |\n| `PINE_PIPELINE_BATCH` | `1` | 批量请求数量，仅在了解 PCSX2 PINE 限制时调整 |\n\n**Socket 路径解析逻辑**（Linux/macOS）：\n\n1. 优先使用 `XDG_RUNTIME_DIR`\n2. 其次尝试 `TMPDIR`\n3. 最后回退到 `/tmp`\n\n资料来源：[README.md:40-55]()\n\n## 错误处理与故障排除\n\n| 错误现象 | 可能原因 | 解决方案 |\n|----------|----------|----------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 | 检查 `PINE_SLOT` 配置，确认模拟器设置中已启用 PINE |\n| `PINE FAIL response` (0xFF) | 未加载游戏或地址未映射 | 确保游戏已加载，尝试地址 `0x00100000` |\n| 读取返回全零 | 地址在未分配区域 | 从 EE RAM 常用区域开始（`0x00100000`）|\n| 值看起来损坏 | 字节序误解 | PINE 返回小端序；字符串使用 `read_range` 逐字节读取 |\n| `PINE call timed out (10s)` ping 后频繁使用 | PCSX2 PINE 请求队列错位 | 完全重启 PCSX2（仅重新连接无效）|\n\n### PCSX2 PINE 服务器已知限制\n\nPCSX2 的 PINE 服务器存在一个已知的脆弱性问题：当飞行中请求超过约6个时，服务器会静默丢弃请求，导致回复管道错位。一旦发生这种情况，即使 `pine_ping` 也会超时，唯一恢复方法是完全重启模拟器。\n\n为避免此问题：\n\n- 默认情况下 `mcp-pine` 完全序列化所有请求\n- Loopback TCP 速度足够快，完整4KB读取仅需约52毫秒\n- 如需更低延迟且可容忍偶发的模拟器重启，可设置 `PINE_PIPELINE_BATCH=2` 或更高\n\n资料来源：[src/pine.ts:95-110]()\n\n## 工具描述质量标准\n\nmcp-pine 的每个工具描述都遵循 Glama 的工具定义质量评分（TDQS）标准，确保以下方面完整：\n\n1. **目的明确性**：每个工具一句话说明其操作\n2. **使用指南**：何时使用此工具而非其兄弟工具\n3. **行为透明**：副作用、错误条件、破坏性操作说明\n4. **参数语义**：超出 JSON Schema 的上下文信息\n5. **简洁性**：无冗余描述\n6. **上下文完整性**：错误模式、对齐要求、返回值格式\n\n资料来源：[CHANGELOG.md:20-35]()\n\n## 快速参考表\n\n| 工具名 | 参数 | 返回类型 | 破坏性 |\n|--------|------|----------|--------|\n| `pine_ping` | - | string | 否 |\n| `pine_get_info` | - | string | 否 |\n| `pine_get_status` | - | string | 否 |\n| `pine_read8` | address | string | 否 |\n| `pine_read16` | address | string | 否 |\n| `pine_read32` | address | string | 否 |\n| `pine_read64` | address | string | 否 |\n| `pine_read_range` | address, length | string | 否 |\n| `pine_write8` | address, value | string | 是 |\n| `pine_write16` | address, value | string | 是 |\n| `pine_write32` | address, value | string | 是 |\n| `pine_write64` | address, value | string | 是 |\n| `pine_save_state` | slot | string | 是 |\n| `pine_load_state` | slot | string | 是 |\n\n---\n\n<a id='page-memory-operations'></a>\n\n## 内存操作指南\n\n### 相关页面\n\n相关主题：[工具参考](#page-tools-reference), [使用范例](#page-recipes)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 内存操作指南\n\n## 概述\n\nmcp-pine 提供的核心功能之一是通过 PINE（PlayStation Interface for Networked Entertainment）协议对运行中的模拟器进行实时内存读写操作。该功能允许用户直接访问 PS2/PS3/PSP 等平台的内存地址空间，实现游戏状态检测、作弊修改、运行时数据分析等高级操作。\n\n内存操作由 8 个 MCP 工具组成，分为**读取**和**写入**两大类：\n\n| 类别 | 工具 | 数据宽度 |\n|------|------|----------|\n| 读取 | `pine_read8` | 1 字节 |\n| 读取 | `pine_read16` | 2 字节 |\n| 读取 | `pine_read32` | 4 字节 |\n| 读取 | `pine_read64` | 8 字节 |\n| 读取 | `pine_read_range` | 批量（最大 4096 字节） |\n| 写入 | `pine_write8` | 1 字节 |\n| 写入 | `pine_write16` | 2 字节 |\n| 写入 | `pine_write32` | 4 字节 |\n| 写入 | `pine_write64` | 8 字节 |\n\n资料来源：[src/tools.ts:56-130]()\n\n## 地址空间与内存布局\n\n### PS2 EE 主内存\n\nPS2 的 Emotion Engine（EE）主内存地址空间是最常用的访问区域：\n\n| 地址范围 | 说明 |\n|----------|------|\n| `0x00100000` - `0x01FFFFFF` | EE 主 RAM（游戏状态主要存储区） |\n| `0x1C000000`+ | IOP RAM（声音/输入子系统） |\n| 其他 | 预留/映射区域 |\n\n> 💡 建议从 `0x00100000` 开始探测，该地址几乎所有游戏都会加载到 EE RAM 中。\n\n资料来源：[src/tools.ts:20-25]()\n\n### 连接传输方式\n\n| 平台 | 传输方式 | 地址格式 |\n|------|----------|----------|\n| Linux/macOS | Unix Domain Socket | `$XDG_RUNTIME_DIR/<PINE_TARGET>.sock.<PINE_SLOT>` |\n| Windows | TCP | `127.0.0.1:<PINE_SLOT>` |\n\n资料来源：[README.md:45-50]()\n\n## 读取操作\n\n### 单值读取工具\n\n| 工具 | 对齐要求 | 返回格式 |\n|------|----------|----------|\n| `pine_read8` | 无 | `ADDR: VAL_DEC (0xVAL_HEX)` |\n| `pine_read16` | 2 字节对齐 | `ADDR: VAL_DEC (0xVAL_HEX)` |\n| `pine_read32` | 4 字节对齐 | `ADDR: VAL_DEC (0xVAL_HEX)` |\n| `pine_read64` | 8 字节对齐 | 字符串格式（JS 无法原生表示完整 u64） |\n\n#### 64 位值处理\n\n由于 JavaScript Number 类型最大只能精确表示到 `2^53`，`pine_read64` 和 `pine_write64` 采用**十进制字符串**作为值编码，避免精度丢失。\n\n```typescript\n// 资料来源：src/pine.ts:55-60\nasync read64(addr: number): Promise<bigint> {\n  const r = await this.call(Op.Read64, this._addr(addr));\n  return r.readBigUInt64LE(0);\n}\n```\n\n资料来源：[src/tools.ts:100-105]()\n\n### 批量读取：pine_read_range\n\n`pine_read_range` 是最高效的批量读取工具，单次调用最多读取 4096 字节：\n\n```typescript\n// 资料来源：src/pine.ts:75-95\nasync readRange(start: number, length: number): Promise<Buffer> {\n  // 计算最优读取步骤：优先使用最大对齐宽度\n  let n: 1 | 2 | 4 | 8;\n  if      (cursor % 8 === 0 && remaining >= 8) n = 8;\n  else if (cursor % 4 === 0 && remaining >= 4) n = 4;\n  else if (cursor % 2 === 0 && remaining >= 2) n = 2;\n  else                                          n = 1;\n}\n```\n\n#### 读取策略\n\n工具内部采用**自适应分块策略**，在每个步骤选择最大可用对齐宽度：\n\n```mermaid\ngraph TD\n    A[开始读取] --> B{地址 % 8 === 0 ?}\n    B -->|是 且 剩余 ≥ 8| C[read64 - 8字节]\n    B -->|否| D{地址 % 4 === 0 ?}\n    D -->|是 且 剩余 ≥ 4| E[read32 - 4字节]\n    D -->|否| F{地址 % 2 === 0 ?}\n    F -->|是 且 剩余 ≥ 2| G[read16 - 2字节]\n    F -->|否| H[read8 - 1字节]\n    C --> I[移动指针]\n    E --> I\n    G --> I\n    H --> I\n    I --> J{还有数据?}\n    J -->|是| B\n    J -->|否| K[组装结果 Buffer]\n```\n\n#### 流水线控制\n\nPINE 协议本身**没有原生批量读取指令**，`pine_read_range` 通过发送多个单次读取请求实现。默认配置为**完全串行**执行以避免 PCSX2 请求队列错位：\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_PIPELINE_BATCH` | `1` | 每批发送请求数；`1` = 完全串行（安全） |\n\n> ⚠️ PCSX2 的 PINE 服务器存在已知缺陷：当流水线中有约 7-9 个请求时，会静默丢弃请求，导致后续所有回复与客户端错位，此时即使 `pine_ping` 也会超时，只能重启模拟器恢复。\n\n实测性能（PCSX2 v2.6.3，localhost）：\n\n| 操作 | 耗时 |\n|------|------|\n| 完整 4096 字节读取 | ~52 ms |\n| 单次 read32 | ~0.1 ms |\n\n资料来源：[src/pine.ts:100-115]()\n\n## 写入操作\n\n### 写入工具\n\n| 工具 | 对齐要求 | 参数类型 |\n|------|----------|----------|\n| `pine_write8` | 无 | `number` |\n| `pine_write16` | 2 字节对齐 | `number` |\n| `pine_write32` | 4 字节对齐 | `number` |\n| `pine_write64` | 8 字节对齐 | `number`（JS 会损失精度，模拟器端可能截断） |\n\n> ⚠️ **破坏性操作**：写入会直接修改游戏内存，可能导致游戏崩溃或存档损坏。\n\n```typescript\n// 资料来源：src/tools.ts:62-70\ncase \"pine_write8\": {\n  await pine.write8(addr(), p.value as number);\n  return ok(`Wrote ${fmtHex(p.value as number)} → ${addrHex(addr())}`);\n}\n```\n\n## 对齐要求与边界处理\n\n### PCSX2 对齐特性\n\n**关键警告**：PCSX2 的 PINE 实现**不强制对齐检查**。对未对齐地址的多字节访问会静默返回对齐地址的数据，造成数据损坏。\n\n| 访问宽度 | 对齐要求 | 错误行为 |\n|----------|----------|----------|\n| 8 位 (read8/write8) | 无 | 无 |\n| 16 位 (read16/write16) | 地址 % 2 === 0 | 未对齐时返回对齐地址数据 |\n| 32 位 (read32/write32) | 地址 % 4 === 0 | 未对齐时返回对齐地址数据 |\n| 64 位 (read64/write64) | 地址 % 8 === 0 | 未对齐时返回对齐地址数据 |\n\n### 未对齐访问方案\n\n如需读取未对齐地址的数据，建议：\n\n1. 使用 `pine_read_range` 读取足够宽的字节范围\n2. 在客户端自行组装字节序\n\n```typescript\n// 示例：读取未对齐的 32 位值\nconst bytes = await pine.readRange(0x00102001, 4);  // 从 0x00102000 开始读 4 字节\nconst value = bytes.readUInt32LE(1);  // 从偏移 1 开始解释\n```\n\n资料来源：[src/tools.ts:10-20]()\n\n## 字节序\n\nPINE 协议使用 **小端序（Little-Endian）** 编码多字节值：\n\n- LSB 存储在起始地址\n- MSB 存储在起始地址 + 宽度 - 1\n\n```mermaid\ngraph LR\n    subgraph \"32 位值 0x12345678 在地址 0x00100000\"\n        A0[\"0x00100000: 0x78 (LSB)\"]\n        A1[\"0x00100001: 0x56\"]\n        A2[\"0x00100002: 0x34\"]\n        A3[\"0x00100003: 0x78 (MSB)\"]\n    end\n```\n\n> 💡 字符串读取（`getTitle`、`getId` 等）使用 UTF-8 编码，通过 `readString` 方法处理截断空字节。\n\n资料来源：[src/pine.ts:35-40]()\n\n## 超时与错误处理\n\n### 超时机制\n\n每个 PINE 调用都有 **10 秒超时**。超时后抛出 `PINE call timed out` 错误：\n\n```\n原因：\n1. 模拟器未运行\n2. PINE 服务器未启用（PCSX2: Settings → Advanced → Enable PINE Server）\n3. PINE_SLOT 与模拟器配置不匹配\n4. PCSX2 PINE 请求队列错位（需重启模拟器）\n```\n\n资料来源：[README.md:70-80]()\n\n### 常见错误\n\n| 错误信息 | 原因 | 解决方案 |\n|----------|------|----------|\n| `Cannot reach PINE server` | 连接失败 | 检查模拟器运行状态和 PINE_SLOT |\n| `PINE FAIL response (0xFF)` | 地址无映射或无游戏加载 | 确认游戏已加载，使用 `0x00100000` 探测 |\n| 返回全零 | 地址未分配 | 尝试 `0x00100000` |\n| 数据异常 | 字节序误判或对齐错误 | 检查对齐，使用 `read_range` 手动组装 |\n\n## 完整使用流程\n\n```mermaid\ngraph TD\n    A[启动模拟器] --> B[启用 PINE 服务器]\n    B --> C[运行 mcp-pine]\n    C --> D[调用 pine_ping 验证连接]\n    D --> E{连接成功?}\n    E -->|否| F[检查配置和模拟器状态]\n    F --> B\n    E -->|是| G[调用 pine_get_info 获取游戏信息]\n    G --> H[选择目标地址]\n    H --> I[调用 read/write 工具]\n    I --> J{操作成功?}\n    J -->|否| K[检查对齐/地址/超时]\n    K --> I\n    J -->|是| L[处理返回值]\n```\n\n## 工具调用示例\n\n### 读取玩家分数（假设在 0x00201000）\n\n```\n工具: pine_read32\n参数: { \"address\": 2113536 }\n返回值: \"0x00201000: 9500 (0x0000251c)\"\n```\n\n### 批量扫描内存\n\n```\n工具: pine_read_range\n参数: { \"address\": 1048576, \"length\": 4096 }\n返回值: <Buffer: 4096 bytes>\n```\n\n### 修改生命值\n\n```\n工具: pine_write32\n参数: { \"address\": 2097152, \"value\": 999 }\n返回值: \"Wrote 0x000003e7 → 0x00200000\"\n```\n\n## 环境变量配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称前缀（socket 文件名） |\n| `PINE_SLOT` | `28011` | PINE 槽位号（Linux/macOS 为 socket 后缀，Windows 为 TCP 端口） |\n| `PINE_HOST` | `127.0.0.1` | 主机地址（可覆盖） |\n| `PINE_SOCKET_PATH` | 自动 | 完整 socket 路径（完全覆盖自动解析） |\n| `PINE_PIPELINE_BATCH` | `1` | 批量请求数（建议仅在非 PCSX2 模拟器上增加） |\n\n资料来源：[README.md:45-55]()\n\n## 安全注意事项\n\n1. **写入操作不可逆**：修改内存会导致游戏状态永久改变，可能造成存档损坏\n2. **不要过度流水线**：PCSX2 在超过 ~6 个并行请求时会静默失败\n3. **定期保存状态**：使用 `pine_save_state` 在修改前备份当前游戏状态\n4. **验证对齐**：未对齐写入会产生静默数据损坏\n\n## 相关工具\n\n| 工具 | 功能 |\n|------|------|\n| `pine_ping` | 验证连接（会话开始时调用） |\n| `pine_get_info` | 获取游戏元数据（标题、序列号、CRC） |\n| `pine_get_status` | 获取运行状态（running/paused/shutdown） |\n| `pine_save_state` | 保存当前游戏状态到槽位 |\n| `pine_load_state` | 从槽位加载游戏状态 |\n\n---\n\n*最后更新：基于 mcp-pine v0.2.1*\n\n---\n\n<a id='page-savestate'></a>\n\n## 存档状态管理\n\n### 相关页面\n\n相关主题：[工具参考](#page-tools-reference), [使用范例](#page-recipes)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 存档状态管理\n\n## 概述\n\n存档状态管理（Save State Management）是 mcp-pine 项目为 PlayStation 2/3 模拟器提供的核心功能之一。该模块通过 PINE（Plugin Interface for Networked Emulation）协议实现模拟器内存状态的保存与恢复，允许 MCP 客户端在不中断游戏进程的情况下快速保存和加载游戏进度。\n\nmcp-pine 暴露了两个主要工具：\n\n| 工具名称 | 功能 |\n|---------|------|\n| `pine_save_state` | 将当前模拟器状态保存到指定槽位 |\n| `pine_load_state` | 从指定槽位加载模拟器状态 |\n\n资料来源：[src/tools.ts:工具定义区域]()\n\n## 系统架构\n\n### 组件层次\n\n```\n┌─────────────────────────────────────────────┐\n│           MCP 客户端 (Claude Code)          │\n└─────────────────────┬───────────────────────┘\n                      │ 标准 MCP 协议 (stdio)\n┌─────────────────────▼───────────────────────┐\n│              mcp-pine 桥接服务               │\n│  ┌─────────────────────────────────────┐    │\n│  │        tools.ts - 工具定义层        │    │\n│  │  • pine_save_state                  │    │\n│  │  • pine_load_state                  │    │\n│  └──────────────┬──────────────────────┘    │\n│  ┌──────────────▼──────────────────────┐    │\n│  │      pine.ts - PINE 客户端实现       │    │\n│  │  • saveState(slot)                  │    │\n│  │  • loadState(slot)                  │    │\n│  └──────────────┬──────────────────────┘    │\n└─────────────────┼───────────────────────────┘\n                  │ TCP / Unix Socket\n┌─────────────────▼───────────────────────────┐\n│           模拟器 PINE 服务器                 │\n│  • PCSX2 (Qt 版本 ≥ 1.7.x)                 │\n│  • RPCS3 (IPC 服务器)                       │\n│  • Duckstation (部分版本)                   │\n└─────────────────────────────────────────────┘\n```\n\n### 数据流\n\n```mermaid\nsequenceDiagram\n    participant Client as MCP 客户端\n    participant Bridge as mcp-pine 桥接\n    participant Pine as PINE 服务器\n    participant Emu as 模拟器核心\n\n    Client->>Bridge: pine_save_state { slot: 5 }\n    Bridge->>Pine: Op.SaveState (0x09) + slot=5\n    Pine->>Emu: 触发状态保存\n    Emu-->>Pine: 保存完成确认\n    Pine-->>Bridge: PINE 回复帧\n    Bridge-->>Client: \"Saved state → Slot 5\"\n\n    Client->>Bridge: pine_load_state { slot: 5 }\n    Bridge->>Pine: Op.LoadState (0x0A) + slot=5\n    Pine->>Emu: 触发状态加载\n    Emu-->>Pine: 加载完成确认\n    Pine-->>Bridge: PINE 回复帧\n    Bridge-->>Client: \"Loaded state from Slot 5\"\n```\n\n## API 实现\n\n### PineClient 类方法\n\n`src/pine.ts` 中定义了 `PineClient` 类的两个核心异步方法：\n\n```typescript\nasync saveState(slot: number): Promise<void> {\n  const args = Buffer.alloc(1); args.writeUInt8(slot, 0);\n  await this.call(Op.SaveState, args);\n}\n\nasync loadState(slot: number): Promise<void> {\n  const args = Buffer.alloc(1); args.writeUInt8(slot, 0);\n  await this.call(Op.LoadState, args);\n}\n```\n\n**参数说明：**\n\n| 参数 | 类型 | 范围 | 说明 |\n|------|------|------|------|\n| `slot` | `number` | 0-255 | 存档槽位编号 |\n\n**协议细节：**\n\n- 槽位参数写入 1 字节 Buffer\n- 使用 `Op.SaveState`（0x09）和 `Op.LoadState`（0x0A）操作码\n- 调用通过 `this.call()` 统一请求方法，携带 10 秒超时\n- 返回 `void`，操作成功时静默完成\n\n资料来源：[src/pine.ts:saveState方法定义]()\n\n### 协议层交互\n\n```mermaid\ngraph LR\n    A[saveState/loadState] --> B[构造 1 字节参数 Buffer]\n    B --> C[call Op.SaveState/Op.LoadState]\n    C --> D{请求发送}\n    D -->|成功| E[PINE 服务器处理]\n    E --> F[模拟器核心执行]\n    F --> G[返回确认帧]\n    D -->|超时| H[抛出 TimeoutError]\n    G --> I[解析响应 - void]\n```\n\n## 工具定义\n\n### pine_save_state\n\n```json\n{\n  \"name\": \"pine_save_state\",\n  \"description\": \"PURPOSE: Save the current emulator memory and execution state to a numbered slot...\\nBEHAVIOR: DESTRUCTIVE: overwrites any existing state in the target slot without prompting...\",\n  \"inputSchema\": {\n    \"type\": \"object\",\n    \"required\": [\"slot\"],\n    \"properties\": {\n      \"slot\": {\n        \"type\": \"integer\",\n        \"minimum\": 0,\n        \"maximum\": 255,\n        \"description\": \"Save state slot number (0-255)...\"\n      }\n    }\n  }\n}\n```\n\n**用途说明：**\n\n- 保存当前模拟器的完整运行状态到指定槽位\n- 包括 CPU 寄存器、内存快照、硬件状态等\n- 覆盖操作不可逆，无确认提示\n\n### pine_load_state\n\n```json\n{\n  \"name\": \"pine_load_state\",\n  \"description\": \"PURPOSE: Load and restore the emulator to a previously saved state in the given slot...\",\n  \"inputSchema\": {\n    \"type\": \"object\",\n    \"required\": [\"slot\"],\n    \"properties\": {\n      \"slot\": {\n        \"type\": \"integer\",\n        \"minimum\": 0,\n        \"maximum\": 255,\n        \"description\": \"Save state slot number (0-255)...\"\n      }\n    }\n  }\n}\n```\n\n**用途说明：**\n\n- 从指定槽位恢复之前保存的模拟器状态\n- 加载后模拟器立即进入加载的运行状态\n- 不存在的槽位会返回 PINE FAIL 响应\n\n资料来源：[src/tools.ts:工具定义完整内容]()\n\n## 槽位系统\n\n### 槽位编号规范\n\n| 槽位范围 | 典型用途 | 说明 |\n|---------|---------|------|\n| 0-9 | 快捷键映射 | PCSX2 GUI 中 F1-F10 对应槽位 0-9 |\n| 10-99 | 常规存档 | 用户手动保存位置 |\n| 100-255 | 扩展槽位 | 自动化脚本、批量实验使用 |\n\n### 存档文件位置\n\n| 平台 | 路径 |\n|------|------|\n| Windows | `%USERPROFILE%\\Documents\\PCSX2\\sstates` |\n| Linux | `~/.config/PCSX2/sstates` |\n| macOS | `~/.config/PCSX2/sstates` |\n\n**文件名格式：**\n\n```\n<游戏序列号> (<Disc CRC>).<slot>.p2s\n```\n\n例如：`SLUS-21274 (ABCD1234).5.p2s` 表示序列号为 SLUS-21274、CRC 为 ABCD1234 的游戏存档在第 5 槽位。\n\n资料来源：[src/tools.ts:SLOT_PARAM_DESC常量定义]()\n\n## 配置参数\n\n存档状态管理涉及以下环境变量配置：\n\n| 环境变量 | 默认值 | 说明 |\n|---------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，用于 Unix socket 文件路径前缀 |\n| `PINE_SLOT` | `28011` | PINE 通信槽位/端口号 |\n\n### 连接配置差异\n\n| 平台 | 连接方式 | 地址格式 |\n|------|---------|---------|\n| Linux/macOS | Unix Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>`，回退到 `$TMPDIR` 或 `/tmp` |\n| Windows | TCP | `127.0.0.1:<slot>` |\n\n## 工作流程示例\n\n### 基础保存-加载循环\n\n```mermaid\ngraph TD\n    A[启动模拟器] --> B[加载游戏]\n    B --> C[正常游戏]\n    C --> D[关键时刻]\n    D --> E[pine_save_state slot=5]\n    E --> F[继续游戏]\n    F --> G[出错/想重来]\n    G --> H[pine_load_state slot=5]\n    H --> I[恢复到存档点]\n    I --> F\n```\n\n### 自动化实验工作流\n\n```\n1. pine_get_info          # 确认当前游戏\n2. pine_save_state 0      # 保存基准状态\n3. [执行多次实验]\n   3a. 修改内存\n   3b. 测试假设\n   3c. pine_load_state 0  # 快速重置到基准\n4. pine_save_state 99    # 最终保存\n```\n\n## 已知问题与限制\n\n### PCSX2 PINE 服务器稳定性\n\n根据项目发现并记录的问题：\n\n| 问题 | 原因 | 解决方式 |\n|------|------|---------|\n| 请求队列脆弱 | PINE 服务器对过多请求处理不稳定 | 限制并发请求数量 |\n| 请求丢失静默 | 服务器丢弃请求时不报错 | 重启模拟器恢复 |\n| 超时后状态不一致 | 错误响应与正确响应混淆 | 确保单一请求链 |\n\n资料来源：[CHANGELOG.md:PCSX2 pipeline drop bug说明]()\n\n### 常见错误响应\n\n| 错误信息 | 可能原因 |\n|---------|---------|\n| `PINE FAIL response (0xFF)` | 游戏未加载、地址无映射、槽位不存在 |\n| `PINE call timed out (10s)` | 服务器无响应或队列错位 |\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 |\n\n## 与其他工具的配合\n\n存档状态管理通常与以下工具配合使用：\n\n| 工具 | 配合场景 |\n|------|---------|\n| `pine_get_info` | 保存前确认游戏和 CRC |\n| `pine_get_status` | 加载前确认模拟器状态 |\n| `pine_read_*` | 分析内存结构，决定保存时机 |\n| `pine_write_*` | 修改状态后保存为实验快照 |\n\n## 技术规格\n\n| 规格项 | 值 |\n|-------|-----|\n| 槽位范围 | 0-255（16 位无符号） |\n| 单次调用超时 | 10 秒 |\n| 协议操作码 | SaveState=0x09, LoadState=0x0A |\n| 参数编码 | 单字节小端序 |\n\n资料来源：[src/pine.ts:协议操作码定义]()\n\n## 总结\n\nmcp-pine 的存档状态管理模块通过 PINE 协议与模拟器深度集成，提供了简洁但功能完整的保存/加载接口。开发者可以通过 MCP 客户端在 Claude Code 等工具中直接调用 `pine_save_state` 和 `pine_load_state`，实现自动化测试、内存分析、实验回溯等工作流程。\n\n---\n\n<a id='page-installation'></a>\n\n## 安装指南\n\n### 相关页面\n\n相关主题：[快速开始](#page-quickstart), [配置参考](#page-configuration)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [src/index.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/index.ts)\n</details>\n\n# 安装指南\n\n## 概述\n\nmcp-pine 是一个基于 Model Context Protocol (MCP) 的服务器工具，用于连接 PlayStation 模拟器（PCSX2、RPCS3、Duckstation）的 PINE IPC 接口。通过该工具，AI 助手（如 Claude）可以直接与运行中的模拟器交互，执行内存读取、写入、保存状态等操作。\n\n本指南涵盖三种安装方式、MCP 客户端配置以及各模拟器的 PINE 服务启用步骤。\n\n---\n\n## 前置要求\n\n| 组件 | 版本要求 | 说明 |\n|------|----------|------|\n| Node.js | ≥ 22.0.0 | npm 包管理器内置 |\n| npm | 最新版 | 用于安装 mcp-pine |\n| PlayStation 模拟器 | 参见下方 | PCSX2 1.7.x Qt 或更高版本推荐 |\n\n资料来源：[package.json:24-26]()\n\n---\n\n## 安装方式\n\n### 方式一：npm 全局安装（推荐）\n\n```bash\nnpm install -g mcp-pine\n```\n\n全局安装后，`mcp-pine` 命令可直接在终端运行。\n\n资料来源：[README.md:40]()\n\n### 方式二：npx 免安装运行\n\n```bash\nnpx -y mcp-pine\n```\n\nnpx 会临时下载并执行包，无需本地安装，适合一次性使用场景。\n\n资料来源：[README.md:43-45]()\n\n### 方式三：源码克隆开发\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install        # 同时运行 build（通过 prepare hook）\n```\n\n适用于需要修改代码或参与开发的场景。\n\n资料来源：[README.md:47-51]()\n\n---\n\n## MCP 客户端配置\n\nmcp-pine 通过标准 stdio 协议与 MCP 客户端通信。以下是各平台的配置方法。\n\n### Claude Code (CLI)\n\n添加 MCP 服务器到用户级配置：\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\n验证连接状态：\n\n```bash\nclaude mcp list\n# 输出示例: pine: mcp-pine - ✓ Connected\n```\n\n资料来源：[README.md:13-19]()\n\n### Claude Desktop\n\n编辑配置文件 `claude_desktop_config.json`，路径因平台而异：\n\n| 平台 | 配置文件路径 |\n|------|-------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n在 `mcpServers` 下添加 pine 配置：\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\n配置完成后需重启 Claude Desktop。\n\n资料来源：[README.md:22-37]()\n\n### 其他 MCP 客户端\n\nmcp-pine 兼容任何支持 stdio 传输的标准 MCP 客户端：\n\n```bash\nmcp-pine\n```\n\n直接运行即可，客户端通过标准输入/输出与其通信。\n\n资料来源：[README.md:38-40]()\n\n---\n\n## 环境变量配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，用于 Unix socket 文件路径前缀（`<target>.sock.<slot>`）。Windows 平台忽略此变量，仅使用 TCP 连接。 |\n| `PINE_SLOT` | `28011` | PINE 端口号/槽位，连接 PCSX2/RPCS3 时指定端口 |\n| `PINE_PIPELINE_BATCH` | `1` | 批量请求数，用于控制内存读取的并发程度。默认值为 1（完全串行）以避免 PCSX2 PINE 服务请求队列崩溃 |\n\n### 连接方式差异\n\n| 平台 | 连接方式 | 地址格式 |\n|------|----------|----------|\n| Linux/macOS | Unix Domain Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>`，备用 `$TMPDIR` 或 `/tmp` |\n| Windows | TCP | `127.0.0.1:<slot>` |\n\n资料来源：[README.md:42-50]()\n\n---\n\n## 模拟器 PINE 服务配置\n\n### PCSX2（推荐）\n\n1. 启动 PCSX2（1.7.x Qt 或更新版本）\n2. 进入 **Settings → Advanced → Enable PINE Server**\n3. 默认槽位为 **28011**，如需更改同步修改 `PINE_SLOT` 环境变量\n4. 加载任意游戏\n\n> **注意**：PINE 服务启用后始终处于运行状态，无需额外脚本或控制台命令。\n\n资料来源：[README.md:53-64]()\n\n### Duckstation\n\n1. 确认 Duckstation 构建版本包含 PINE 服务器（并非所有版本都有）\n2. 如包含，设置环境变量：\n   ```bash\n   PINE_TARGET=duckstation PINE_SLOT=<port> mcp-pine\n   ```\n\n资料来源：[README.md:66-69]()\n\n### RPCS3\n\nRPCS3 使用独立 IPC 实现，兼容 PINE 操作码集，但线级兼容性尚未全面测试。\n\n1. 进入 **Configuration → Advanced → Enable IPC server**\n2. 记下配置的端口\n3. 启动命令：\n   ```bash\n   PINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine\n   ```\n\n资料来源：[README.md:71-78]()\n\n---\n\n## 验证安装\n\n### 快速测试脚本\n\n克隆仓库后可运行冒烟测试：\n\n```bash\nnode .scratch/smoke.cjs\n```\n\n该脚本会连接运行中的模拟器并执行基础调用。\n\n### MCP 工具列表\n\n安装成功后，通过 MCP 客户端可调用以下工具：\n\n| 工具名称 | 功能 |\n|----------|------|\n| `pine_ping` | 检测连接，获取模拟器版本 |\n| `pine_get_info` | 获取游戏元数据（标题、序列号、CRC、版本、运行状态） |\n| `pine_get_status` | 获取模拟器运行状态（running/paused/shutdown） |\n| `pine_read8/16/32/64` | 读取内存（按字节宽度） |\n| `pine_read_range` | 批量读取内存（最多 4096 字节） |\n| `pine_write8/16/32/64` | 写入内存 |\n| `pine_save_state` | 保存状态到指定槽位 |\n| `pine_load_state` | 从指定槽位加载状态 |\n\n资料来源：[src/tools.ts:1-200]()\n\n---\n\n## 架构概览\n\n```mermaid\ngraph TD\n    subgraph \"MCP 客户端\"\n        A[Claude Code / Claude Desktop]\n    end\n    \n    subgraph \"mcp-pine 服务器\"\n        B[index.ts - 主入口]\n        C[tools.ts - 工具定义]\n        D[pine.ts - PINE 客户端]\n    end\n    \n    subgraph \"底层通信\"\n        E[StdioTransport]\n        F[net.Socket]\n    end\n    \n    subgraph \"目标模拟器\"\n        G[PCSX2 / RPCS3 / Duckstation]\n        H[PINE Server]\n    end\n    \n    A -->|stdio| B\n    B --> C\n    C --> D\n    D -->|StdioServerTransport| E\n    D -->|TCP / Unix Socket| F\n    F -->|PINE Protocol| G\n    G --> H\n    \n    style A fill:#e1f5fe\n    style G fill:#fff3e0\n    style H fill:#f3e5f5\n```\n\n---\n\n## 故障排查\n\n| 问题 | 可能原因 | 解决方案 |\n|------|----------|----------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 | 检查 `PINE_SLOT` 设置，确认模拟器 PINE 服务已开启 |\n| `PINE FAIL response` (0xFF) | 未加载游戏或地址未映射 | 确保已加载游戏，尝试地址 `0x00100000` |\n| 读取返回全零 | 地址在未分配区域 | 优先尝试 `0x00100000`（EE 主内存几乎总是映射） |\n| `PINE call timed out (10s)` | PCSX2 PINE 请求队列崩溃 | 需完全重启 PCSX2，重连无效 |\n\n> **重要提示**：PCSX2 的 PINE 服务请求队列脆弱，当飞行中请求超过约 6 个时会静默丢弃请求，导致回复错位。一旦发生此问题，即使 `pine_ping` 也会超时，只能通过重启模拟器恢复。\n\n资料来源：[README.md:83-101]()\n\n---\n\n## 开发相关\n\n### 本地开发\n\n```bash\nnpm install\nnpm run dev      # tsc --watch\n```\n\n### 依赖关系\n\n```mermaid\ngraph LR\n    A[mcp-pine] --> B[@modelcontextprotocol/sdk]\n    A --> C[@types/node]\n    \n    style A fill:#e8f5e9\n    style B fill:#c8e6c9\n    style C fill:#c8e6c9\n```\n\n资料来源：[package.json:16-22]()\n\n---\n\n## 许可证\n\n本项目采用 MIT 许可证。\n\n资料来源：[README.md:122]()\n\n---\n\n## 相关项目\n\n| 项目 | 平台 | 特性 |\n|------|------|------|\n| [mcp-mgba](https://github.com/dmang-dev/mcp-mgba) | mGBA (Game Boy Advance) | 含按钮输入、截图功能 |\n\n资料来源：[README.md:124-126]()\n\n---\n\n<a id='page-emulator-setup'></a>\n\n## 模拟器配置\n\n### 相关页面\n\n相关主题：[配置参考](#page-configuration), [故障排除](#page-troubleshooting)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 模拟器配置\n\n## 概述\n\nmcp-pine 是一个基于 Model Context Protocol (MCP) 的桥接工具，用于连接 Claude 等 AI 助手与支持 PINE 协议的 PS2/PS3/PSP 模拟器。通过标准化的 MCP 工具接口，用户可以读取/写入模拟器内存、保存/加载存档状态以及获取游戏元数据。\n\n当前项目支持的模拟器包括 **PCSX2**、**RPCS3** 和 **Duckstation**，每种模拟器在 PINE 功能的实现和配置方式上存在差异。\n\n## 支持的模拟器\n\n| 模拟器 | 平台 | PINE 状态 | 备注 |\n|--------|------|-----------|------|\n| PCSX2  | Qt 1.7.x+ | ✅ 原生支持 | 主要测试平台，协议实现最完整 |\n| RPCS3  | 最新版 | ⚠️ 部分兼容 | 使用自定义 IPC 实现，兼容性未充分测试 |\n| Duckstation | 特定构建 | ⚠️ 需检查 | 部分构建版本包含 PINE 服务器 |\n\n资料来源：[README.md:1-60]()\n\n## 环境变量配置\n\nmcp-pine 通过环境变量控制连接行为，无需配置文件。\n\n### 核心参数\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，用于构建 Unix socket 文件路径（Linux/macOS）或 TCP 连接标识（Windows） |\n| `PINE_SLOT` | `28011` | PINE 槽位编号，对应模拟器中配置的端口号 |\n| `PINE_PIPELINE_BATCH` | `1` | 请求流水线批次大小，控制并发请求数量 |\n\n资料来源：[README.md:40-45]()\n\n### 连接地址解析\n\n连接目标根据操作系统和配置的 `PINE_TARGET` 值自动确定：\n\n```mermaid\ngraph TD\n    A[启动 mcp-pine] --> B{操作系统}\n    B -->|Linux/macOS| C{连接类型}\n    B -->|Windows| D[TCP 连接]\n    C -->|Unix Socket| E[使用 Unix Socket]\n    C -->|TCP| D\n    D --> F[127.0.0.1:{PINE_SLOT}]\n    E --> G[{$XDG_RUNTIME_DIR}/{PINE_TARGET}.sock.{PINE_SLOT}]\n    G --> H{fallback: TMPDIR}\n    H -->|失败| I[/tmp/{PINE_TARGET}.sock.{PINE_SLOT}]\n```\n\n- **Unix Socket 路径**：`{PINE_TARGET}.sock.{PINE_SLOT}`\n  - 优先使用 `$XDG_RUNTIME_DIR`\n  - 降级使用 `$TMPDIR`\n  - 最终降级到 `/tmp`\n\n资料来源：[src/pine.ts:1-150]()\n\n## PCSX2 配置指南\n\nPCSX2 是项目的主要测试平台，提供最完整的 PINE 支持。\n\n### 启用 PINE 服务器\n\n1. 启动 PCSX2（Qt 版本 1.7.x 或更高）\n2. 进入 **Settings → Advanced → Enable PINE Server**\n3. 默认槽位为 **28011**，如需更改则同步设置 `PINE_SLOT` 环境变量\n4. 加载任意游戏\n\n> 注意：PINE 服务器启用后始终保持运行，无需额外脚本或控制台命令。\n\n资料来源：[README.md:50-60]()\n\n### 连接配置\n\n**Linux/macOS：**\n```bash\nPINE_TARGET=pcsx2 PINE_SLOT=28011 mcp-pine\n```\n\n**Windows（TCP 强制）：**\n```bash\nset PINE_SLOT=28011\nmcp-pine\n```\n\n## RPCS3 配置指南\n\nRPCS3 使用自有的 IPC 实现，其操作码集合与 PINE 类似，但线级兼容性尚未经过充分测试。\n\n### 启用 IPC 服务器\n\n1. 进入 **Configuration → Advanced → Enable IPC server**（菜单位置可能因版本而异）\n2. 记录配置的端口号\n3. 使用以下命令运行：\n\n```bash\nPINE_TARGET=rpcs3 PINE_SLOT=<端口号> mcp-pine\n```\n\n资料来源：[README.md:65-72]()\n\n## Duckstation 配置指南\n\nDuckstation 的 PINE 支持因构建版本而异，并非所有发行版都包含该功能。\n\n### 检查 PINE 支持\n\n确认你的 Duckstation 构建版本包含 PINE 服务器后，使用以下配置：\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=<端口号> mcp-pine\n```\n\n其中 `<端口号>` 需要与 Duckstation 中配置的槽位端口一致。\n\n资料来源：[README.md:35-38]()\n\n## MCP 客户端集成\n\n### Claude Code (CLI)\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\n验证连接：\n```bash\nclaude mcp list\n# 输出: pine: mcp-pine - ✓ Connected\n```\n\n资料来源：[README.md:15-22]()\n\n### Claude Desktop\n\n编辑配置文件：\n\n| 操作系统 | 配置文件路径 |\n|----------|--------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\n修改配置后需重启 Claude Desktop。\n\n资料来源：[README.md:24-35]()\n\n## 性能调优\n\n### 批量读取配置\n\n`PINE_PIPELINE_BATCH` 环境变量控制并发请求数量：\n\n| 值 | 行为 | 延迟 | 风险 |\n|----|------|------|------|\n| `1` | 完全串行（默认） | ~52ms/4KB | 无 |\n| `2` 或更高 | 流水线并发 | 降低 | PCSX2 可能丢包 |\n\n> ⚠️ PCSX2 的 PINE 服务器请求队列脆弱，约 7-9 个飞行中请求即可导致无声丢包，进而使回复管道永久失步。\n\n资料来源：[src/pine.ts:80-100]()\n\n### 测量结果\n\n在 PCSX2 v2.6.3 上通过 loopback TCP 测量：\n\n- 完整 4096 字节读取：约 52ms\n- 相当于不到两个模拟帧的时间\n\n资料来源：[CHANGELOG.md:30-35]()\n\n## 故障排除\n\n| 症状 | 原因 | 解决方案 |\n|------|------|----------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、端口不匹配 | 检查 `PINE_SLOT` 设置 |\n| `PINE FAIL response` (0xFF) | 模拟器拒绝请求，通常因为未加载游戏或地址未映射 | 确保已加载游戏，使用有效地址 |\n| 读取返回零值 | 地址在未分配区域 | 尝试 `0x00100000`（EE 主 RAM） |\n| 数值看起来损坏 | 字节序问题 | PINE 返回小端序 |\n| `pine_ping` 超时（10s） | PCSX2 PINE 服务器卡死 | **完全重启 PCSX2**，重连无效 |\n\n### PCSX2 PINE 服务器卡死问题\n\n**现象**：即使 ping 也超时\n\n**原因**：请求管道失步，回复与等待客户端错位\n\n**恢复**：必须完全重启 PCSX2，仅重连无法解决问题\n\n资料来源：[README.md:90-100]()\n\n## 可用工具一览\n\n配置完成后，以下 MCP 工具可用于与模拟器交互：\n\n| 工具名称 | 功能 | PINE 调用次数 |\n|----------|------|---------------|\n| `pine_ping` | 获取模拟器版本 | 1 |\n| `pine_get_info` | 获取游戏标题、序列号、CRC、版本、状态 | 5（并行） |\n| `pine_get_status` | 获取运行状态（running/paused/shutdown） | 1 |\n| `pine_read8/16/32/64` | 读取指定宽度的内存值 | 1 |\n| `pine_read_range` | 批量读取最多 4096 字节 | N（串行） |\n| `pine_write8/16/32/64` | 写入指定宽度的内存值 | 1 |\n| `pine_save_state` | 保存游戏状态到槽位 | 1 |\n| `pine_load_state` | 从槽位加载游戏状态 | 1 |\n\n资料来源：[src/tools.ts:1-200]()\n\n## 地址空间参考\n\n### PS2 (PCSX2) 地址区域\n\n| 地址范围 | 描述 |\n|----------|------|\n| `0x00100000 - 0x01FFFFFF` | EE 主内存（99% 游戏状态所在） |\n| `0x1C000000+` | IOP 内存 |\n| 特定区域 | Scratchpad 等 |\n\n> ⚠️ 多字节读写（16/32/64 位）必须对齐地址。PCSX2 的 PINE 不强制对齐，非对齐访问会静默返回损坏数据。\n\n资料来源：[src/tools.ts:50-80]()\n\n## 安装方式\n\n### 方式 A：npm 全局安装\n\n```bash\nnpm install -g mcp-pine\n```\n\n### 方式 B：npx 临时运行\n\n```bash\nnpx -y mcp-pine\n```\n\n### 方式 C：源码开发\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install\n```\n\n资料来源：[README.md:42-50]()\n\n## 开发调试\n\n运行开发模式（TypeScript 监视编译）：\n\n```bash\nnpm run dev\n```\n\n针对运行中的 PCSX2 进行冒烟测试：\n\n```bash\nnode .scratch/smoke.cjs\n```\n\n资料来源：[README.md:105-112]()\n\n---\n\n<a id='page-configuration'></a>\n\n## 配置参考\n\n### 相关页面\n\n相关主题：[模拟器配置](#page-emulator-setup), [安装指南](#page-installation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 配置参考\n\n本文档详细说明 mcp-pine 的所有配置选项，包括环境变量、连接参数、运行时行为调优，以及不同平台下的连接机制差异。\n\n## 概述\n\nmcp-pine 通过 PINE（PlayStation Interactive Networked Entertainment）协议与模拟器进行 IPC 通信。项目采用零配置默认值设计，用户只需在模拟器中启用 PINE 服务即可开箱即用。高级用户可通过环境变量或代码级配置自定义连接目标、传输方式及请求管道行为。\n\n配置分为三个层级：\n\n| 层级 | 来源 | 优先级 | 适用场景 |\n|------|------|--------|----------|\n| 环境变量 | `process.env` | 最高 | 容器化部署、CLI 用户 |\n| 代码选项 | `PineConnectOptions` | 中 | SDK 集成开发者 |\n| 编译默认值 | 源码硬编码 | 最低 | 快速尝鲜 |\n\n## 环境变量配置\n\n环境变量是用户最常用的配置方式，适用于所有运行场景。\n\n### 完整配置表\n\n| 环境变量 | 默认值 | 类型 | 说明 |\n|----------|--------|------|------|\n| `PINE_TARGET` | `pcsx2` | string | 模拟器标识名，用于 Unix socket 文件路径前缀 |\n| `PINE_SLOT` | `28011` | number | PINE 槽位号，TCP 模式下作为端口号 |\n| `PINE_HOST` | `127.0.0.1` | string | TCP 连接模式下的目标主机（覆盖自动检测） |\n| `PINE_SOCKET_PATH` | 自动解析 | string | Unix socket 文件路径（覆盖自动检测） |\n| `PINE_PIPELINE_BATCH` | `1` | number | 请求管道批大小，1=完全串行 |\n\n资料来源：[README.md:38-45]()\n\n### PINE_TARGET\n\n指定目标模拟器名称，该值作为 Unix socket 文件路径的前缀部分。\n\n```bash\n# 连接到 PCSX2（默认）\nPINE_TARGET=pcsx2 mcp-pine\n\n# 连接到 Duckstation\nPINE_TARGET=duckstation PINE_SLOT=28013 mcp-pine\n\n# 连接到 RPCS3\nPINE_TARGET=rpcs3 PINE_SLOT=28014 mcp-pine\n```\n\n在 Linux/macOS 上，socket 路径格式为 `<socket_dir>/<target>.sock.<slot>`。\n\n### PINE_SLOT\n\nPINE 槽位号，映射到模拟器内部的 PINE 服务端口或 Unix socket 编号。\n\n```bash\n# 使用非标准槽位\nPINE_SLOT=28015 mcp-pine\n```\n\n槽位必须与模拟器 PINE 设置中的配置一致。PCSX2 默认槽位为 `28011`，RPCS3 可能因版本而异。\n\n### PINE_HOST 与 PINE_SOCKET_PATH\n\n这两个变量用于覆盖自动检测的连接方式：\n\n```bash\n# 强制使用 TCP 连接到指定主机\nPINE_HOST=192.168.1.100 PINE_SLOT=28011 mcp-pine\n\n# 强制使用指定的 Unix socket 路径\nPINE_SOCKET_PATH=/var/run/pcsx2.sock.28011 mcp-pine\n```\n\n通常无需手动设置，除非需要连接非本机模拟器或使用非标准 socket 位置。\n\n### PINE_PIPELINE_BATCH\n\n控制 `pine_read_range` 等批量读取操作的并行请求数。\n\n```bash\n# 完全串行（默认，最安全）\nPINE_PIPELINE_BATCH=1 mcp-pine\n\n# 允许 2 个请求并行（中等风险）\nPINE_PIPELINE_BATCH=2 mcp-pine\n\n# 允许 N 个请求并行（高风险）\nPINE_PIPELINE_BATCH=8 mcp-pine\n```\n\n> **警告**：PCSX2 的 PINE 服务器请求队列存在已知缺陷，当在飞请求超过约 6-7 个时会静默丢弃请求，导致回复管道永久错位。详情见故障排除章节。\n\n资料来源：[src/pine.ts:87-94]()\n\n## 连接选项接口\n\n对于通过 SDK 集成的开发者，`PineClient` 构造函数接受 `PineConnectOptions` 对象：\n\n```typescript\ninterface PineConnectOptions {\n  target?: string;      // 模拟器标识，默认为 \"pcsx2\"\n  slot?: number;        // 槽位号，默认为 28011\n  host?: string;        // 覆盖 TCP 主机\n  socketPath?: string;  // 覆盖 Unix socket 路径\n}\n```\n\n使用示例：\n\n```typescript\nimport { PineClient } from \"mcp-pine\";\n\nconst pine = new PineClient({\n  target: \"pcsx2\",\n  slot: 28011,\n});\n\n// 或指定自定义连接\nconst pine2 = new PineClient({\n  host: \"192.168.1.100\",\n  slot: 28011,\n});\n```\n\n## 传输层架构\n\n### 平台自动检测\n\nmcp-pine 根据运行平台自动选择最优传输方式：\n\n```mermaid\ngraph TD\n    A[启动 mcp-pine] --> B{平台检测}\n    B -->|Windows| C[TCP 连接]\n    B -->|Linux/macOS| D[Unix Domain Socket]\n    \n    C --> E[127.0.0.1:PINE_SLOT]\n    D --> F{XDG_RUNTIME_DIR}\n    F -->|存在| G[XDG_RUNTIME_DIR/target.sock.slot]\n    F -->|不存在| H{TMPDIR}\n    H -->|存在| I[TMPDIR/target.sock.slot]\n    H -->|不存在| J[/tmp/target.sock.slot]\n    \n    style C fill:#e1f5fe\n    style D fill:#fff3e0\n    style E fill:#e1f5fe\n    style G fill:#e8f5e9\n    style I fill:#e8f5e9\n    style J fill:#e8f5e9\n```\n\n### Socket 路径解析优先级\n\n在 Linux/macOS 上，Unix socket 路径按以下优先级确定：\n\n| 优先级 | 环境变量 | 示例路径 |\n|--------|----------|----------|\n| 1 | `PINE_SOCKET_PATH`（显式覆盖） | 用户指定 |\n| 2 | `$XDG_RUNTIME_DIR` | `/run/user/1000/pcsx2.sock.28011` |\n| 3 | `$TMPDIR` | `/tmp/pcsx2.sock.28011` |\n| 4 | `/tmp`（最终回退） | `/tmp/pcsx2.sock.28011` |\n\n资料来源：[src/pine.ts:30-48]()\n\n### TCP 连接模式\n\n在 Windows 或显式指定 `PINE_HOST` 时，mcp-pine 使用标准 TCP 连接：\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP 客户端\n    participant Bridge as mcp-pine\n    participant PCSX2 as PCSX2 PINE\n    \n    Note over Bridge: TCP 模式初始化\n    MCP->>Bridge: 连接请求\n    Bridge->>PCSX2: net.createConnection<br/>host: 127.0.0.1\n    PCSX2-->>Bridge: 连接成功\n    Bridge-->>MCP: 就绪\n```\n\n连接地址格式：`127.0.0.1:<PINE_SLOT>`\n\n## 请求处理机制\n\n### PINE 协议帧格式\n\nmcp-pine 使用二进制 PINE 协议进行通信，帧格式如下：\n\n```mermaid\ngraph LR\n    subgraph 发送帧\n        A[uint32<br/>总长度] --> B[uint8<br/>操作码] --> C[可变长度<br/>载荷数据]\n    end\n    \n    subgraph 接收帧\n        D[uint32<br/>总长度] --> E[uint8<br/>状态] --> F[可变长度<br/>响应数据]\n    end\n```\n\n所有多字节整数均采用小端序（Little-Endian）编码。\n\n### 操作码映射\n\n| 操作码 | 名称 | 方向 | 说明 |\n|--------|------|------|------|\n| 0x01 | Version | R | 获取模拟器版本 |\n| 0x02 | Title | R | 获取游戏标题 |\n| 0x03 | ID | R | 获取游戏序列号 |\n| 0x04 | UUID | R | 获取光盘 CRC |\n| 0x05 | GameVersion | R | 获取游戏版本 |\n| 0x06 | Status | R | 获取运行状态 |\n| 0x10 | SaveState | W | 保存状态到槽位 |\n| 0x11 | LoadState | W | 从槽位加载状态 |\n| 0x20-0x23 | Read8/16/32/64 | R | 读取内存 |\n| 0x30-0x33 | Write8/16/32/64 | W | 写入内存 |\n\n资料来源：[src/pine.ts:1-28]()\n\n### 批量读取实现\n\n`pine_read_range` 通过组合多种宽度的读取操作实现高效批量读取：\n\n```mermaid\nflowchart TD\n    A[pine_read_range<br/>length=4096] --> B{对齐检测}\n    \n    B -->|cursor%8==0 且 remaining>=8| C[read64]\n    B -->|cursor%4==0 且 remaining>=4| D[read32]\n    B -->|cursor%2==0 且 remaining>=2| E[read16]\n    B -->|其他情况| F[read8]\n    \n    C --> G{下一个字节}\n    D --> G\n    E --> G\n    F --> G\n    \n    G -->|remaining>0| B\n    G -->|remaining=0| H[组装结果缓冲区]\n    \n    I{PIPELINE_BATCH}\n    I -->|=1| J[串行执行<br/>每批1个请求]\n    I -->|>1| K[并行执行<br/>每批N个请求]\n    \n    J --> L[安全但延迟较高]\n    K --> M[低延迟但可能丢包]\n    \n    style J fill:#c8e6c9\n    style K fill:#ffcdd2\n```\n\n默认 `PIPELINE_BATCH=1` 表示完全串行执行，避免 PCSX2 PINE 服务器的队列问题。\n\n资料来源：[src/pine.ts:58-86]()\n\n## 模拟器配置要求\n\n### PCSX2 设置\n\n1. 启动 PCSX2 1.7.x 或更新版本\n2. 进入 **Settings → Advanced → Enable PINE Server**\n3. 默认槽位为 **28011**，如需更改同步修改环境变量\n\n无需额外脚本或控制台命令，PINE 启用后始终可用。\n\n### RPCS3 设置\n\nRPCS3 实现了兼容 PINE 的 IPC 接口，但线级兼容性尚未完全测试：\n\n1. 进入 **Configuration → Advanced → Enable IPC server**\n2. 记下配置的端口\n3. 使用 `PINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine` 运行\n\n### Duckstation 设置\n\n部分 Duckstation 构建包含 PINE 服务器：\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=<port> mcp-pine\n```\n\n## 故障排除\n\n### 连接问题诊断\n\n```mermaid\nflowchart TD\n    A[连接失败] --> B{PING 工具测试}\n    \n    B -->|超时| C{模拟器运行中?}\n    C -->|否| D[启动模拟器并加载游戏]\n    C -->|是| E[PINE 已启用?]\n    E -->|否| F[在模拟器设置中启用 PINE]\n    E -->|是| G{端口匹配?}\n    G -->|否| H[对齐 PINE_SLOT 和模拟器设置]\n    \n    B -->|FAIL 响应| I{是否有游戏加载?}\n    I -->|否| J[加载游戏后重试]\n    I -->|是| K[地址无效或未映射]\n    \n    K --> L[从 0x00100000 开始尝试]\n    \n    style D fill:#c8e6c9\n    style F fill:#c8e6c9\n    style H fill:#c8e6c9\n    style J fill:#c8e6c9\n    style L fill:#c8e6c9\n```\n\n### PCSX2 PINE 服务器卡死\n\nPCSX2 的 PINE 服务器在收到约 7 个以上并行请求时会静默丢弃请求，导致回复管道永久错位。\n\n**症状**：即使 `pine_ping` 也超时（10秒后）。\n\n**解决方案**：完全重启 PCSX2。重新连接无效，损坏发生在模拟器端。\n\n**预防措施**：\n- 保持 `PINE_PIPELINE_BATCH=1`\n- 如需更高性能，确保请求数量不超过 6 个\n\n资料来源：[README.md:98-115]()\n\n### 内存读取问题\n\n| 症状 | 可能原因 | 解决方案 |\n|------|----------|----------|\n| 返回全零 | 地址未分配 | 从 `0x00100000` 开始尝试 |\n| 数据损坏 | 未对齐访问 | 使用 `pine_read_range` 自行组装 |\n| 值不符合预期 | 大端序误解 | PINE 返回小端序 |\n\n## 配置示例\n\n### 基本用法（默认 PCSX2）\n\n```bash\n# 使用所有默认值\nmcp-pine\n```\n\n等价于：\n```bash\nPINE_TARGET=pcsx2 PINE_SLOT=28011 mcp-pine\n```\n\n### 连接远程模拟器\n\n```bash\nPINE_HOST=192.168.1.50 PINE_SLOT=28011 mcp-pine\n```\n\n### 自定义 Unix Socket 路径\n\n```bash\nPINE_SOCKET_PATH=/home/user/my-socket mcp-pine\n```\n\n### 性能调优（风险自负）\n\n```bash\n# 允许 2 个并行请求\nPINE_PIPELINE_BATCH=2 mcp-pine\n```\n\n### NPM 方式运行\n\n```bash\nnpx -y mcp-pine\n```\n\n## 环境变量速查表\n\n```\nPINE_TARGET          默认: pcsx2        模拟器标识名\nPINE_SLOT            默认: 28011        槽位号/端口\nPINE_HOST            默认: 127.0.0.1    TCP 主机\nPINE_SOCKET_PATH     默认: 自动解析     Unix socket 路径\nPINE_PIPELINE_BATCH  默认: 1            并行请求批大小\n```\n\n## 相关文档\n\n- [快速开始指南](README.md) — 安装与基础使用\n- [工具参考](src/tools.ts) — MCP 工具完整列表\n- [PINE 协议规范](https://github.com/GovanifY/pine) — 底层 IPC 标准\n- [mcp-mgba](https://github.com/dmang-dev/mcp-mgba) — 同系 Game Boy Advance 客户端\n\n---\n\n<a id='page-recipes'></a>\n\n## 使用范例\n\n### 相关页面\n\n相关主题：[内存操作指南](#page-memory-operations), [存档状态管理](#page-savestate), [故障排除](#page-troubleshooting)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 使用范例\n\n## 概述\n\nmcp-pine 是一个基于 Model Context Protocol (MCP) 的桥接工具，用于连接 Claude 等 AI 助手与支持 PINE（PlayStation 2 Inter-Process Communication）协议的模拟器（如 PCSX2、RPCS3、Duckstation）。通过 mcp-pine，用户可以让 AI 直接读取和写入模拟器的内存、获取游戏状态信息、保存和加载存档。\n\n该项目的主要功能包括：\n\n- **内存读写**：支持 8/16/32/64 位数值读取以及批量内存读取\n- **游戏状态查询**：获取游戏标题、序列号、CRC、版本信息\n- **存档管理**：保存和加载指定槽位的存档\n- **跨模拟器支持**：兼容 PCSX2、RPCS3、Duckstation 等主流模拟器\n\n资料来源：[README.md:1-5](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 系统架构\n\n```mermaid\ngraph TD\n    A[\"Claude / MCP 客户端\"] -->|MCP stdio| B[\"mcp-pine 桥接工具\"]\n    B -->|PINE 协议| C[\"PCSX2 PINE Server\"]\n    B -->|PINE 协议| D[\"RPCS3 IPC Server\"]\n    B -->|PINE 协议| E[\"Duckstation PINE Server\"]\n    \n    F[\"EE 主内存 0x00100000-0x01FFFFFF\"] --> C\n    G[\"IOP 内存 0x1C000000+\"] --> C\n    H[\"PS3 主内存\"] --> D\n```\n\nmcp-pine 作为中间层，将 MCP 协议请求转换为 PINE 协议调用，与模拟器的内置 PINE 服务器通信。不同模拟器使用不同的连接方式：Unix 域套接字（Linux/macOS）或 TCP（Windows）。\n\n资料来源：[src/pine.ts:1-50](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## 安装方式\n\n### 方式一：npm 全局安装\n\n```bash\nnpm install -g mcp-pine\n```\n\n### 方式二：npx 直接运行\n\n```bash\nnpx -y mcp-pine\n```\n\n### 方式三：源码安装\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install\n```\n\n资料来源：[README.md:40-50](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## MCP 客户端配置\n\n### Claude Code (CLI)\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\n验证连接：\n\n```bash\nclaude mcp list\n# 输出: pine: mcp-pine - ✓ Connected\n```\n\n### Claude Desktop\n\n根据操作系统编辑配置文件：\n\n| 平台 | 配置文件路径 |\n|------|-------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n配置内容：\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\n修改配置后需重启 Claude Desktop。\n\n资料来源：[README.md:18-38](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 环境变量配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，用于构建 Unix 套接字文件路径（`<target>.sock.<slot>`）。Windows 系统忽略此变量，仅使用 TCP 连接。 |\n| `PINE_SLOT` | `28011` | PINE 槽位号，对应 PCSX2 中的端口或槽位号。 |\n| `PINE_PIPELINE_BATCH` | `1` | 批量流水线深度。默认为 1（完全串行），设为更高值可降低延迟但可能导致 PCSX2 请求队列错位。 |\n\n资料来源：[README.md:42-48](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 模拟器配置\n\n### PCSX2 配置步骤\n\n1. 启动 PCSX2（1.7.x Qt 或更高版本）\n2. 进入 **Settings → Advanced → Enable PINE Server**\n3. 默认槽位为 **28011**，如需更改则在启动 mcp-pine 时设置 `PINE_SLOT`\n4. 加载任意游戏\n\n> 注意：PINE 服务启用后始终处于开启状态，无需脚本或控制台命令。\n\n资料来源：[README.md:52-60](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### RPCS3 配置步骤\n\n1. 进入 **Configuration → Advanced → Enable IPC server**\n2. 记下配置的端口号\n3. 运行命令：`PINE_TARGET=rpcs3 PINE_SLOT=<端口> mcp-pine`\n\n> 注意：RPCS3 的 IPC 实现参考了 PINE 操作码，但协议层面的兼容性尚未经过充分测试。\n\n资料来源：[README.md:62-68](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Duckstation 配置步骤\n\n检查当前构建的 Duckstation 是否包含 PINE 服务器（如有则设置 `PINE_TARGET=duckstation PINE_SLOT=<端口>`）。\n\n资料来源：[README.md:70-71](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 工具清单\n\nmcp-pine 提供以下 MCP 工具：\n\n| 工具名称 | 功能 | 用途场景 |\n|----------|------|----------|\n| `pine_ping` | 检测连接状态 | 验证模拟器 PINE 服务是否可用 |\n| `pine_get_info` | 获取游戏元数据 | 获取游戏标题、序列号、CRC、版本、运行状态 |\n| `pine_get_status` | 获取运行状态 | 快速检查模拟器是运行中、暂停还是已关闭 |\n| `pine_read8/16/32/64` | 定点内存读取 | 按指定字节宽度读取单个值 |\n| `pine_read_range` | 批量内存读取 | 一次性读取最多 4096 字节的连续内存区域 |\n| `pine_write8/16/32/64` | 定点内存写入 | 向指定地址写入数值 |\n| `pine_save_state` | 保存存档 | 将当前状态保存到指定槽位 |\n| `pine_load_state` | 加载存档 | 从指定槽位恢复存档 |\n\n资料来源：[src/tools.ts:1-150](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## 典型使用流程\n\n```mermaid\ngraph TD\n    A[启动 PCSX2 并加载游戏] --> B[启动 mcp-pine]\n    B --> C{连接成功?}\n    C -->|是| D[调用 pine_ping 验证]\n    D --> E[调用 pine_get_info 获取游戏信息]\n    E --> F{需要读取内存?}\n    F -->|是| G[使用 pine_read_range 批量读取]\n    G --> H[分析内存数据]\n    F -->|否| I[使用 pine_read8/16/32/64 定点读取]\n    I --> H\n    H --> J{需要修改状态?}\n    J -->|是| K[使用 pine_write* 写入]\n    J -->|否| L[完成]\n    K --> L\n    C -->|否| M[检查 PINE_SLOT 配置]\n    M --> C\n```\n\n## 内存地址说明\n\n### PS2 内存布局（PCSX2）\n\n| 地址范围 | 说明 |\n|----------|------|\n| `0x00100000` - `0x01FFFFFF` | EE 主内存（99% 的游戏状态位于此处） |\n| `0x1C000000`+ | IOP 内存 |\n| 0x10000000 区域 | Scratchpad（高速缓存） |\n\n> 重要提示：对于 16/32/64 位读取，地址**必须对齐**（即地址值能被读写宽度整除）。PCSX2 的 PINE 服务**不强制对齐**，未对齐的地址会静默返回错误数据。如需读取未对齐的数据，请使用 `pine_read_range` 并自行组装字节。\n\n资料来源：[src/tools.ts:40-55](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## 工具使用详解\n\n### 连接验证\n\n```typescript\n// 调用 pine_ping\n工具输入: {}\n预期输出: \"OK — emulator: <版本号>\"\n```\n\n### 获取游戏信息\n\n```typescript\n// 调用 pine_get_info\n工具输入: {}\n预期输出:\n\"Title:        <游戏标题>\nSerial:       <序列号>\nDisc CRC:     <CRC值>\nGame version: <版本号>\nStatus:       <运行状态>\"\n```\n\n此工具并行发送 5 个 PINE 操作码（Title、ID、UUID、GameVersion、Status），任一字段失败时返回 `(unavailable)` 而不影响其他字段。\n\n资料来源：[src/tools.ts:75-95](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### 内存读取示例\n\n#### 定点读取\n\n```typescript\n// 读取 32 位无符号整数\n工具输入: { \"address\": 0x00100000 }\n预期输出: \"0x00100000: 12345 (0x3039)\"\n\n// 读取 64 位值（返回字符串形式的十进制数，因为 JS 无法精确表示超过 2^53 的整数）\n工具输入: { \"address\": 0x00200000 }\n预期输出: \"0x00200000: 18446744073709551615 (0xFFFFFFFFFFFFFFFF)\"\n```\n\n#### 批量读取\n\n`pine_read_range` 是最高效的批量读取方式，内部实现为串行调用最大对齐宽度的读取操作。实测 PCSX2 v2.6.3 下读取 4096 字节约需 52ms。\n\n```typescript\n工具输入: { \"address\": 0x00100000, \"length\": 256 }\n预期输出: \"0x00100000: <256字节的十六进制数据>\"\n```\n\n> 默认情况下请求完全串行执行，以避免 PCSX2 请求队列错位。可通过设置 `PINE_PIPELINE_BATCH` 环境变量调整流水线深度。\n\n资料来源：[src/pine.ts:80-130](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n### 内存写入示例\n\n```typescript\n// 写入 8 位值\n工具输入: { \"address\": 0x00100000, \"value\": 255 }\n\n// 写入 32 位值\n工具输入: { \"address\": 0x00100004, \"value\": 12345678 }\n预期输出: \"Wrote 12345678 (0xBC614E) → 0x00100004\"\n```\n\n> 注意：内存写入是**破坏性操作**，会覆盖原有数据。\n\n资料来源：[src/tools.ts:96-110](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### 存档管理\n\n```typescript\n// 保存到槽位 3\n工具输入: { \"slot\": 3 }\n预期输出: \"Saved state to slot 3\"\n\n// 从槽位 5 加载\n工具输入: { \"slot\": 5 }\n预期输出: \"Loaded state from slot 5\"\n```\n\nPCSX2 存档文件通常位于：\n- Windows: `%USERPROFILE%\\Documents\\PCSX2\\sstates`\n- Linux: `~/.config/PCSX2/sstates`\n\n文件名格式：`<序列号> (<CRC>).<槽位号>.p2s`\n\n资料来源：[src/tools.ts:130-140](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## 常见问题排查\n\n| 问题症状 | 原因与解决方案 |\n|----------|---------------|\n| `Cannot reach PINE server` | 模拟器未运行、PINE 未启用、或槽位号不匹配。检查 `PINE_SLOT` 配置。 |\n| `PINE FAIL response` (0xFF) | 模拟器拒绝请求，通常是因为未加载游戏或地址未映射。 |\n| 读取返回零值 | 地址位于未分配区域，尝试从 `0x00100000` 开始（几乎总是在 EE RAM 范围内）。 |\n| 数据看起来损坏 | 检查字节序，PINE 返回小端序；字符串应使用 `read_range` 风格的字节读取。 |\n| `pine_ping` 超时（10秒） | **PCSX2 PINE 服务器可能卡死**。请求队列在超过约 6 个飞行中请求时会静默丢包，导致后续所有回复错位。**解决方案：完全重启 PCSX2**，仅重新连接无效。 |\n\n资料来源：[README.md:100-115](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 开发相关\n\n### 本地开发\n\n```bash\nnpm install\nnpm run dev      # 启动 tsc --watch 监听文件变化\n```\n\n### 快速测试\n\n在运行 PCSX2 的环境下执行冒烟测试：\n\n```bash\nnode .scratch/smoke.cjs\n```\n\n资料来源：[README.md:118-125](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## 版本历史\n\n| 版本 | 日期 | 主要变更 |\n|------|------|----------|\n| 0.2.1 | 2026-05-15 | 工具描述质量改进，符合 Glama Tool Definition Quality Score 规范 |\n| 0.2.0 | 2026-05-10 | 新增 `pine_read_range` 批量读取、10秒超时机制 |\n| 0.1.x | 早期版本 | 基础功能实现 |\n\n资料来源：[CHANGELOG.md:1-50](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n## 相关项目\n\n- [mcp-mgba](https://github.com/dmang-dev/mcp-mgba) — mcp-pine 的姊妹项目，支持 mGBA 模拟器（Game Boy Advance），额外包含按键输入和截图功能\n- [PINE 协议规范](https://github.com/GovanifY/pine) — 底层 IPC 标准文档\n\n资料来源：[README.md:128-131](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n---\n\n<a id='page-troubleshooting'></a>\n\n## 故障排除\n\n### 相关页面\n\n相关主题：[模拟器配置](#page-emulator-setup), [配置参考](#page-configuration), [使用范例](#page-recipes)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n- [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n- [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n</details>\n\n# 故障排除\n\n本文档提供 mcp-pine 与 PINE 协议模拟器通信时遇到的常见问题诊断与解决方案。\n\n## 连接问题\n\n### 无法连接 PINE 服务器\n\n**症状**: 调用任何工具时返回 `Cannot reach PINE server` 错误。\n\n**可能原因**:\n\n| 原因 | 检查方法 | 解决方案 |\n|------|----------|----------|\n| 模拟器未运行 | 检查模拟器进程是否启动 | 启动 PCSX2/RPCS3/Duckstation |\n| PINE 功能未启用 | 模拟器设置中搜索 \"PINE\" | Settings → Advanced → Enable PINE Server |\n| 端口/插槽号不匹配 | 检查 `PINE_SLOT` 环境变量 | 设置 `PINE_SLOT=28011` (PCSX2 默认值) |\n| 模拟器未加载游戏 | 确认游戏已加载 | 加载任意游戏后再尝试 |\n\n**排查步骤**:\n\n```mermaid\ngraph TD\n    A[连接失败] --> B{模拟器运行中?}\n    B -->|否| C[启动模拟器]\n    B -->|是| D{PINE已启用?}\n    D -->|否| E[启用PINE Server]\n    D -->|是| F{游戏已加载?}\n    F -->|否| G[加载游戏]\n    F -->|是| H{端口匹配?}\n    H -->|否| I[设置PINE_SLOT]\n    H -->|是| J[检查防火墙/权限]\n```\n\n资料来源：[README.md:1]() [README.md:52]()\n\n### 连接方式差异\n\n| 操作系统 | 连接方式 | 路径/地址格式 |\n|----------|----------|---------------|\n| Linux/macOS | Unix Domain Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>` 或 `$TMPDIR/<target>.sock.<slot>` |\n| Windows | TCP | `127.0.0.1:<slot>` |\n| 默认目标 | PCSX2 | `PINE_TARGET=pcsx2` |\n| 替代目标 | RPCS3/Duckstation | `PINE_TARGET=rpcs3` 或 `PINE_TARGET=duckstation` |\n\n资料来源：[src/pine.ts:88-100]()\n\n## PINE 协议错误响应\n\n### PINE FAIL 响应 (0xFF)\n\n**症状**: 返回 `PINE FAIL response` (0xFF) 错误。\n\n**可能原因**:\n\n| 原因 | 诊断方法 | 解决方案 |\n|------|----------|----------|\n| 未加载游戏 | 检查模拟器状态 | 加载游戏后重试 |\n| 地址未映射 | 尝试 `0x00100000` (EE RAM) | 使用已确认有效的地址 |\n| 只读区域写入 | 检查目标区域类型 | BIOS/IOP ROM 写入会被静默丢弃 |\n\n**地址空间参考**:\n\n| 区域 | 地址范围 | 说明 |\n|------|----------|------|\n| EE Main RAM | `0x00100000` - `0x01FFFFFF` | 99% 的游戏状态在此区域 |\n| IOP RAM | `0x1C000000+` | IOP 处理器内存 |\n| Scratchpad | 特定区域 | 高速缓存区域 |\n\n资料来源：[README.md:54]() [src/tools.ts:35-39]()\n\n## 内存读取问题\n\n### 读取返回全零\n\n**症状**: `pine_read8/16/32/64` 返回值全为 0。\n\n**诊断流程**:\n\n```mermaid\ngraph LR\n    A[读取返回0] --> B{地址有效?}\n    B -->|尝试0x00100000| C{仍然返回0?}\n    C -->|是| D[游戏未正确加载]\n    C -->|否| E[原地址在未分配区域]\n    B -->|无效地址| F[使用有效地址重试]\n```\n\n**解决方案**: 首先尝试 `0x00100000`，这是 EE 主 RAM 的起始地址，几乎总是可访问的。\n\n### 数据损坏/值看起来不正确\n\n**症状**: 读取的值看起来错误或损坏。\n\n**可能原因**: 字节序问题。PINE 协议返回小端序数据。\n\n| 操作类型 | 字节序 | 处理方式 |\n|----------|--------|----------|\n| 字符串读取 | UTF-8 | 使用 `read_range` 逐字节读取 |\n| 数值读取 | Little-Endian | LSB 在低位地址，MSB 在高位地址 |\n\n**解决方案**: 对于字符串，使用 `pine_read_range` 进行字节级读取。对于数值，确认解析时使用小端序。\n\n## 超时问题\n\n### PINE 调用超时 (10秒)\n\n**症状**: `pine_ping` 在某些高频使用后开始超时。\n\n**根本原因**: PCSX2 的 PINE 服务器请求队列存在已知问题。\n\n```mermaid\ngraph TD\n    A[PCSX2 PINE Server] --> B[请求队列]\n    B --> C{请求数量 <= 6}\n    C -->|是| D[正常处理]\n    C -->|否| E[请求被静默丢弃]\n    E --> F[回复流水线失步]\n    F --> G[所有后续请求超时]\n    G --> H[甚至ping也超时]\n```\n\n**已知限制**:\n\n- PCSX2 的 PINE 服务器请求队列脆弱\n- 同时有超过约 6 个进行中的请求时会静默丢弃请求\n- 一旦失步，即使 `pine_ping` 也会超时\n- **重新连接无法恢复，必须完全重启 PCSX2**\n\n资料来源：[README.md:55-56]() [CHANGELOG.md:45-52]() [src/pine.ts:60-68]()\n\n**恢复步骤**:\n\n1. 完全关闭 PCSX2（不只是暂停）\n2. 重新启动 PCSX2\n3. 重新加载游戏\n4. 重新连接 mcp-pine\n\n## 性能问题\n\n### `pine_read_range` 速度较慢\n\n**现象**: 大范围内存读取比 mGBA 的 `read_range` 慢。\n\n**原因分析**:\n\n| 特性 | PINE | mGBA |\n|------|------|------|\n| 原生批量读取 | ❌ 无 | ✅ 有 |\n| 实现方式 | 串行发送多个 read64/32/16/8 | 单次批量请求 |\n| 4096字节读取耗时 | ~52ms (PCSX2 v2.6.3) | 显著更快 |\n\n**延迟基准**:\n\n| 操作 | 耗时 | 说明 |\n|------|------|------|\n| 完整 4096 字节读取 | ~52ms | 循环回程 TCP 性能 |\n| 相当于模拟帧数 | < 2 帧 | 60fps 下约 33ms/帧 |\n\n资料来源：[README.md:57-58]() [CHANGELOG.md:37-40]()\n\n### 流水线批处理选项\n\n**环境变量**: `PINE_PIPELINE_BATCH`\n\n| 值 | 行为 | 风险 |\n|----|------|------|\n| 1 (默认) | 完全串行请求 | 无 |\n| >= 2 | 启用流水线 | 可能导致 PCSX2 失步 |\n\n```typescript\n// src/pine.ts 中的实现逻辑\nconst PIPELINE_BATCH = Number.parseInt(process.env.PINE_PIPELINE_BATCH ?? \"1\", 10) || 1;\n\nfor (let i = 0; i < steps.length; i += PIPELINE_BATCH) {\n    const batch = steps.slice(i, i + PIPELINE_BATCH);\n    const promises = batch.map((s) => /* ... */);\n    const results = await Promise.all(promises);\n}\n```\n\n**警告**: 启用流水线可能导致 PCSX2 PINE 服务器失步。仅在能够容忍偶尔模拟器重启的情况下使用。\n\n资料来源：[src/pine.ts:70-73]() [src/pine.ts:95-100]()\n\n## 对齐问题\n\n### 未对齐地址访问\n\n**症状**: 多字节读取返回值看起来错误或损坏。\n\n**根本原因**: PINE on PCSX2 **不强制对齐要求**。\n\n| 操作 | 对齐要求 | 未对齐行为 |\n|------|----------|------------|\n| `pine_read8` / `pine_write8` | 无 | 正常工作 |\n| `pine_read16` / `pine_write16` | 2字节对齐 | 返回对齐地址以下的字节 |\n| `pine_read32` / `pine_write32` | 4字节对齐 | 返回对齐地址以下的字节 |\n| `pine_read64` / `pine_write64` | 8字节对齐 | 返回对齐地址以下的字节 |\n\n**解决方案**:\n\n1. 确保传入对齐的地址\n2. 如需未对齐访问，使用 `pine_read_range` 逐字节读取后自行组装\n\n```mermaid\ngraph LR\n    A[需要读取0x1003] --> B{可接受的访问方式?}\n    B --> C[使用read_range读取0x1000-0x1007]\n    B --> D[忽略不对齐的write64]\n    C --> E[自行组装字节]\n```\n\n资料来源：[src/tools.ts:11-15]()\n\n## 工具调用错误\n\n### 各工具的错误条件汇总\n\n| 工具 | 失败模式 | 错误信息 |\n|------|----------|----------|\n| `pine_ping` | 连接失败/PINE 失步 | `Cannot reach PINE server` / 超时 |\n| `pine_get_info` | 连接失败/部分字段不可用 | 返回 `(unavailable)` |\n| `pine_get_status` | 连接失败 | `PINE FAIL response` |\n| `pine_read*` | 无效地址/未对齐 | PINE FAIL 或错误值 |\n| `pine_write*` | 只读区域/无效地址 | PINE FAIL (静默丢弃) |\n| `pine_save_state` | 插槽超出范围 | Schema 拒绝 (0-255) |\n| `pine_load_state` | 插槽无存档 | PINE FAIL |\n\n### 存档状态槽位\n\n| 槽位范围 | 约定 | 实际协议支持 |\n|----------|------|--------------|\n| 0-255 | 完整协议支持 | ✅ |\n| 0-9 | PCSX2 GUI 映射到 F1-F10 | 推荐使用 |\n\n资料来源：[src/tools.ts:58-63]()\n\n## 环境变量参考\n\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `PINE_TARGET` | `pcsx2` | 模拟器名称，决定 Unix socket 文件前缀 |\n| `PINE_SLOT` | `28011` | PINE 插槽号，也是 TCP 端口号 |\n| `PINE_PIPELINE_BATCH` | `1` | 流水线批处理大小，1=完全串行 |\n\n资料来源：[README.md:29-32]() [src/pine.ts:70]()\n\n## 调试技巧\n\n### 快速冒烟测试\n\n```bash\n# 确保模拟器运行且 PINE 已启用\nnode .scratch/smoke.cjs\n```\n\n### 推荐的调试工作流\n\n1. **首先验证连接**: 使用 `pine_ping`\n2. **获取基本信息**: 使用 `pine_get_info` 确认游戏加载\n3. **检查状态**: 使用 `pine_get_status`\n4. **从已知地址开始**: 尝试 `0x00100000` 验证读取功能\n5. **逐步深入**: 确认基础功能后再访问特定内存区域\n\n### 连接质量检查\n\n```mermaid\ngraph TD\n    A[开始调试] --> B[ping成功?]\n    B -->|否| C[检查模拟器/网络]\n    B -->|是| D[get_info成功?]\n    D -->|否| E[无游戏加载]\n    D -->|是| F[测试已知地址]\n    F --> G{0x00100000返回非零?}\n    G -->|否| H[EE RAM未映射]\n    G -->|是| I[基础连接正常]\n```\n\n## 已知限制\n\n| 限制 | 描述 | 状态 |\n|------|------|------|\n| PCSX2 请求队列脆弱 | >6 流水线请求会导致失步 | 已知问题，无法自动恢复 |\n| 无原生批量读取 | `read_range` 串行实现 | 设计限制，性能可接受 |\n| 未对齐访问静默损坏 | PCSX2 不强制对齐 | 需客户端保证 |\n| RPCS3 兼容性未充分测试 | Wire-level 兼容性待验证 | 实验性支持 |\n\n资料来源：[README.md:45-51]() [CHANGELOG.md:48-54]()\n\n## 获取帮助\n\n如遇到本文档未覆盖的问题，请：\n\n1. 确认问题可重现\n2. 记录模拟器版本、PINE 设置、错误信息\n3. 在 [GitHub Issues](https://github.com/dmang-dev/mcp-pine/issues) 创建 Issue\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：dmang-dev/mcp-pine\n\n摘要：发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：安装坑 - 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers。\n\n## 1. 安装坑 · 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Submit listing PR to punkpeye/awesome-mcp-servers\n- 对用户的影响：可能阻塞安装或首次运行。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_540ae479012f437fb2cb5e7d33636f1f | https://github.com/dmang-dev/mcp-pine/issues/2 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 2. 配置坑 · 可能修改宿主 AI 配置\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 防护动作：涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- 证据：capability.host_targets | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | host_targets=mcp_host, claude\n\n## 3. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | README/documentation is current enough for a first validation pass.\n\n## 4. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | last_activity_observed missing\n\n## 5. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 6. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 7. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | issue_or_pr_quality=unknown\n\n## 8. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | release_recency=unknown\n\n<!-- canonical_name: dmang-dev/mcp-pine; human_manual_source: deepwiki_human_wiki -->\n",
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "Human Manual / 人类版说明书"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log / 踩坑日志\n\n项目：dmang-dev/mcp-pine\n\n摘要：发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：安装坑 - 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers。\n\n## 1. 安装坑 · 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Submit listing PR to punkpeye/awesome-mcp-servers\n- 对用户的影响：可能阻塞安装或首次运行。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_540ae479012f437fb2cb5e7d33636f1f | https://github.com/dmang-dev/mcp-pine/issues/2 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 2. 配置坑 · 可能修改宿主 AI 配置\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 防护动作：涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- 证据：capability.host_targets | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | host_targets=mcp_host, claude\n\n## 3. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | README/documentation is current enough for a first validation pass.\n\n## 4. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | last_activity_observed missing\n\n## 5. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 6. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 7. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | issue_or_pr_quality=unknown\n\n## 8. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | release_recency=unknown\n",
      "summary": "用户实践前最可能遇到的身份、安装、配置、运行和安全坑。",
      "title": "Pitfall Log / 踩坑日志"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# mcp-pine - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 mcp-pine 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的工具连接与集成任务。\n我常用的宿主 AI：MCP Client / claude\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-introduction：项目介绍。围绕“项目介绍”模拟一次用户任务，不展示安装或运行结果。\n2. page-quickstart：快速开始。围绕“快速开始”模拟一次用户任务，不展示安装或运行结果。\n3. page-architecture：系统架构。围绕“系统架构”模拟一次用户任务，不展示安装或运行结果。\n4. page-tools-reference：工具参考。围绕“工具参考”模拟一次用户任务，不展示安装或运行结果。\n5. page-memory-operations：内存操作指南。围绕“内存操作指南”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-introduction\n输入：用户提供的“项目介绍”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-quickstart\n输入：用户提供的“快速开始”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-architecture\n输入：用户提供的“系统架构”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-tools-reference\n输入：用户提供的“工具参考”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-memory-operations\n输入：用户提供的“内存操作指南”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-introduction：Step 1 必须围绕“项目介绍”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-quickstart：Step 2 必须围绕“快速开始”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-architecture：Step 3 必须围绕“系统架构”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-tools-reference：Step 4 必须围绕“工具参考”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-memory-operations：Step 5 必须围绕“内存操作指南”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/dmang-dev/mcp-pine\n- https://github.com/dmang-dev/mcp-pine#readme\n- README.md\n- package.json\n- src/index.ts\n- src/pine.ts\n- src/tools.ts\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 mcp-pine 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start / 官方入口\n\n项目：dmang-dev/mcp-pine\n\n## 官方安装入口\n\n### Node.js / npm · 官方安装入口\n\n```bash\nnpm install -g mcp-pine\n```\n\n来源：https://github.com/dmang-dev/mcp-pine#readme\n\n## 来源\n\n- repo: https://github.com/dmang-dev/mcp-pine\n- docs: https://github.com/dmang-dev/mcp-pine#readme\n",
      "summary": "从项目官方 README 或安装文档提取的开工入口。",
      "title": "Quick Start / 官方入口"
    }
  },
  "validation_id": "dval_99340a3d39b8461282fe507952ba5142"
}
