{
  "canonical_name": "dmang-dev/mcp-pine",
  "compilation_id": "pack_6dd8a270b24248e5a2d0a904846b6829",
  "created_at": "2026-05-24T13:36:02.118813+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": "Knowledge Base Q&A",
        "label_zh": "知识库问答",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-knowledge-base-q-a",
        "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": "Checkpoint Resume",
        "label_zh": "断点恢复流程",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-checkpoint-resume",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Evaluation Suite",
        "label_zh": "评测体系",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-evaluation-suite",
        "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> Copy the prompt below into your AI host before installing anything.\n> Its purpose is to let you safely feel the project's workflow, not to claim the project has already run.\n\n## Copy this prompt\n\n```text\nYou are using an independent Doramagic capability pack for dmang-dev/mcp-pine.\n\nProject:\n- Name: mcp-pine\n- Repository: https://github.com/dmang-dev/mcp-pine\n- Summary: MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control\n- Host target: mcp_host, claude\n\nGoal:\nHelp me evaluate this project for the following task without installing it yet: MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control\n\nBefore taking action:\n1. Restate my task, success standard, and boundary.\n2. Identify whether the next step requires tools, browser access, network access, filesystem access, credentials, package installation, or host configuration.\n3. Use only the Doramagic Project Pack, the upstream repository, and the source-linked evidence listed below.\n4. If a real command, install step, API call, file write, or host integration is required, mark it as \"requires post-install verification\" and ask for approval first.\n5. If evidence is missing, say \"evidence is missing\" instead of filling the gap.\n\nPreviewable capabilities:\n- Capability 1: MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control\n\nCapabilities that require post-install verification:\n- Capability 1: Use the source-backed project context to guide one small, checkable workflow step.\n\nCore service flow:\n1. overview: Project Overview. Produce one small intermediate artifact and wait for confirmation.\n2. emulator-setup: Emulator Setup. Produce one small intermediate artifact and wait for confirmation.\n3. system-architecture: System Architecture. Produce one small intermediate artifact and wait for confirmation.\n4. configuration: Configuration Reference. Produce one small intermediate artifact and wait for confirmation.\n5. memory-operations: Memory Operations. Produce one small intermediate artifact and wait for confirmation.\n\nSource-backed evidence to keep in mind:\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/pine.ts\n- src/index.ts\n- src/tools.ts\n\nFirst response rules:\n1. Start Step 1 only.\n2. Explain the one service action you will perform first.\n3. Ask exactly three questions about my target workflow, success standard, and sandbox boundary.\n4. Stop and wait for my answers.\n\nStep 1 follow-up protocol:\n- After I answer the first three questions, stay in Step 1.\n- Produce six parts only: clarified task, success standard, boundary conditions, two or three options, tradeoffs for each option, and one recommendation.\n- End by asking whether I confirm the recommendation.\n- Do not move to Step 2 until I explicitly confirm.\n\nConversation rules:\n- Advance one step at a time and wait for confirmation after each small artifact.\n- Write outputs as recommendations or planned checks, not as completed execution.\n- Do not claim tests passed, files changed, commands ran, APIs were called, or the project was installed.\n- If the user asks for execution, first provide the sandbox setup, expected output, rollback, and approval checkpoint.\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:33:44 UTC\n\n## 目录\n\n- [Project Overview](#overview)\n- [Installation Guide](#installation)\n- [Emulator Setup](#emulator-setup)\n- [System Architecture](#system-architecture)\n- [Configuration Reference](#configuration)\n- [Memory Operations](#memory-operations)\n- [Savestate Management](#savestate-management)\n- [System Query Tools](#system-queries)\n- [Development Guide](#development-guide)\n- [Troubleshooting Guide](#troubleshooting)\n\n<a id='overview'></a>\n\n## Project Overview\n\n### 相关页面\n\n相关主题：[System Architecture](#system-architecture), [Emulator Setup](#emulator-setup)\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- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n</details>\n\n# Project Overview\n\n`mcp-pine` is a Model Context Protocol (MCP) server that bridges AI coding assistants (primarily Claude) with PINE-enabled PlayStation emulators. It exposes a suite of memory reading, memory writing, and save state management tools, enabling AI agents to introspect and manipulate live game state in real-time.\n\n## Project Purpose and Scope\n\nThe project serves as an intermediary layer between an AI assistant and emulator internals. Instead of requiring manual memory hunting or external tools, developers and power users can query game state through natural language, with the MCP server translating those requests into PINE protocol calls.\n\n**Core capabilities include:**\n\n- Reading memory at arbitrary addresses (8/16/32/64-bit values and bulk byte ranges)\n- Writing memory values to live game state\n- Querying emulator metadata (game title, serial, CRC, status)\n- Saving and loading emulator states to named slots\n- Supporting multiple emulator backends through a unified interface\n\n资料来源：[README.md:1](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## System Architecture\n\n```mermaid\ngraph TD\n    subgraph \"MCP Host (Claude)\"\n        A[Claude AI Assistant]\n    end\n    \n    subgraph \"mcp-pine\"\n        B[MCP Server<br/>src/index.ts]\n        C[Tool Handler<br/>src/tools.ts]\n        D[PINE Client<br/>src/pine.ts]\n    end\n    \n    subgraph \"Emulator\"\n        E[PCSX2 / RPCS3 / Duckstation]\n        F[PINE Server]\n    end\n    \n    A -->|MCP Protocol| B\n    B --> C\n    C --> D\n    D -->|PINE Wire Protocol| F\n    F --> E\n    \n    style A fill:#e1f5fe\n    style E fill:#fff3e0\n    style D fill:#e8f5e9\n```\n\nThe system consists of three main layers:\n\n| Layer | Component | Purpose |\n|-------|-----------|---------|\n| MCP Host | Claude Desktop / Claude Code | User interface; issues tool calls via MCP |\n| Bridge | `mcp-pine` (Node.js) | Translates MCP requests to PINE protocol; manages connection lifecycle |\n| Emulator | PCSX2 / RPCS3 / Duckstation | Executes game; exposes PINE server for IPC |\n\n资料来源：[README.md:23-51](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Supported Emulators\n\n| Emulator | Platform | Status | Notes |\n|----------|----------|--------|-------|\n| PCSX2 | Windows / Linux / macOS | **Primary** | Full PINE support; default target |\n| RPCS3 | Windows / Linux | Compatible | IPC implementation mirrors PINE; wire-level compatibility untested |\n| Duckstation | Multi-platform | Compatible | Varies by build; requires PINE-enabled build |\n\nPCSX2 is the reference implementation. It is recommended to use PCSX2 1.7.x Qt or newer with PINE enabled via **Settings → Advanced → Enable PINE Server**.\n\n资料来源：[README.md:29-47](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## MCP Tools Reference\n\nThe server exposes 13 MCP tools organized into four functional categories.\n\n### Connectivity & Introspection\n\n| Tool | Description |\n|------|-------------|\n| `pine_ping` | Returns emulator version string. Use to verify connectivity. |\n| `pine_get_info` | Batch-retrieves title, serial, disc CRC, game version, and status in one round-trip. |\n| `pine_get_status` | Returns emulator run state: `running`, `paused`, `shutdown`, or `unknown`. |\n\n资料来源：[src/tools.ts:45-85](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### Memory Reads\n\n| Tool | Width | Alignment | Use Case |\n|------|-------|-----------|----------|\n| `pine_read8` | 8-bit | None | Status flags, counters, single bytes |\n| `pine_read16` | 16-bit | 2-byte | 16-bit counters, flags |\n| `pine_read32` | 32-bit | 4-byte | Pointers, flags, game state values |\n| `pine_read64` | 64-bit | 8-byte | Large IDs, EE pointers, double-word state |\n| `pine_read_range` | Variable | Adaptive | Bulk reads up to 4096 bytes; uses largest aligned width at each step |\n\n> **Important:** PCSX2 does not enforce alignment. Unaligned multi-byte reads silently return corrupted data from the aligned address below. Use `pine_read_range` for unaligned spans.\n\n资料来源：[src/tools.ts:87-200](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### Memory Writes\n\n| Tool | Width | Destructive | Notes |\n|------|-------|-------------|-------|\n| `pine_write8` | 8-bit | Yes | Single-byte overwrite |\n| `pine_write16` | 16-bit | Yes | Requires 2-byte alignment |\n| `pine_write32` | 32-bit | Yes | Requires 4-byte alignment |\n| `pine_write64` | 64-bit | Yes | Requires 8-byte alignment; values encoded as decimal strings |\n\n资料来源：[src/tools.ts:200-260](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### Save State Management\n\n| Tool | Description |\n|------|-------------|\n| `pine_save_state` | Serializes current emulator state to a numbered slot (0-255). **Overwrites existing slot.** |\n| `pine_load_state` | Restores emulator state from a numbered slot. |\n\nSave state files are stored in emulator-specific locations:\n\n- **PCSX2 Windows:** `%USERPROFILE%\\Documents\\PCSX2\\sstates`\n- **PCSX2 Linux:** `~/.config/PCSX2/sstates`\n- Filename format: `<serial> (<crc>).<slot>.p2s`\n\n资料来源：[src/tools.ts:260-310](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Default | Platform | Purpose |\n|----------|---------|----------|---------|\n| `PINE_TARGET` | `pcsx2` | Linux/macOS | Emulator name; used as Unix socket filename prefix (`<target>.sock.<slot>`) |\n| `PINE_SLOT` | `28011` | All | PINE slot number (also port for TCP on Windows) |\n| `PINE_HOST` | `127.0.0.1` | Windows | TCP host override |\n| `PINE_SOCKET_PATH` | Auto-resolved | Unix | Full socket path override |\n| `PINE_PIPELINE_BATCH` | `1` | All | Number of serial reads to batch; higher values risk desyncing PCSX2's PINE server |\n\n资料来源：[README.md:52-60](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Socket Resolution\n\n| Platform | Transport | Path Resolution |\n|----------|-----------|-----------------|\n| Linux/macOS | Unix Domain Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>` → `$TMPDIR/<target>.sock.<slot>` → `/tmp/<target>.sock.<slot>` |\n| Windows | TCP | `127.0.0.1:<PINE_SLOT>` |\n\n资料来源：[src/pine.ts:1-80](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## PINE Protocol Implementation\n\nThe `PineClient` class implements the binary PINE wire format:\n\n```mermaid\nsequenceDiagram\n    participant C as MCP Bridge\n    participant P as PineClient\n    participant E as Emulator PINE Server\n    \n    C->>P: pine_read32(0x00100000)\n    P->>P: Buffer.alloc(9)<br/>[4-byte size][opcode][4-byte addr]\n    P->>E: TCP/Unix Socket\n    E-->>P: Reply frame\n    P->>P: Parse response\n    P-->>C: number value\n```\n\n**Wire format per call:**\n\n| Field | Size | Encoding |\n|-------|------|----------|\n| Frame size | 4 bytes | UInt32LE (includes opcode + payload) |\n| Opcode | 1 byte | UInt8 |\n| Payload | Variable | Little-endian |\n\n**Opcodes:**\n\n| Opcode | Name | Direction | Payload |\n|--------|------|-----------|---------|\n| 0x01 | Version | Read | None |\n| 0x02 | Title | Read | None |\n| 0x03 | ID | Read | None |\n| 0x04 | UUID | Read | None |\n| 0x05 | GameVersion | Read | None |\n| 0x06 | SaveState | Write | 1 byte (slot) |\n| 0x07 | LoadState | Write | 1 byte (slot) |\n| 0x08 | Read8 | Read | 4 bytes (address) |\n| 0x09 | Read16 | Read | 4 bytes (address) |\n| 0x0A | Read32 | Read | 4 bytes (address) |\n| 0x0B | Read64 | Read | 4 bytes (address) |\n| 0x0C | Write8 | Write | 1 byte (value) + 4 bytes (address) |\n| 0x0D | Write16 | Write | 2 bytes (value) + 4 bytes (address) |\n| 0x0E | Write32 | Write | 4 bytes (value) + 4 bytes (address) |\n| 0x0F | Status | Read | None |\n| 0x10 | Write64 | Write | 8 bytes (value) + 4 bytes (address) |\n\n资料来源：[src/pine.ts:81-200](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## Installation\n\n### Package Distribution\n\n| Method | Command | Use Case |\n|--------|---------|----------|\n| npm global | `npm install -g mcp-pine` | System-wide installation |\n| npx (on-demand) | `npx -y mcp-pine` | Temporary testing |\n| Source | `git clone` + `npm install` | Development |\n\n资料来源：[README.md:61-72](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Claude Desktop Integration\n\nAdd to `claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\nConfig location by platform:\n\n| Platform | Path |\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资料来源：[README.md:14-35](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Technical Constraints and Known Issues\n\n### PCSX2 PINE Server Fragility\n\nPCSX2's PINE server has a **fragile request queue**. Dropping any single request (which occurs silently when too many requests are pipelined) desyncs the reply pipeline. Once desynced, every subsequent reply is misaligned, causing all tools to timeout until the emulator is restarted.\n\n| Setting | Value | Latency | Safety |\n|---------|-------|---------|--------|\n| `PINE_PIPELINE_BATCH=1` | Serial | ~52ms for 4096 bytes | Safe (default) |\n| `PINE_PIPELINE_BATCH=2+` | Batched | Lower | Risk of desync |\n\nThe default serial mode completes a full 4KB read in under two emulated frames, making pipelining unnecessary for most use cases.\n\n资料来源：[CHANGELOG.md:15-40](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n### Troubleshooting Reference\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running, PINE disabled, port mismatch | Check `PINE_SLOT` and emulator settings |\n| `PINE FAIL response (0xFF)` | No game loaded, address unmapped | Load a game; verify address range |\n| Reads return zeros | Address in unallocated region | Try `0x00100000` (EE main RAM) |\n| Values look corrupted | Endianness mismatch | PINE returns little-endian |\n| `PINE call timed out (10s)` after heavy use | PCSX2 PINE server desynced | **Fully restart PCSX2** |\n\n资料来源：[README.md:95-120](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Dependencies\n\n```json\n{\n  \"dependencies\": {\n    \"@modelcontextprotocol/sdk\": \"^1.12.0\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^22.0.0\",\n    \"typescript\": \"^5.5.0\"\n  }\n}\n```\n\nThe project targets Node.js and uses TypeScript for type safety. The `@modelcontextprotocol/sdk` package provides the MCP server infrastructure.\n\n资料来源：[package.json:1-30](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n\n## Related Projects\n\n| Project | Repository | Description |\n|---------|------------|-------------|\n| mcp-mgba | [dmang-dev/mcp-mgba](https://github.com/dmang-dev/mcp-mgba) | Sister MCP server for mGBA (Game Boy Advance); includes button input and screenshot support |\n| PINE Protocol | [GovanifY/pine](https://github.com/GovanifY/pine) | Underlying IPC specification |\n\n资料来源：[README.md:140-145](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n---\n\n<a id='installation'></a>\n\n## Installation Guide\n\n### 相关页面\n\n相关主题：[Configuration Reference](#configuration), [Troubleshooting Guide](#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- [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</details>\n\n# Installation Guide\n\nThis guide covers all supported methods for installing and configuring `mcp-pine`, a Model Context Protocol (MCP) server that bridges MCP clients to emulators via the PINE protocol.\n\n## Overview\n\n`mcp-pine` enables AI assistants like Claude to interact with PlayStation emulators (PCSX2, RPCS3, Duckstation) through the PINE IPC protocol. It exposes memory read/write tools, save state management, and emulator introspection as MCP tools.\n\n| Component | Technology | Purpose |\n|-----------|------------|---------|\n| MCP Server | TypeScript + Node.js | Bridges MCP clients to PINE protocol |\n| Transport | stdio | Standard MCP communication |\n| Emulator IPC | PINE protocol | Binary memory/state access |\n| Connections | TCP/Unix Socket | Platform-specific transport |\n\n资料来源：[README.md:1-10]()\n\n## Installation Methods\n\n### Method 1: Global npm Install\n\nInstall globally via npm for system-wide access:\n\n```bash\nnpm install -g mcp-pine\n```\n\nThis makes `mcp-pine` available as a command-line tool accessible from any terminal session.\n\n资料来源：[README.md:44-47]()\n\n### Method 2: Direct Execution with npx\n\nRun without installation using npx:\n\n```bash\nnpx -y mcp-pine\n```\n\nThis downloads and executes the package temporarily, useful for testing or one-off usage.\n\n资料来源：[README.md:49-51]()\n\n### Method 3: Clone and Develop\n\nFor development or customization:\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install        # also runs the build via the `prepare` hook\n```\n\nFor live development with TypeScript watching:\n\n```bash\nnpm run dev      # tsc --watch\n```\n\n资料来源：[README.md:53-60]()\n\n## Emulator Setup\n\n### PCSX2 (Recommended)\n\nPCSX2 1.7.x and newer include native PINE server support:\n\n1. Launch PCSX2 (1.7.x Qt or newer)\n2. Navigate to **Settings → Advanced → Enable PINE Server**\n3. Default slot is **28011**\n\n> **Note:** If the option is in a different submenu, search settings for \"PINE\".\n\nOnce enabled, PINE is always-on—no scripts or console commands required. Load any game to start interacting.\n\n资料来源：[README.md:23-33]()\n\n### RPCS3\n\nRPCS3 uses an IPC implementation that mirrors PINE's opcode set:\n\n1. Navigate to **Configuration → Advanced → Enable IPC server**\n2. Note the configured port\n3. Run with: `PINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine`\n\n> **Note:** Wire-level compatibility with RPCS3 hasn't been thoroughly tested. File issues if problems occur.\n\n资料来源：[README.md:35-44]()\n\n### Duckstation\n\nDuckstation builds vary in PINE support:\n\n1. Verify your build includes a PINE server\n2. Set `PINE_TARGET=duckstation PINE_SLOT=<port>`\n\n资料来源：[README.md:46-48]()\n\n## MCP Client Registration\n\n### Claude Code (CLI)\n\nRegister for user-wide access:\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\nVerify the connection:\n\n```bash\nclaude mcp list\n# pine: mcp-pine - ✓ Connected\n```\n\n资料来源：[README.md:11-17]()\n\n### Claude Desktop\n\nEdit the configuration file for your platform:\n\n| Platform | Path |\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\nAdd the server configuration:\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\nRestart Claude Desktop after editing.\n\n资料来源：[README.md:19-32]()\n\n### Other MCP Clients\n\n`mcp-pine` speaks standard MCP over stdio. Run the binary and connect any compatible client:\n\n```bash\nmcp-pine\n```\n\n资料来源：[README.md:45-46]()\n\n## Configuration\n\n### Environment Variables\n\n| Env Variable | Default | Purpose |\n|--------------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator name—used as Unix socket prefix on Linux/macOS (`<target>.sock.<slot>`). Ignored on Windows (TCP only). |\n| `PINE_SLOT` | `28011` | PINE slot number—also the TCP port on Windows. |\n| `PINE_HOST` | `127.0.0.1` | Override the connection host |\n| `PINE_SOCKET_PATH` | Auto-resolved | Override the Unix socket path |\n| `PINE_PIPELINE_BATCH` | `1` | Number of pipelined requests (see Performance Notes) |\n\n资料来源：[README.md:34-43]()\n\n### Socket Path Resolution\n\nConnection transport varies by platform:\n\n```mermaid\ngraph TD\n    A[Start] --> B{Platform?}\n    B -->|Windows| C[TCP 127.0.0.1:PINE_SLOT]\n    B -->|Linux/macOS| D{Look for XDG_RUNTIME_DIR}\n    D -->|Set| E[Use $XDG_RUNTIME_DIR/<target>.sock.<slot>]\n    D -->|Not Set| F{ TMPDIR set?}\n    F -->|Yes| G[Use $TMPDIR/<target>.sock.<slot>]\n    F -->|No| H[Use /tmp/<target>.sock.<slot>]\n```\n\n资料来源：[src/pine.ts:60-75]()\n\n## Smoke Testing\n\nTest against a running emulator:\n\n```bash\nnode .scratch/smoke.cjs\n```\n\n资料来源：[README.md:66-69]()\n\n## Troubleshooting\n\n### Common Issues\n\n| Symptom | Cause / Fix |\n|---------|-------------|\n| `Cannot reach PINE server` | Emulator isn't running, PINE isn't enabled in settings, or slot/port doesn't match. Check `PINE_SLOT`. |\n| `PINE FAIL response` (0xFF) | Emulator rejected request—usually no game loaded or address is unmapped. |\n| Reads return zeros | Address is in an unallocated region. Try `0x00100000` first (almost always inside EE RAM). |\n| Tool calls work but values look corrupted | Check endianness—PINE returns little-endian. Use `read_range`-style byte reads for strings. |\n| `pine_ping` times out after heavy use | **PCSX2 PINE server is wedged.** Only a full emulator restart recovers. Reconnecting alone won't help. |\n\n资料来源：[README.md:68-78]()\n\n### PCSX2 Pipeline Drop Bug\n\nPCSX2's PINE server has a fragile request queue. If more than ~6 in-flight requests are pipelined, it silently drops requests, desyncing the reply pipeline. Once desynced, every reply is misaligned—only an emulator restart fixes this.\n\n| Operation | Latency | Notes |\n|-----------|---------|-------|\n| Full 4096-byte read | ~52 ms | Fully serial requests over loopback TCP |\n| Pipelined requests | Faster but risky | `PINE_PIPELINE_BATCH=2` for experimental use |\n\n资料来源：[src/pine.ts:115-125]()\n\n## Project Structure\n\n```\nmcp-pine/\n├── src/\n│   ├── index.ts      # Main entry point, MCP server setup\n│   ├── pine.ts       # PINE protocol client implementation\n│   └── tools.ts      # MCP tool definitions\n├── .scratch/\n│   └── smoke.cjs     # Quick smoke test script\n├── package.json      # Dependencies and scripts\n└── README.md         # Documentation\n```\n\n## Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `@modelcontextprotocol/sdk` | ^1.12.0 | MCP server framework |\n| `@types/node` | ^22.0.0 | TypeScript types |\n| `typescript` | ^5.5.0 | Build tooling |\n\n资料来源：[package.json:8-14]()\n\n## See Also\n\n- [mcp-mgba](https://github.com/dmang-dev/mcp-mgba) — Sister MCP server for mGBA (includes button input + screenshot)\n- [PINE protocol spec](https://github.com/GovanifY/pine) — Underlying IPC standard\n- [docs/RECIPES.md](docs/RECIPES.md) — Cookbook for common workflows (RAM hunting, struct decoding, snapshot-experiment-restore)\n\n---\n\n<a id='emulator-setup'></a>\n\n## Emulator Setup\n\n### 相关页面\n\n相关主题：[Configuration Reference](#configuration), [Troubleshooting Guide](#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/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# Emulator Setup\n\nThis page documents how to configure and connect PlayStation 2 emulators to the mcp-pine MCP server. mcp-pine acts as a bridge between AI assistants (via the Model Context Protocol) and the PINE IPC (PlayStation 2 Interactive Interface) server embedded in compatible emulators.\n\n## Overview\n\nmcp-pine requires a running emulator with PINE server support enabled. The server communicates with the emulator through either TCP (Windows) or Unix domain sockets (Linux/macOS), allowing AI assistants to read/write memory, query game metadata, and manage save states.\n\n**Supported emulators:**\n\n| Emulator | Platform | PINE Support | Notes |\n|----------|----------|--------------|-------|\n| PCSX2 (1.7.x Qt+) | All | Native | Full support; recommended |\n| RPCS3 | All | Partial | IPC implementation mirrors PINE; wire compatibility untested |\n| Duckstation | All | Varies | Build-dependent; check your version |\n\n资料来源：[README.md:1-50](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Architecture\n\nThe connection flow between mcp-pine and the emulator follows a client-server pattern:\n\n```mermaid\ngraph LR\n    subgraph \"Host System\"\n        A[\"Claude / MCP Client\"] --> B[\"mcp-pine\"]\n        B --> C[\"Emulator PINE Server\"]\n    end\n    \n    D[\"PlayStation 2 Game\"] --> C\n    \n    C -->|TCP 127.0.0.1:28011<br/>Unix Socket<br/>/tmp/pcsx2.sock.28011| B\n    \n    style C fill:#90EE90\n    style B fill:#87CEEB\n```\n\n**Connection transport selection:**\n\n- **Windows:** TCP socket to `127.0.0.1:<PINE_SLOT>`\n- **Linux/macOS:** Unix domain socket at `<TMPDIR or /tmp>/<PINE_TARGET>.sock.<PINE_SLOT>`\n\n资料来源：[src/pine.ts:150-200](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator name—used as Unix socket filename prefix on Linux/macOS |\n| `PINE_SLOT` | `28011` | PINE slot number (port on Windows, socket suffix on Unix) |\n| `PINE_PIPELINE_BATCH` | `1` | Number of serial PINE requests to batch (higher = faster but riskier) |\n\n资料来源：[README.md:60-75](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Socket Path Resolution\n\nThe `PineClient` class resolves the socket path based on platform and options:\n\n```mermaid\ngraph TD\n    A[\"PineClient constructor\"] --> B{opts.kind explicitly set?}\n    B -->|Yes| C[\"Use opts.host/opts.path\"]\n    B -->|No| D{Platform = Windows?}\n    D -->|Yes| E[\"TCP: 127.0.0.1:PINE_SLOT\"]\n    D -->|No| F{Platform = Linux/macOS?}\n    F -->|Yes| G[\"Unix: XDG_RUNTIME_DIR<br/>or TMPDIR<br/>/<target>.sock.<slot>\"]\n    F -->|No| H[\"TCP fallback: localhost:PINE_SLOT\"]\n    \n    style G fill:#90EE90\n    style E fill:#87CEEB\n```\n\n资料来源：[src/pine.ts:100-180](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## PCSX2 Setup\n\nPCSX2 provides native, stable PINE server support starting from version 1.7.x Qt.\n\n### Prerequisites\n\n- PCSX2 1.7.x (Qt build) or newer\n- A loaded PlayStation 2 game\n\n### Configuration Steps\n\n1. Launch PCSX2\n2. Navigate to **Settings → Advanced → Enable PINE Server**\n   - The option location may vary slightly by build version\n   - Use the settings search function to find \"PINE\" if the menu structure differs\n3. Verify the default slot is **28011**\n4. Load any PlayStation 2 game\n\nNo console commands or external scripts are required—PINE is always-on once the toggle is enabled.\n\n资料来源：[README.md:30-45](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## RPCS3 Setup\n\nRPCS3 implements its own IPC mechanism that mirrors PINE's opcode set, but wire-level compatibility with this client has not been thoroughly tested.\n\n### Configuration Steps\n\n1. Navigate to **Configuration → Advanced → Enable IPC server**\n2. Note the configured port number\n3. Run mcp-pine with the target override:\n\n```bash\nPINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine\n```\n\n**Note:** Full compatibility is not guaranteed. If issues arise, please file a bug report with connection logs and emulator version information.\n\n资料来源：[README.md:46-55](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Duckstation Setup\n\nDuckstation includes PINE server support in some builds, but availability varies by version and distribution.\n\n### Configuration\n\nIf your Duckstation build includes PINE support:\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=<port> mcp-pine\n```\n\n**Note:** Check your Duckstation build version to confirm PINE server availability.\n\n资料来源：[README.md:56-60](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## MCP Client Registration\n\nAfter the emulator is configured, register mcp-pine with your MCP client.\n\n### Claude Code (CLI)\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\nVerify registration:\n\n```bash\nclaude mcp list\n# pine: mcp-pine - ✓ Connected\n```\n\n资料来源：[README.md:85-95](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Claude Desktop\n\nEdit the configuration file at your platform-specific location:\n\n| Platform | Path |\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\nAdd the mcp-pine server entry:\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\nRestart Claude Desktop after editing.\n\n资料来源：[README.md:96-115](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Available Tools\n\nOnce connected, the following tools are available through the MCP interface:\n\n| Tool | Purpose | Call Type |\n|------|---------|-----------|\n| `pine_ping` | Verify connection to emulator | 1 round-trip |\n| `pine_get_info` | Get game title, serial, CRC, version, and status | 5 parallel calls |\n| `pine_get_status` | Get emulator run state (running/paused/shutdown) | 1 round-trip |\n| `pine_read8/16/32/64` | Read bytes from EE memory | 1 round-trip each |\n| `pine_read_range` | Bulk read up to 4096 bytes | Serial sequence |\n| `pine_write8/16/32/64` | Write bytes to EE memory | 1 round-trip each |\n| `pine_save_state` | Save emulator state to slot | 1 round-trip |\n| `pine_load_state` | Load emulator state from slot | 1 round-trip |\n\n### Address Parameter Notes\n\nAll address parameters reference the **EE main address space**. Key memory regions:\n\n| Region | Address Range | Description |\n|--------|---------------|-------------|\n| EE Main RAM | `0x00100000` – `0x01FFFFFF` | Primary game state memory (99% of use cases) |\n| IOP RAM | `0x1C000000`+ | Input/Output Processor memory |\n| Scratchpad | `0x70000000` – `0x70003FFF` | Fast local memory |\n\n**Alignment requirements:**\n\n| Width | Alignment | Notes |\n|-------|-----------|-------|\n| 8-bit | None | Safe to use at any address |\n| 16-bit | 2-byte | Misaligned access silently corrupts data |\n| 32-bit | 4-byte | Misaligned access silently corrupts data |\n| 64-bit | 8-byte | Misaligned access silently corrupts data |\n\n**Important:** PCSX2's PINE implementation does NOT enforce alignment. Misaligned multi-byte access returns bytes from the aligned address below, silently corrupting values.\n\n资料来源：[src/tools.ts:1-100](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## Troubleshooting\n\n### Common Issues\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running, PINE not enabled, or slot mismatch | Check `PINE_SLOT` matches emulator setting |\n| `PINE FAIL response` (0xFF) | No game loaded, or address unmapped | Load a game; try `0x00100000` first |\n| Reads return zeros | Address in unallocated region | Use `0x00100000` (EE RAM base) |\n| Values look corrupted | Wrong endianness or alignment | PINE returns little-endian; use `pine_read_range` for byte-level control |\n| `PINE call timed out (10s)` after heavy use | PCSX2 PINE queue desync | Full PCSX2 restart required—reconnecting alone won't help |\n\n资料来源：[README.md:130-150](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### PCSX2 PINE Queue Desync\n\nPCSX2's PINE server has a fragile request queue. If more than approximately 6 in-flight requests are issued, the server silently drops requests, corrupting the reply pipeline alignment. Once desynced, every subsequent reply is misaligned, causing timeouts on even simple operations like `pine_ping`.\n\n**Symptoms:**\n- Fresh `pine_ping` calls timing out after heavy use\n- Intermittent read/write failures\n- Non-deterministic response values\n\n**Fix:**\n1. Fully restart PCSX2\n2. Reconnect mcp-pine\n3. Reduce `PINE_PIPELINE_BATCH` to `1` (default)\n\n资料来源：[README.md:155-165](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)  \n资料来源：[src/pine.ts:60-90](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n### Performance Considerations\n\n`pine_read_range` issues PINE calls serially by default to avoid queue desync. Measured performance on PCSX2 v2.6.3:\n\n| Operation | Latency |\n|-----------|---------|\n| Full 4096-byte read | ~52 ms |\n| Per 64-bit word | ~13 ms |\n\nLoopback TCP is fast enough that serial reads complete in less than two emulated frames. For lower latency with acceptable risk, set `PINE_PIPELINE_BATCH=2` or higher.\n\n**Warning:** Higher batch values increase the probability of triggering PCSX2's queue drop behavior.\n\n资料来源：[README.md:166-175](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Development Setup\n\nFor testing against a running emulator:\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install        # Runs build via prepare hook\n\n# Development mode with TypeScript watching\nnpm run dev\n\n# Smoke test\nnode .scratch/smoke.cjs\n```\n\nThe project builds using TypeScript 5.5+ with Node 22+ support.\n\n资料来源：[README.md:175-190](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)  \n资料来源：[package.json:1-30](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n\n---\n\n<a id='system-architecture'></a>\n\n## System Architecture\n\n### 相关页面\n\n相关主题：[Memory Operations](#memory-operations), [Savestate Management](#savestate-management), [System Query Tools](#system-queries)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\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</details>\n\n# System Architecture\n\n## Overview\n\nmcp-pine is an MCP (Model Context Protocol) server that bridges AI assistants (such as Claude) with PlayStation 2 emulators (PCSX2, RPCS3, Duckstation) via the PINE (Platform Independent Networked Environment) protocol. It exposes emulator memory, save states, and game information as MCP tools, enabling AI-driven game analysis, memory hacking, and automation workflows.\n\nThe architecture follows a layered client-server model with three distinct subsystems: the MCP protocol layer, the PINE protocol client, and the cross-platform transport layer.\n\n## High-Level Architecture\n\n```mermaid\ngraph TD\n    subgraph \"MCP Host (Claude)\"\n        A[\"Claude AI\"]\n    end\n    \n    subgraph \"mcp-pine\"\n        B[\"MCP Server<br/>(@modelcontextprotocol/sdk)\"]\n        C[\"PineClient<br/>(Protocol Layer)\"]\n        D[\"Transport Layer<br/>(TCP / Unix Socket)\"]\n    end\n    \n    subgraph \"Emulator\"\n        E[\"PINE Server\"]\n        F[\"EE Memory<br/>IOP Memory<br/>Save States\"]\n    end\n    \n    A <-->|\"MCP stdio\"| B\n    B <-->|\"Tool Calls\"| C\n    C <-->|\"PINE Protocol\"| D\n    D <-->|\"TCP:127.0.0.1<br/>Unix:/tmp/*.sock\"| E\n    E <--> F\n```\n\n**资料来源：** [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md) - Project overview and configuration documentation\n\n## Component Architecture\n\n### Layer 1: MCP Server\n\nThe MCP server layer implements the Model Context Protocol specification using the `@modelcontextprotocol/sdk`. It registers tool handlers and routes incoming tool calls to the PINE client.\n\n| Component | File | Responsibility |\n|-----------|------|----------------|\n| `registerTools()` | `src/tools.ts` | Registers all 13 MCP tools with the SDK |\n| Tool dispatcher | `src/tools.ts` | Routes `CallToolRequest` to corresponding PINE operations |\n| Response formatter | `src/tools.ts` | Formats PINE responses for MCP protocol |\n\n**资料来源：** [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) - MCP tool registration and handler implementation\n\n### Layer 2: PINE Protocol Client\n\nThe `PineClient` class (`src/pine.ts`) implements the binary PINE wire format specification. It handles request encoding, response decoding, and protocol state management.\n\n```mermaid\ngraph LR\n    A[\"Tool Request\"] --> B[\"Encode Opcode<br/>+ Payload\"]\n    B --> C[\"Buffer<br/>(4-byte size prefix)\"]\n    C --> D[\"Socket Write\"]\n    D --> E[\"Response Read\"]\n    E --> F[\"Parse Size\"]\n    F --> G[\"Extract Opcode<br/>+ Data\"]\n    G --> H[\"Decode Value\"]\n    H --> I[\"Return to Tool\"]\n```\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - PINE client implementation\n\n#### Opcode Mapping\n\n| Operation | Opcode | Direction | Description |\n|-----------|--------|-----------|-------------|\n| `getVersion` | `Op.Version` | Read | Emulator version string |\n| `getTitle` | `Op.Title` | Read | Game title |\n| `getId` | `Op.ID` | Read | Game serial number |\n| `getUuid` | `Op.UUID` | Read | Disc CRC hash |\n| `getGameVersion` | `Op.GameVersion` | Read | Game version string |\n| `getStatus` | `Op.Status` | Read | Emulator state (running/paused/shutdown) |\n| `read8/16/32/64` | `Op.Read*` | Read | Memory reads at specified width |\n| `write8/16/32/64` | `Op.Write*` | Write | Memory writes at specified width |\n| `saveState` | `Op.SaveState` | Write | Save to slot (0-255) |\n| `loadState` | `Op.LoadState` | Write | Load from slot (0-255) |\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - Opcode constants and operation implementations\n\n### Layer 3: Transport Layer\n\nThe transport layer provides cross-platform connectivity using the appropriate socket type for each operating system.\n\n```mermaid\ngraph TD\n    A[\"Platform Detection\"] --> B{OS?}\n    B -->|Windows| C[\"TCP Socket<br/>127.0.0.1:SLOT\"]\n    B -->|Linux/macOS| D[\"Unix Domain Socket\"]\n    D --> E[\"$XDG_RUNTIME_DIR<br/>/<target>.sock.<slot>\"]\n    D --> F[\"$TMPDIR<br/>/<target>.sock.<slot>\"]\n    D --> G[\"/tmp<br/>/<target>.sock.<slot>\"]\n```\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - `resolveSocket()` function and transport abstraction\n\n#### Socket Resolution Strategy\n\n| Priority | Linux/macOS Path | Windows |\n|----------|------------------|---------|\n| 1 | `$XDG_RUNTIME_DIR/<target>.sock.<slot>` | TCP `127.0.0.1:<slot>` |\n| 2 | `$TMPDIR/<target>.sock.<slot>` | — |\n| 3 | `/tmp/<target>.sock.<slot>` | — |\n\n**资料来源：** [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md) - Configuration and transport documentation\n\n## Request Queue Management\n\nThe `PineClient` maintains an internal request queue to handle concurrent tool calls and ensure responses are matched to their originating requests.\n\n```mermaid\nsequenceDiagram\n    participant Tool1 as Tool Call 1\n    participant Tool2 as Tool Call 2\n    participant Queue as Request Queue\n    participant Client as PineClient\n    participant Socket as Network Socket\n    \n    Tool1->>Queue: Enqueue request\n    Tool2->>Queue: Enqueue request\n    Queue->>Socket: Write Request 1\n    Queue->>Socket: Write Request 2\n    Socket-->>Client: Receive Response 1\n    Client->>Queue: Resolve Promise 1\n    Socket-->>Client: Receive Response 2\n    Client->>Queue: Resolve Promise 2\n```\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - Request queue implementation\n\n### Pending Request Structure\n\n```typescript\ninterface Pending {\n  resolve: (value: Buffer) => void;\n  reject: (err: Error) => void;\n}\n```\n\nEach pending request holds references to its `resolve` and `reject` functions, allowing the response handler to deliver results to the correct caller even when multiple requests are in-flight.\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - Pending interface definition\n\n## Bulk Read Implementation\n\nThe `readRange()` method implements efficient bulk memory reads by combining multiple aligned PINE operations.\n\n```mermaid\ngraph TD\n    A[\"readRange(addr, length)\"] --> B[\"Calculate Steps\"]\n    B --> C{\"Aligned?\"}\n    C -->|8-byte| D[\"read64\"]\n    C -->|4-byte| E[\"read32\"]\n    C -->|2-byte| F[\"read16\"]\n    C -->|1-byte| G[\"read8\"]\n    D --> H[\"PIPELINE_BATCH\"]\n    E --> H\n    F --> H\n    G --> H\n    H --> I[\"Promise.all(batch)\"]\n    I --> J{\"More steps?\"}\n    J -->|Yes| H\n    J -->|No| K[\"Return Buffer\"]\n```\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - `readRange()` implementation\n\n### Pipelining Configuration\n\n| Env Variable | Default | Effect |\n|--------------|---------|--------|\n| `PINE_PIPELINE_BATCH` | `1` | Number of concurrent requests (1=serial, 2+=parallel) |\n\n> **Warning:** PCSX2's PINE server silently drops requests when too many are pipelined (~7+ in-flight). This desyncs the reply pipeline, causing all subsequent requests to time out until emulator restart.\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - Pipeline batch configuration\n\n## Tool Registration Flow\n\n```mermaid\ngraph LR\n    A[\"MCP Server<br/>Instantiation\"] --> B[\"PineClient<br/>Creation\"]\n    B --> C[\"registerTools()<br/>called\"]\n    C --> D[\"ListToolsRequestHandler<br/>registered\"]\n    C --> E[\"CallToolRequestHandler<br/>registered\"]\n    F[\"MCP Host<br/>connects\"] --> G[\"ListTools<br/>request\"]\n    G --> H[\"TOOLS[]<br/>schema returned\"]\n    F --> I[\"Tool Call<br/>invoked\"]\n    I --> J[\"switch(name)<br/>dispatch\"]\n    J --> K[\"PineClient<br/>operation\"]\n```\n\n**资料来源：** [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) - Tool registration and dispatch\n\n## Memory Address Space\n\nThe PINE protocol operates on PlayStation 2 memory regions. All address parameters use absolute byte addresses in the EE (Emotion Engine) main address space.\n\n| Region | Address Range | Size | Description |\n|--------|---------------|------|-------------|\n| EE Main RAM | `0x00100000` - `0x01FFFFFF` | ~31 MB | Primary game state storage |\n| IOP RAM | `0x1C000000`+ | Variable | I/O Processor memory |\n| Scratchpad | Special range | 16 KB | Fast-access cache |\n\n> **Alignment Note:** Multi-byte reads/writes (16/32/64-bit) must be aligned to their width. PINE on PCSX2 does NOT enforce alignment — unaligned access silently returns corrupted data.\n\n**资料来源：** [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) - Address parameter descriptions\n\n## 64-bit Value Handling\n\nJavaScript's `Number` type loses precision beyond `2^53`. The implementation handles 64-bit values as decimal strings.\n\n| Operation | Input Format | Output Format | Reason |\n|-----------|-------------|---------------|--------|\n| `pine_write64` | Decimal string (`\"18446744073709551615\"`) | — | Preserve full u64 range |\n| `pine_read64` | — | Decimal string | Preserve full u64 range |\n\n**资料来源：** [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) - 64-bit parameter descriptions\n\n## Configuration Environment Variables\n\n| Variable | Default | Platform | Purpose |\n|----------|---------|----------|---------|\n| `PINE_TARGET` | `pcsx2` | All | Emulator name prefix for Unix socket path |\n| `PINE_SLOT` | `28011` | All | PINE slot number (also port on Windows) |\n| `PINE_HOST` | `127.0.0.1` | Windows | TCP host override |\n| `PINE_SOCKET_PATH` | Auto | All | Custom Unix socket path |\n| `PINE_PIPELINE_BATCH` | `1` | All | Concurrent request batching |\n| `PIPELINE_BATCH` | `1` | All | Alias for `PINE_PIPELINE_BATCH` |\n\n**资料来源：** [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md) - Configuration table\n\n## Error Handling\n\n| Error | Cause | Fix |\n|-------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running or PINE disabled | Check `PINE_SLOT` matches emulator settings |\n| `PINE FAIL response (0xFF)` | No game loaded or address unmapped | Load a game; verify address range |\n| Reads return zeros | Address in unallocated region | Try `0x00100000` first (EE RAM base) |\n| Values look corrupted | Endianness mismatch | PINE returns little-endian; check parsing |\n| `PINE call timed out (10s)` | PCSX2 PINE server wedged | Full emulator restart required |\n\n**资料来源：** [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md) - Troubleshooting section\n\n## Lazy Reconnect Behavior\n\nThe MCP server implements lazy reconnection — if the emulator is restarted, the PINE client automatically reconnects without requiring the MCP host to restart.\n\n```mermaid\ngraph TD\n    A[\"Tool Call\"] --> B{\"Connected?\"}\n    B -->|No| C[\"Connect()\"]\n    C --> D{\"Success?\"}\n    D -->|Yes| E[\"Send Request\"]\n    D -->|No| F[\"Error (retry next call)\"]\n    B -->|Yes| E\n    E --> G[\"Response\"]\n```\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - Connection management\n\n## Package Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `@modelcontextprotocol/sdk` | `^1.12.0` | MCP protocol implementation |\n| `typescript` | `^5.5.0` | TypeScript compilation (dev) |\n| `@types/node` | `^22.0.0` | Node.js type definitions (dev) |\n\n**资料来源：** [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json) - Dependencies section\n\n## Supported Emulators\n\n| Emulator | Platform | Status | Notes |\n|----------|----------|--------|-------|\n| PCSX2 | All | Primary | Full PINE support; Qt 1.7.x+ |\n| RPCS3 | All | Experimental | IPC implementation mirrors PINE; wire compatibility untested |\n| Duckstation | All | Varies | Depends on build; PINE server availability varies |\n\n**资料来源：** [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md) - Emulator setup documentation\n\n---\n\n<a id='configuration'></a>\n\n## Configuration Reference\n\n### 相关页面\n\n相关主题：[Emulator Setup](#emulator-setup), [System Architecture](#system-architecture)\n\n<details>\n<summary>Related Source Files</summary>\n\nThe following source files were used to generate this page:\n\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- [src/index.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/index.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# Configuration Reference\n\n## Overview\n\nThe `mcp-pine` project provides a Model Context Protocol (MCP) server that bridges MCP clients (such as Claude Code or Claude Desktop) to PlayStation 2/3 emulators via the PINE (Platform Independent Networked Environment) protocol. Configuration is driven entirely through environment variables, allowing users to customize connection targets, communication protocols, and runtime behavior without modifying code.\n\nThis reference documents all supported environment variables, their default values, acceptable ranges, and behavioral implications.\n\n---\n\n## Environment Variables Summary\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator identifier for socket path resolution |\n| `PINE_SLOT` | `28011` | PINE slot/port number for connection |\n| `PINE_HOST` | `127.0.0.1` | Host address for TCP connections |\n| `PINE_SOCKET_PATH` | auto-generated | Override Unix socket or TCP path |\n| `PINE_PIPELINE_BATCH` | `1` | Number of concurrent in-flight PINE requests |\n\n---\n\n## Connection Configuration\n\n### `PINE_TARGET`\n\nSpecifies the target emulator name, which determines the Unix socket file prefix on Linux/macOS systems.\n\n**Type:** string  \n**Default:** `pcsx2`  \n**Valid Values:** `pcsx2`, `rpcs3`, `duckstation`\n\n```mermaid\ngraph LR\n    A[PINE_TARGET] --> B{Platform?}\n    B -->|Linux/macOS| C[Unix Socket Path]\n    B -->|Windows| D[TCP Connection]\n    C --> E[\"<target>.sock.<slot>\"]\n    D --> F[\"127.0.0.1:<slot>\"]\n```\n\nOn Linux/macOS, the socket path follows the pattern `<target>.sock.<slot>`. The system resolves the directory using:\n\n1. `$XDG_RUNTIME_DIR` (Linux common)\n2. `$TMPDIR` (macOS common)\n3. `/tmp` (fallback)\n\n**Example:**\n\n```bash\nPINE_TARGET=pcsx2 PINE_SLOT=28011 mcp-pine\n# Linux socket: /run/user/1000/pcsx2.sock.28011\n```\n\n资料来源：[README.md:45-50]()\n\n### `PINE_SLOT`\n\nDefines the PINE slot number used for communication. This value serves as:\n\n- The TCP port number on Windows (`127.0.0.1:<slot>`)\n- The Unix socket suffix on Linux/macOS (`<target>.sock.<slot>`)\n\n**Type:** integer  \n**Default:** `28011`  \n**Valid Range:** 0–65535 (though PINE protocol reserves 0–255 for official slot semantics)\n\n```mermaid\ngraph TD\n    A[Emulator PINE Server] --> B{Slot Configured?}\n    B -->|Default 28011| C[PCSX2 Qt 1.7.x]\n    B -->|Custom Port| D[RPCS3 / Duckstation]\n    A --> E[PCSX2 Settings]\n    E --> F[Settings > Advanced > Enable PINE Server]\n```\n\n资料来源：[README.md:46-47]()\n\n### `PINE_HOST`\n\nSpecifies the hostname or IP address for TCP connections on Windows systems.\n\n**Type:** string  \n**Default:** `127.0.0.1`  \n**Valid Values:** Any valid IPv4/IPv6 address or hostname\n\nOn Windows, TCP is used exclusively instead of Unix sockets. This variable allows connection to remote emulators if needed.\n\n```typescript\n// Connection resolution logic (src/pine.ts)\nconst descriptor = resolveSocket(opts);\n// Returns { kind: \"tcp\", host, port } or { kind: \"unix\", path }\n```\n\n资料来源：[src/pine.ts:100-110]()\n\n### `PINE_SOCKET_PATH`\n\nProvides a complete override for the socket path, bypassing automatic resolution based on `PINE_TARGET` and `PINE_SLOT`.\n\n**Type:** string  \n**Default:** auto-generated  \n**Format:** Absolute path for Unix sockets, or `host:port` for TCP\n\nThis variable is useful for:\n\n- Custom socket locations\n- Docker containers with volume-mounted sockets\n- Testing with mock PINE servers\n\n资料来源：[package.json:5-10]()\n\n---\n\n## Runtime Behavior Configuration\n\n### `PINE_PIPELINE_BATCH`\n\nControls the number of concurrent in-flight PINE requests when performing bulk reads via `pine_read_range`.\n\n```mermaid\ngraph TD\n    A[pine_read_range call] --> B{How many steps?}\n    B --> C[Split into steps]\n    C --> D{PIPELINE_BATCH}\n    D -->|1 (default)| E[Serial execution<br/>Safe: no queue corruption]\n    D -->|2+| F[Batch execution<br/>⚠️ Risk: PCSX2 queue desync]\n    E --> G[~52ms for 4KB]\n    F --> H[Lower latency<br/>Potential reply misalignment]\n```\n\n**Type:** integer  \n**Default:** `1`  \n**Valid Range:** Positive integers\n\n| Value | Behavior | Latency | Risk Level |\n|-------|----------|---------|------------|\n| `1` | Fully serial execution | ~52ms for 4KB | None |\n| `2` | Batches of 2 concurrent requests | Lower | Low |\n| `>6` | Aggressive pipelining | Lowest | High (queue corruption) |\n\n#### Why Pipelining Can Break PCSX2\n\nPCSX2's PINE server has a **fragile request queue**. When more than approximately 6-9 requests are in-flight simultaneously, the server silently drops requests. This causes the reply pipeline to become desynchronized, and every subsequent request times out—even `pine_ping`.\n\n**Symptoms of queue corruption:**\n\n```\nPINE call timed out (10s) from pine_ping\n```\n\n**Recovery:** Complete PCSX2 restart required. Reconnecting alone does not fix the desync.\n\n资料来源：[src/pine.ts:70-85]()\n\n---\n\n## Connection Flow Architecture\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Client\n    participant Server as mcp-pine Server\n    participant Pine as PINE Client\n    participant Emu as Emulator PINE Server\n\n    MCP->>Server: Stdio connection\n    Server->>Pine: Connect via resolveSocket()\n    Note over Server,Pine: Platform detection<br/>TCP vs Unix socket\n\n    Pine->>Emu: Initial connection\n    Emu-->>Pine: Connected\n\n    loop Per tool call\n        MCP->>Server: CallToolRequest\n        Server->>Pine: Typed method (read8, write32, etc.)\n        Pine->>Emu: PINE binary frame\n        Emu-->>Pine: PINE reply frame\n        Pine-->>Server: Parsed result\n        Server-->>MCP: ToolResponse\n    end\n```\n\n### Socket Resolution Logic\n\n```mermaid\ngraph TD\n    A[resolveSocket options] --> B{Target platform?}\n    B -->|Windows| C[Use TCP]\n    B -->|Linux/macOS| D[Use Unix Socket]\n\n    C --> E[\"net.createConnection<br/>host:port\"]\n    D --> F{PINE_SOCKET_PATH set?}\n    F -->|Yes| G[\"Use custom path\"]\n    F -->|No| H[\"Build from TARGET + SLOT\"]\n    H --> I[XDG_RUNTIME_DIR]\n    H --> J[TMPDIR]\n    H --> K[/tmp fallback]\n\n    I --> L[\"<dir>/<target>.sock.<slot>\"]\n    J --> L\n    K --> L\n```\n\n资料来源：[src/pine.ts:95-120]()\n\n---\n\n## Timeout Configuration\n\nEach PINE call has a **10-second timeout** enforced by the client. This prevents the MCP server from hanging indefinitely if:\n\n- The emulator drops a reply\n- The PINE server becomes unresponsive\n- Network latency exceeds normal bounds\n\n**Implementation:**\n\n```typescript\n// From src/pine.ts\nprivate readonly TIMEOUT_MS = 10_000;\n\nconst result = await Promise.race([\n    this.call(Op.Read64, args),\n    new Promise((_, reject) =>\n        setTimeout(() => reject(new Error(\"PINE call timed out\")), TIMEOUT_MS)\n    )\n]);\n```\n\n资料来源：[src/pine.ts:25-30]()\n\n---\n\n## Environment Variable Precedence\n\nWhen multiple variables could affect the same aspect of connection, the following precedence applies:\n\n| Priority | Variable | Override Behavior |\n|----------|----------|-------------------|\n| 1 (highest) | `PINE_SOCKET_PATH` | Complete path override |\n| 2 | `PINE_HOST` + `PINE_SLOT` | TCP connection details |\n| 3 | `PINE_TARGET` + `PINE_SLOT` | Auto-generated Unix socket |\n\n---\n\n## Configuration Examples\n\n### PCSX2 (Default)\n\n```bash\n# Uses defaults: pcsx2.sock.28011 on Linux, 127.0.0.1:28011 on Windows\nmcp-pine\n```\n\n### RPCS3\n\n```bash\nPINE_TARGET=rpcs3 PINE_SLOT=28012 mcp-pine\n```\n\n### Duckstation\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=28013 mcp-pine\n```\n\n### Custom Socket Path\n\n```bash\nPINE_SOCKET_PATH=/tmp/custom-pine.sock.28011 mcp-pine\n```\n\n### Aggressive Pipelining (Not Recommended)\n\n```bash\nPINE_PIPELINE_BATCH=4 mcp-pine\n# ⚠️ May cause PCSX2 queue corruption\n```\n\n### Remote Connection\n\n```bash\nPINE_HOST=192.168.1.100 PINE_SLOT=28011 mcp-pine\n```\n\n---\n\n## Quick Reference Card\n\n| Scenario | Recommended Variables |\n|----------|----------------------|\n| PCSX2 on Linux | None (defaults work) |\n| PCSX2 on Windows | None (defaults work) |\n| RPCS3 | `PINE_TARGET=rpcs3` |\n| Duckstation | `PINE_TARGET=duckstation` |\n| Custom port | `PINE_SLOT=<port>` |\n| Docker/special socket | `PINE_SOCKET_PATH=<path>` |\n| Performance testing | `PINE_PIPELINE_BATCH=2` |\n| Debugging queue issues | `PINE_PIPELINE_BATCH=1` (default) |\n\n---\n\n## Error States and Diagnostics\n\n| Error Message | Cause | Fix |\n|---------------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running, PINE disabled, port mismatch | Verify emulator PINE settings |\n| `PINE FAIL response (0xFF)` | No game loaded, unmapped address | Load game, check address |\n| Reads return zeros | Unmapped memory region | Try `0x00100000` (EE RAM start) |\n| Values look corrupted | Endianness mismatch | PINE is little-endian |\n| `PINE call timed out (10s)` | Queue desync | Full PCSX2 restart required |\n\n资料来源：[README.md:80-95]()\n\n---\n\n<a id='memory-operations'></a>\n\n## Memory Operations\n\n### 相关页面\n\n相关主题：[Savestate Management](#savestate-management), [System Query Tools](#system-queries)\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</details>\n\n# Memory Operations\n\n## Overview\n\nMemory Operations in mcp-pine provide read and write access to the emulated PlayStation 2's (PS2) Emotion Engine (EE) address space through the PINE (Plugin Interface for Networked Emulation) protocol. These operations enable AI assistants and MCP clients to inspect and modify game state in real-time while an emulator runs.\n\nThe primary use cases include:\n\n- **Game state inspection** — reading RAM to discover health, score, position, or other variables\n- **Cheat development** — writing values to memory addresses to create or test cheats\n- **Debugging** — inspecting memory regions during gameplay to understand game logic\n- **Save state management** — snapshotting and restoring emulator state through specific slots\n\nMemory operations in mcp-pine are exposed as MCP tools that bridge the AI assistant to the underlying PINE protocol implementation in `src/pine.ts`.\n\n资料来源：[src/tools.ts:1-50]()\n\n## Architecture\n\n### Component Hierarchy\n\n```mermaid\ngraph TD\n    subgraph \"MCP Client Layer\"\n        A[\"AI Assistant / Claude\"]\n    end\n    \n    subgraph \"MCP Bridge (mcp-pine)\"\n        B[\"src/tools.ts<br/>Tool Definitions\"]\n        C[\"src/pine.ts<br/>PineClient\"]\n        D[\"PINE Protocol Encoder/Decoder\"]\n    end\n    \n    subgraph \"Transport Layer\"\n        E[\"Unix Socket<br/>Linux/macOS\"]\n        F[\"TCP Socket<br/>Windows\"]\n    end\n    \n    subgraph \"Emulator\"\n        G[\"PCSX2 / RPCS3 / Duckstation<br/>PINE Server\"]\n    end\n    \n    A --> B\n    B --> C\n    C --> D\n    D --> E\n    D --> F\n    E --> G\n    F --> G\n```\n\n### Request-Response Flow\n\n```mermaid\nsequenceDiagram\n    participant AI as AI Assistant\n    participant MCP as MCP Bridge\n    participant PC as PineClient\n    participant PINE as PINE Server\n    \n    AI->>MCP: pine_read32(0x00100000)\n    MCP->>PC: read32() call\n    PC->>PINE: Op.Read32 + addr (12 bytes)\n    PINE-->>PC: Reply frame (12 bytes)\n    PC-->>MCP: number value\n    MCP-->>AI: \"0x00100000: 1234 (0x4D2)\"\n```\n\n### Key Components\n\n| Component | File | Responsibility |\n|-----------|------|-----------------|\n| `PineClient` | `src/pine.ts` | Socket management, request queuing, protocol encoding/decoding |\n| Tool definitions | `src/tools.ts` | MCP tool schemas, parameter validation, response formatting |\n| Opcode enum | `src/pine.ts` | PINE protocol opcodes (Op.Read32, Op.Write8, etc.) |\n\n资料来源：[src/pine.ts:1-80]()\n\n## Read Operations\n\nmcp-pine provides four aligned read operations for accessing EE memory:\n\n| Tool | Width | Opcode | Alignment |\n|------|-------|--------|-----------|\n| `pine_read8` | 8-bit / 1 byte | `Op.Read8` | None required |\n| `pine_read16` | 16-bit / 2 bytes | `Op.Read16` | 2-byte |\n| `pine_read32` | 32-bit / 4 bytes | `Op.Read32` | 4-byte |\n| `pine_read64` | 64-bit / 8 bytes | `Op.Read64` | 8-byte |\n\nAll read operations return values as little-endian unsigned integers. The return format follows a consistent pattern: `ADDR_HEX: VAL_DEC (0xVAL_HEX)`.\n\n### Address Parameter\n\nThe `address` parameter for all read/write operations accepts an absolute byte address in the EE main address space:\n\n```\nAbsolute byte address in the EE main address space (NOT a per-domain offset).\nPass as a number; hex literals like 0x00200000 are fine.\n```\n\n**PS2 Memory Landmarks:**\n\n| Region | Address Range | Description |\n|--------|---------------|-------------|\n| EE Main RAM | `0x00100000` - `0x01FFFFFF` | Where 99% of game state lives |\n| IOP RAM | `0x1C000000`+ | Input/Output Processor memory |\n| Scratchpad | `0x70000000` - `0x70003FFF` | Fast 16KB scratchpad |\n\n资料来源：[src/tools.ts:30-45]()\n\n### Usage Examples\n\n```javascript\n// Read 32-bit value at game state pointer\npine_read32(0x00200000)\n\n// Read 8-bit byte for flag detection\npine_read8(0x00201004)\n\n// Read 64-bit EE pointer\npine_read64(0x00203000)\n```\n\n### Alignment Caveats\n\n> **Important:** PINE on PCSX2 does NOT enforce alignment. Unaligned multi-byte access returns whatever bytes are at the aligned address below, silently corrupting the value.\n\n| Operation | Required Alignment | Misaligned Behavior |\n|-----------|-------------------|---------------------|\n| `read8` | None | Correct |\n| `read16` | 2-byte | Returns wrong value silently |\n| `read32` | 4-byte | Returns wrong value silently |\n| `read64` | 8-byte | Returns wrong value silently |\n\nIf you need an unaligned multi-byte read, use `pine_read_range` and assemble the bytes yourself.\n\n资料来源：[src/tools.ts:30-40]()\n\n## Write Operations\n\nWrite operations modify memory in the emulated EE address space:\n\n| Tool | Width | Opcode | Value Encoding |\n|------|-------|--------|----------------|\n| `pine_write8` | 8-bit | `Op.Write8` | Number `0-255` |\n| `pine_write16` | 16-bit | `Op.Write16` | Number `0-65535` |\n| `pine_write32` | 32-bit | `Op.Write32` | Number `0-4294967295` |\n| `pine_write64` | 64-bit | `Op.Write64` | Decimal string `0-18446744073709551615` |\n\n### Destructive Behavior Notes\n\n- Writes **bypass TLB protection** and DMA mediation\n- Writes to **read-only regions** (BIOS, IOP ROM) are silently dropped\n- **No undo mechanism** — changes are permanent until emulator restart or explicit restoration\n\n### 64-bit Value Encoding\n\n64-bit values use decimal string encoding because JavaScript's number type cannot represent the full `uint64` range (max safe integer is `2^53 - 1`):\n\n```javascript\n// Write maximum 64-bit value\npine_write64(0x00200000, \"18446744073709551615\")\n```\n\nThe schema enforces this with `pattern: \"^[0-9]+$\"` to reject non-numeric input.\n\n资料来源：[src/tools.ts:140-180]()\n\n### Usage Examples\n\n```javascript\n// Infinite health cheat\npine_write32(0x00201000, 9999)\n\n// Set RGBA color (packed 32-bit)\npine_write32(0x00300000, 0xFFFFFFFF)\n\n// Write large 64-bit ID\npine_write64(0x00204000, \"12345678901234567\")\n```\n\n## Bulk Read Operation\n\n### `pine_read_range`\n\nReads up to 4096 consecutive bytes in a single tool call. Since PINE has no native bulk read opcode, this is implemented client-side as a serial sequence of aligned reads.\n\n**Implementation Strategy:**\n\n```mermaid\ngraph TD\n    A[\"read_range(addr, length)\"] --> B[\"Calculate read steps\"]\n    B --> C{\"Remaining bytes?\"}\n    C -->|≥8 & addr%8==0| D[\"read64\"]\n    C -->|≥4 & addr%4==0| E[\"read32\"]\n    C -->|≥2 & addr%2==0| F[\"read16\"]\n    C -->|else| G[\"read8\"]\n    D --> H[\"cursor += 8\"]\n    E --> I[\"cursor += 4\"]\n    F --> J[\"cursor += 2\"]\n    G --> K[\"cursor += 1\"]\n    H --> C\n    I --> C\n    J --> C\n    K --> C\n    C -->|0| L[\"Return Buffer\"]\n```\n\n**Performance Characteristics:**\n\n| Configuration | Measured Time (4KB) |\n|---------------|---------------------|\n| Serial (`PINE_PIPELINE_BATCH=1`) | ~52 ms |\n| With pipelining (`PINE_PIPELINE_BATCH=2+`) | Lower latency, higher risk |\n\n> Measured on PCSX2 v2.6.3 over loopback TCP.\n\n### Pipelining and PCSX2 Fragility\n\nPCSX2's PINE server has a **fragile request queue**: dropping any single request silently desyncs the reply pipeline, causing all subsequent requests to timeout until the emulator restarts.\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant PCSX2 as PCSX2 PINE Server\n    \n    Note over Client,PCSX2: Normal operation (≤6 in-flight)\n    Client->>PCSX2: Request 1\n    Client->>PCSX2: Request 2\n    Client->>PCSX2: Request 3\n    PCSX2-->>Client: Reply 1\n    PCSX2-->>Client: Reply 2\n    PCSX2-->>Client: Reply 3\n    \n    Note over Client,PCSX2: Pipeline saturation (≥7 in-flight)\n    Client->>PCSX2: Request 1\n    Client->>PCSX2: Request 2\n    Client->>PCSX2: Request 3\n    Client->>PCSX2: Request 4\n    Client->>PCSX2: Request 5\n    Client->>PCSX2: Request 6\n    Client->>PCSX2: Request 7\n    PCSX2->>PCSX2: Dropped!\n    Note over Client,PCSX2: All subsequent replies misaligned!\n```\n\n**Recommendation:** Use serial mode by default. Only set `PINE_PIPELINE_BATCH=2` or higher if you can tolerate occasional emulator restarts.\n\n资料来源：[src/pine.ts:60-100]()\n\n## Save State Operations\n\nThe save state operations provide snapshot and restore functionality through PINE slots:\n\n| Tool | Opcode | Description |\n|------|--------|-------------|\n| `pine_save_state` | `Op.SaveState` | Save current emulator state to slot |\n| `pine_load_state` | `Op.LoadState` | Load emulator state from slot |\n\n### Slot Numbering\n\n- **Range:** 0-255\n- **PCSX2 convention:** Slots 0-9 mapped to F1-F10 in GUI\n- **Storage location:** Per-game savestate folder\n\n### Slot File Naming\n\n```\n<serial> (<crc>).<slot>.p2s\n```\n\nExample: `SCUS-97211 (ABC12345).3.p2s`\n\n资料来源：[src/tools.ts:180-220]()\n\n## Error Handling\n\n### Connection Failures\n\n| Error | Cause | Fix |\n|-------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running, PINE disabled, wrong slot | Check `PINE_SLOT` setting |\n| `PINE FAIL response (0xFF)` | Emulator rejected request | Ensure game loaded, check address validity |\n| Timeout (10s) | Reply dropped | Restart emulator if PCSX2 PINE is wedged |\n\n### Data Corruption\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| Reads return zeros | Address in unallocated region | Try `0x00100000` first |\n| Values look corrupted | Wrong endianness interpretation | PINE returns little-endian |\n| Silent wrong values | Unaligned access | Align addresses or use `read_range` |\n\n资料来源：[README.md:80-100]()\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator name prefix for Unix socket path |\n| `PINE_SLOT` | `28011` | PINE slot / port number |\n| `PINE_PIPELINE_BATCH` | `1` | Parallel request count (use with caution) |\n\n### Socket Path Resolution\n\n```mermaid\ngraph TD\n    A[\"Start\"] --> B{\"OS?\"}\n    B -->|Windows| C[\"TCP 127.0.0.1:<PINE_SLOT>\"]\n    B -->|Linux/macOS| D{\"XDG_RUNTIME_DIR set?\"}\n    D -->|Yes| E[\"$XDG_RUNTIME_DIR/<PINE_TARGET>.sock.<PINE_SLOT>\"]\n    D -->|No| F{\"TMPDIR set?\"}\n    F -->|Yes| G[\"$TMPDIR/<PINE_TARGET>.sock.<PINE_SLOT>\"]\n    F -->|No| H[\"/tmp/<PINE_TARGET>.sock.<PINE_SLOT>\"]\n```\n\n资料来源：[src/pine.ts:20-50]()\n\n## Tool Reference Summary\n\n| Tool | Input Schema | Return Format |\n|------|--------------|---------------|\n| `pine_ping` | None | `OK — emulator: <version>` |\n| `pine_get_info` | None | Multi-line status with title, serial, CRC, version |\n| `pine_get_status` | None | `Status: running\\|paused\\|shutdown` |\n| `pine_read8` | `{address: integer}` | `ADDR_HEX: VAL (0xVAL_HEX)` |\n| `pine_read16` | `{address: integer}` | `ADDR_HEX: VAL (0xVAL_HEX)` |\n| `pine_read32` | `{address: integer}` | `ADDR_HEX: VAL (0xVAL_HEX)` |\n| `pine_read64` | `{address: integer}` | `ADDR_HEX: VAL (0xVAL_HEX)` |\n| `pine_read_range` | `{address: integer, length: 1-4096}` | Raw bytes (base64 or hex) |\n| `pine_write8` | `{address: integer, value: number}` | `Wrote VAL → ADDR` |\n| `pine_write16` | `{address: integer, value: number}` | `Wrote VAL → ADDR` |\n| `pine_write32` | `{address: integer, value: number}` | `Wrote VAL → ADDR` |\n| `pine_write64` | `{address: integer, value: string}` | `Wrote VAL → ADDR` |\n| `pine_save_state` | `{slot: 0-255}` | `Saved state to slot <N>` |\n| `pine_load_state` | `{slot: 0-255}` | `Loaded state from slot <N>` |\n\n资料来源：[src/tools.ts:50-250]()\n\n---\n\n<a id='savestate-management'></a>\n\n## Savestate Management\n\n### 相关页面\n\n相关主题：[Memory Operations](#memory-operations), [System Query Tools](#system-queries)\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</details>\n\n# Savestate Management\n\n## Overview\n\nSavestate Management provides MCP clients with the ability to programmatically save and load emulator states for PlayStation 2 games running in PCSX2 (or other PINE-compatible emulators). This enables workflows such as checkpoint-based experimentation, automated testing, and stateful memory analysis where the user can snapshot game state, perform operations, and restore to a known baseline.\n\nThe feature is implemented through two MCP tools (`pine_save_state` and `pine_load_state`) that wrap the PINE protocol's `SaveState` and `LoadState` opcodes. These tools interact directly with the emulator's running instance, writing savestate files to the emulator's native storage location.\n\n## Architecture\n\n### Component Overview\n\n```mermaid\ngraph TD\n    A[\"MCP Client<br/>(Claude Code, Claude Desktop)\"] --> B[\"mcp-pine Bridge\"]\n    B --> C[\"PineClient<br/>(src/pine.ts)\"]\n    C --> D[\"PINE Protocol<br/>(TCP/Unix Socket)\"]\n    D --> E[\"PCSX2 PINE Server\"]\n    E --> F[\"Savestate Files<br/>(~/.config/PCSX2/sstates)\"]\n    \n    G[\"src/tools.ts\"] -->|Tool Definitions| B\n```\n\n### Savestate Workflow\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Client\n    participant Bridge as mcp-pine Bridge\n    participant Pine as PineClient\n    participant Emu as PCSX2 PINE Server\n    participant FS as File System\n\n    Note over MCP, FS: Save State Flow\n    MCP->>Bridge: pine_save_state(slot: N)\n    Bridge->>Pine: saveState(slot)\n    Pine->>Emu: PINE SaveState opcode + slot byte\n    Emu->>FS: Write <serial>.<crc>.<slot>.p2s\n    Emu-->>Pine: PINE OK response\n    Pine-->>Bridge: Promise resolves\n    Bridge-->>MCP: \"State saved to slot N\"\n\n    Note over MCP, FS: Load State Flow\n    MCP->>Bridge: pine_load_state(slot: N)\n    Bridge->>Pine: loadState(slot)\n    Pine->>Emu: PINE LoadState opcode + slot byte\n    Emu->>FS: Read <serial>.<crc>.<slot>.p2s\n    Emu-->>Pine: PINE OK response\n    Pine-->>Bridge: Promise resolves\n    Bridge-->>MCP: \"State loaded from slot N\"\n```\n\n## MCP Tools\n\n### pine_save_state\n\nSaves the current emulator state to a specified slot.\n\n| Property | Value |\n|----------|-------|\n| **Tool Name** | `pine_save_state` |\n| **Source** | [src/tools.ts:1-20](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) |\n\n**Parameters:**\n\n| Parameter | Type | Constraints | Description |\n|-----------|------|-------------|-------------|\n| `slot` | integer | 0-255 | Save state slot number |\n\n**Description (from source):**\n\n```\nPURPOSE: Atomically snapshot the full emulator state (CPU registers, RAM, VRAM, \n         SPU, device states) to the specified slot and persist it to disk. USAGE: \n         Save checkpoints before risky operations (memory edits, patch applications, \n         speedrun route branches). Use pine_load_state to restore. Slot 0 is \n         conventional for \"current run\", slots 1-9 map to F1-F10 in PCSX2's GUI. \n         BEHAVIOR: DESTRUCTIVE — overwrites any existing savestate in the same \n         slot without prompting. Requires a game to be loaded; returns PINE FAIL \n         if invoked from the BIOS. Emulator retains the saved data across sessions \n         (survives emulator restart). RETURNS: \"State saved to slot N\" on success.\n```\n\n### pine_load_state\n\nRestores the emulator state from a specified slot.\n\n| Property | Value |\n|----------|-------|\n| **Tool Name** | `pine_load_state` |\n| **Source** | [src/tools.ts:1-20](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) |\n\n**Parameters:**\n\n| Parameter | Type | Constraints | Description |\n|-----------|------|-------------|-------------|\n| `slot` | integer | 0-255 | Save state slot number |\n\n**Description (from source):**\n\n```\nPURPOSE: Atomically restore the full emulator state (CPU registers, RAM, VRAM, \n         SPU, device states) from a previously saved slot. USAGE: Restore after \n         experimental memory edits, reset to a known checkpoint, or implement \n         trial-and-error workflows (save → modify → load → try again). \n         BEHAVIOR: DESTRUCTIVE — immediately overwrites all emulator state with \n         the slot's contents. Does not verify the slot contains a valid savestate \n         before restoring (PINE FAIL if slot is empty/missing). The restored state \n         reflects the exact game position at the time of save, including any \n         unsaved progress. RETURNS: \"State loaded from slot N\" on success.\n```\n\n## Implementation\n\n### PineClient Methods\n\nThe `PineClient` class in `src/pine.ts` implements the savestate operations:\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**资料来源:** [src/pine.ts:1-10](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n### Tool Registration\n\nThe tools are registered in `registerTools()` which handles the MCP request routing:\n\n```typescript\ncase \"pine_save_state\": {\n  await pine.saveState(p.slot as number);\n  return ok(`State saved to slot ${p.slot}`);\n}\ncase \"pine_load_state\": {\n  await pine.loadState(p.slot as number);\n  return ok(`State loaded from slot ${p.slot}`);\n}\n```\n\n**资料来源:** [src/tools.ts:1-20](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## Slot Management\n\n### Slot Number Conventions\n\n| Slot Range | Conventional Use | GUI Mapping |\n|------------|------------------|-------------|\n| 0 | Current run / temporary checkpoint | Manual |\n| 1-9 | Quick save slots | F1-F10 |\n| 10-99 | Scene-specific saves | Named folders |\n| 100-255 | Long-term snapshots | Archive |\n\nPCSX2 conventionally uses slots 0-9 mapped to function keys F1-F10 in the GUI. The PINE protocol accepts the full 0-255 range, but slots beyond 9 are only accessible programmatically.\n\n### File Location\n\nSavestate files are stored in the emulator's per-game savestate folder:\n\n| Platform | Path |\n|----------|------|\n| Linux | `~/.config/PCSX2/sstates/` |\n| macOS | `~/.config/PCSX2/sstates/` |\n| Windows | `%USERPROFILE%\\Documents\\PCSX2\\sstates\\` |\n\n**Filename format:** `<serial> (<crc>).<slot>.p2s`\n\n## Usage Patterns\n\n### Checkpoint Workflow\n\n```mermaid\ngraph LR\n    A[Game Running] --> B[\"pine_save_state<br/>slot=0\"]\n    B --> C[Perform Memory Edits]\n    C --> D{Results OK?}\n    D -->|Yes| E[Continue Playing]\n    D -->|No| F[\"pine_load_state<br/>slot=0\"]\n    F --> A\n```\n\n### Memory Analysis Workflow\n\n```mermaid\ngraph TD\n    A[Save Baseline] -->|\"slot=0\"| B\n    B[Find Target Address] -->|\"pine_read32\"| C\n    C[Edit Memory] -->|\"pine_write32\"| D\n    D[Verify Change] -->|\"pine_read32\"| E\n    E{Correct?} -->|Yes| F[Continue]\n    E{No} -->|\"pine_load_state slot=0\"| B\n```\n\n### Example Tool Calls\n\n**Save state:**\n```json\n{\n  \"name\": \"pine_save_state\",\n  \"arguments\": { \"slot\": 0 }\n}\n```\n\n**Load state:**\n```json\n{\n  \"name\": \"pine_load_state\",\n  \"arguments\": { \"slot\": 0 }\n}\n```\n\n## Error Handling\n\n### Common Failure Modes\n\n| Error | Cause | Fix |\n|-------|-------|-----|\n| PINE FAIL response | No game loaded, or slot is invalid | Load a game before saving |\n| Slot contains garbage | Corrupted savestate file | Delete file and re-save |\n| Load restores wrong game | Serial/CRC mismatch | Use correct game or different slot |\n\n### Connection Requirements\n\nThe emulator must be running with PINE enabled:\n\n1. Launch PCSX2 (1.7.x Qt or newer)\n2. Navigate to **Settings → Advanced → Enable PINE Server**\n3. Default slot is **28011** (configurable via `PINE_SLOT`)\n\n**资料来源:** [README.md:1-20](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Configuration\n\nSavestate operations are affected by the following environment variables:\n\n| Variable | Default | Effect |\n|----------|---------|--------|\n| `PINE_SLOT` | `28011` | Sets the PINE slot used for communication |\n| `PINE_TARGET` | `pcsx2` | Emulator name prefix for Unix socket path |\n| `PINE_TIMEOUT` | `10000` (ms) | Per-call timeout; affects savestate operations |\n\n## Related Tools\n\n| Tool | Purpose |\n|------|---------|\n| `pine_get_info` | Get game metadata before saving (title, serial, CRC) |\n| `pine_get_status` | Check if emulator is running/paused before operations |\n| `pine_read_*` | Read memory from restored state |\n| `pine_write_*` | Modify memory after loading a state |\n\n## See Also\n\n- [mcp-mgba](https://github.com/dmang-dev/mcp-mgba) — sister MCP server for mGBA with button input support\n- [PINE protocol spec](https://github.com/GovanifY/pine) — underlying IPC standard\n\n---\n\n<a id='system-queries'></a>\n\n## System Query Tools\n\n### 相关页面\n\n相关主题：[Memory Operations](#memory-operations), [Savestate Management](#savestate-management)\n\n<details>\n<summary>Relevant Source Files</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</details>\n\n# System Query Tools\n\nThe System Query Tools in mcp-pine provide MCP (Model Context Protocol) clients with a comprehensive interface to query and interact with PINE-enabled PlayStation 2 emulators. These tools expose low-level emulator introspection capabilities—including game metadata retrieval, memory reading/writing, and save state management—through the standardized MCP tool interface.\n\n## Overview\n\nmcp-pine bridges the gap between AI assistants (primarily Claude) and PlayStation 2 emulators by implementing the PINE (Platform for Interactive Nintendo/Network Environments) protocol. The System Query Tools form the public API layer that MCP clients interact with.\n\n### Architecture\n\n```mermaid\ngraph TD\n    subgraph \"MCP Client Layer\"\n        A[Claude / MCP Host]\n    end\n    \n    subgraph \"mcp-pine Bridge\"\n        B[tools.ts<br/>Tool Definitions]\n        C[pine.ts<br/>PineClient]\n    end\n    \n    subgraph \"Emulator Layer\"\n        D[PCSX2 / RPCS3 / Duckstation]\n    end\n    \n    A -->|CallToolRequest| B\n    B -->|PINE Protocol| C\n    C -->|TCP / Unix Socket| D\n    \n    style B fill:#f9f,color:#000\n    style C fill:#9ff,color:#000\n```\n\n### Tool Categories\n\n| Category | Tools | Purpose |\n|----------|-------|---------|\n| **Connectivity** | `pine_ping` | Verify emulator connection and retrieve version |\n| **Introspection** | `pine_get_info`, `pine_get_status` | Query game metadata and emulator state |\n| **Memory Read** | `pine_read8`, `pine_read16`, `pine_read32`, `pine_read64`, `pine_read_range` | Read from emulator's EE address space |\n| **Memory Write** | `pine_write8`, `pine_write16`, `pine_write32`, `pine_write64` | Write to emulator's memory |\n| **State Management** | `pine_save_state`, `pine_load_state` | Manipulate emulator save states |\n\n资料来源：[src/tools.ts:47-140]()\n\n## Connectivity & Introspection\n\n### pine_ping\n\nA lightweight health check that retrieves the emulator's PINE protocol version.\n\n```typescript\n{\n  name: \"pine_ping\",\n  description:\n    \"PURPOSE: Verify connectivity to the emulator's PINE server and retrieve its version string. \" +\n    \"USAGE: Call first when starting a session or debugging connection issues. Unlike pine_get_info, \" +\n    \"this makes only one PINE round-trip (Status opcode) — fastest way to confirm the link is alive. \" +\n    \"BEHAVIOR: No side effects. Issues PINE Version opcode (0x08). Times out after ~10s if the \" +\n    \"emulator is unresponsive or the PINE queue is desynced. \" +\n    \"RETURNS: 'OK — emulator: VERSION_STRING'.\",\n  inputSchema: { type: \"object\", properties: {} },\n}\n```\n\n资料来源：[src/tools.ts:48-54]()\n\n**Returns:** `OK — emulator: <version_string>`\n\n### pine_get_info\n\nRetrieves comprehensive game and emulator metadata in a single batched call.\n\n```typescript\n{\n  name: \"pine_get_info\",\n  description:\n    \"PURPOSE: Fetch all available game metadata (title, serial, disc CRC, game version, run state) in one tool call. \" +\n    \"USAGE: Use at session start to identify the loaded game. For repeated status-only checks, pine_get_status is cheaper (1 opcode vs 5). \" +\n    \"BEHAVIOR: No side effects — pure reads. Batches PINE opcodes: Title (0x01), ID (0x02), UUID (0x03), GameVersion (0x05), Status (0x0F). \" +\n    \"Each field falls back to '(unavailable)' if the emulator returns PINE FAIL. \" +\n    \"RETURNS: Multi-line string with Title, Serial, Disc CRC, Game version, Status.\",\n  inputSchema: { type: \"object\", properties: {} },\n}\n```\n\n资料来源：[src/tools.ts:56-62]()\n\n**Implementation:**\n\n```typescript\ncase \"pine_get_info\": {\n  const [title, id, uuid, gameVer, status] = await Promise.all([\n    pine.getTitle().catch(() => \"(unavailable)\"),\n    pine.getId().catch(() => \"(unavailable)\"),\n    pine.getUuid().catch(() => \"(unavailable)\"),\n    pine.getGameVersion().catch(() => \"(unavailable)\"),\n    pine.getStatus(),\n  ]);\n  return ok(\n    `Title:        ${title}\\n` +\n    `Serial:       ${id}\\n` +\n    `Disc CRC:     ${uuid}\\n` +\n    `Game version: ${gameVer}\\n` +\n    `Status:       ${status}`,\n  );\n}\n```\n\n资料来源：[src/tools.ts:16-27]()\n\n**Returns:**\n```\nTitle:        <game title>\nSerial:       <game serial>\nDisc CRC:     <disc CRC UUID>\nGame version: <version string>\nStatus:       <running|paused|shutdown|unknown>\n```\n\n### pine_get_status\n\nQueries only the emulator's run state, optimized for repeated checks.\n\n```typescript\n{\n  name: \"pine_get_status\",\n  description:\n    \"PURPOSE: Get the emulator run state — 'running', 'paused', 'shutdown', or 'unknown'. \" +\n    \"USAGE: Cheap (1 PINE round-trip) check before timing-sensitive sequences — writes work while paused but only take visible effect after unpause. \" +\n    \"For game metadata (title, serial, CRC) use pine_get_info. PINE has no pause/resume opcode; this tool only reports state. \" +\n    \"BEHAVIOR: No side effects. Issues PINE Status opcode (0x0F), decodes the 32-bit response (0=running, 1=paused, 2=shutdown). \" +\n    \"RETURNS: 'Status: STATE' where STATE ∈ {running, paused, shutdown, unknown}.\",\n  inputSchema: { type: \"object\", properties: {} },\n}\n```\n\n资料来源：[src/tools.ts:95-101]()\n\n**Status Mapping:**\n\n| PINE Response | Emulator Status |\n|---------------|-----------------|\n| `0` | `running` |\n| `1` | `paused` |\n| `2` | `shutdown` |\n| Other | `unknown` |\n\n资料来源：[src/pine.ts:20-22]()\n\n## Memory Read Operations\n\n### Single-Value Reads\n\nThe `pine_read8`, `pine_read16`, `pine_read32`, and `pine_read64` tools read fixed-width values from the emulator's EE (Emotion Engine) address space.\n\n```typescript\ncase \"pine_read8\":  return ok(`${addrHex(addr())}: ${fmtHex(await pine.read8(addr()))}`);\ncase \"pine_read16\": return ok(`${addrHex(addr())}: ${fmtHex(await pine.read16(addr()))}`);\ncase \"pine_read32\": return ok(`${addrHex(addr())}: ${fmtHex(await pine.read32(addr()))}`);\ncase \"pine_read64\": return ok(`${addrHex(addr())}: ${fmtHex(await pine.read64(addr()))}`);\n```\n\n资料来源：[src/tools.ts:29-32]()\n\n#### Address Parameter\n\n```typescript\nconst ADDRESS_PARAM_DESC = (widthBytes: number) => {\n  const alignNote = widthBytes === 1\n    ? \"No alignment requirement for byte access.\"\n    : `MUST be ${widthBytes}-byte aligned (address % ${widthBytes} === 0). PINE on PCSX2 does NOT enforce ` +\n      `alignment — unaligned ${widthBytes * 8}-bit access typically returns whatever bytes are at the ` +\n      `aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, ` +\n      `use pine_read_range and assemble the bytes yourself.`;\n  return (\n    `Absolute byte address in the EE main address space (NOT a per-domain offset).\n    ...\n    Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives).`\n  );\n};\n```\n\n资料来源：[src/tools.ts:1-18]()\n\n#### Alignment Requirements\n\n| Tool | Width | Alignment | Corruption Risk |\n|------|-------|-----------|-----------------|\n| `pine_read8` | 1 byte | None | None |\n| `pine_read16` | 2 bytes | 2-byte | Silently returns wrong value |\n| `pine_read32` | 4 bytes | 4-byte | Silently returns wrong value |\n| `pine_read64` | 8 bytes | 8-byte | Silently returns wrong value |\n\n资料来源：[src/tools.ts:3-9]()\n\n#### Tool Descriptions\n\n**pine_read8**\n```typescript\ndescription:\n  \"PURPOSE: Read an unsigned 8-bit byte from the emulator's EE address space at the given absolute address. \" +\n  \"USAGE: Use for single-byte fields — status flags, counters, 8-bit enums, character bytes...\"\n```\n\n**pine_read16**\n```typescript\ndescription:\n  \"PURPOSE: Read an unsigned 16-bit little-endian value from the emulator's EE address space...\"\n```\n\n**pine_read32**\n```typescript\ndescription:\n  \"PURPOSE: Read an unsigned 32-bit little-endian value from the emulator's EE address space...\" +\n  \"little-endian (LSB at `address`, MSB at `address+3`). Address MUST be 4-byte aligned...\"\n```\n\n**pine_read64**\n```typescript\ndescription:\n  \"PURPOSE: Read an unsigned 64-bit little-endian value from the emulator's EE address space...\" +\n  \"The PS2 EE is a 128-bit MIPS (Emotion Engine), and a lot of game state genuinely lives in 64-bit slots...\"\n```\n\n资料来源：[src/tools.ts:103-134]()\n\n**Returns Format:** `ADDR_HEX: VAL_DEC (0xVAL_HEX)`\n\n**64-bit Value Encoding:** Due to JavaScript's number precision limit (2^53), 64-bit values are returned as decimal strings to preserve full precision.\n\n### pine_read_range (Bulk Read)\n\nReads a contiguous byte span up to 4096 bytes in a single tool call.\n\n```typescript\n{\n  name: \"pine_read_range\",\n  description:\n    \"PURPOSE: Read a contiguous byte span (1-4096 bytes) from the emulator's EE address space in one tool call. \" +\n    \"USAGE: Use for structs, strings, buffers, or any multi-byte region. Prefer over multiple single reads to minimize round-trips (1 call vs N). \" +\n    \"BEHAVIOR: No side effects — pure read. Internally dispatches read64/read32/read16/read8 calls, choosing the largest aligned width at each step...\",\n}\n```\n\n资料来源：[src/tools.ts:136-140]()\n\n#### Implementation\n\n```typescript\nasync readRange(address: number, length: number): Promise<Buffer> {\n  const out = Buffer.alloc(length);\n  let cursor = address;\n  let outOffset = 0;\n  let remaining = length;\n  \n  while (remaining > 0) {\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    steps.push({ op: n, addr: cursor, outOffset });\n    cursor    += n;\n    outOffset += n;\n    remaining -= n;\n  }\n  // ...\n}\n```\n\n资料来源：[src/pine.ts:24-45]()\n\n#### Pipelining Behavior\n\n```mermaid\ngraph LR\n    A[read_range call] --> B{env: PINE_PIPELINE_BATCH}\n    B -->|1| C[Fully Serial]\n    B -->|2+| D[Batched Pipeline]\n    C --> E[Safe<br/>~52ms for 4KB]\n    D --> F[Fast but risky<br/>May desync PCSX2]\n```\n\n资料来源：[src/pine.ts:47-60]()\n\n**Performance:** ~52 ms for full 4096-byte read on PCSX2 v2.6.3 over loopback TCP.\n\n**Pipeline Warning:** PCSX2's PINE server has a fragile request queue. Dropping ANY request (occurs with ~7+ in-flight requests) desyncs the reply pipeline, causing all subsequent requests to timeout. Default is fully serial (`PINE_PIPELINE_BATCH=1`).\n\n## Memory Write Operations\n\n### pine_write8 through pine_write64\n\nWrite fixed-width little-endian values to the emulator's EE address space.\n\n```typescript\ncase \"pine_write8\": {\n  await pine.write8(addr(), p.value as number);\n  return ok(`Wrote ${fmtHex(p.value as number)} → ${addrHex(addr())}`);\n}\ncase \"pine_write16\": {\n  await pine.write16(addr(), p.value as number);\n  return ok(`Wrote ${fmtHex(p.value as number)} → ${addrHex(addr())}`);\n}\ncase \"pine_write32\": {\n  await pine.write32(addr(), p.value as number);\n  return ok(`Wrote ${fmtHex(p.value as number)} → ${addrHex(addr())}`);\n}\n```\n\n资料来源：[src/tools.ts:34-41]()\n\n#### Write Tool Parameters\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `address` | integer | Absolute byte address in EE address space |\n| `value` | integer | Value to write (decimal or hex) |\n\n#### Alignment Requirements\n\nSame as read operations—multi-byte writes must be aligned, or data corruption occurs silently.\n\n#### Behavior Notes\n\n- **DESTRUCTIVE:** Overwrites existing memory contents\n- Side effects persist after the call completes\n- Writes work while emulator is paused but changes only take effect after unpause\n- Returns PINE FAIL on unmapped addresses\n\n资料来源：[src/tools.ts:75-82]()\n\n## Save State Management\n\n### pine_save_state\n\nSaves the current emulator state to a numbered slot.\n\n```typescript\n{\n  name: \"pine_save_state\",\n  description:\n    \"PURPOSE: Capture a full emulator snapshot and write it to a numbered save-state slot. \" +\n    \"USAGE: Use before experimental memory writes or to bookmark a checkpoint for later restoration. \" +\n    \"Save states are emulator-process snapshots — they persist across emulator restarts. \" +\n    \"BEHAVIOR: DESTRUCTIVE: Overwrites any existing state in the target slot. Issues PINE SaveState opcode (0x10). \" +\n    \"Slot files are stored in PCSX2's per-game savestate folder...\",\n  inputSchema: {\n    type: \"object\",\n    required: [\"slot\"],\n    properties: {\n      slot: { type: \"integer\", minimum: 0, maximum: 255, description: SLOT_PARAM_DESC },\n    },\n    additionalProperties: false,\n  },\n}\n```\n\n资料来源：[src/tools.ts:143-152]()\n\n#### Slot Parameter\n\n```typescript\nconst SLOT_PARAM_DESC =\n  \"Save state slot number (0-255). PCSX2 conventionally uses slots 0-9 (mapped to F1-F10 in the GUI), \" +\n  \"but the PINE protocol accepts the full 0-255 range. Slot files live in PCSX2's per-game savestate \" +\n  \"folder (typically %USERPROFILE%/Documents/PCSX2/sstates on Windows, ~/.config/PCSX2/sstates on Linux) \" +\n  \"with filenames like '<serial> (<crc>).<slot>.p2s'. Slot numbers are independent of any path.\";\n```\n\n资料来源：[src/tools.ts:21-25]()\n\n### pine_load_state\n\nRestores the emulator state from a numbered slot.\n\n```typescript\n{\n  name: \"pine_load_state\",\n  description:\n    \"PURPOSE: Load a previously saved emulator snapshot from a save-state slot. \" +\n    \"USAGE: Use to restore a checkpoint (e.g., after experimental memory writes that didn't work as expected). \" +\n    \"BEHAVIOR: DESTRUCTIVE: Replaces the current running state with the saved snapshot. \" +\n    \"Issues PINE LoadState opcode (0x11). Returns PINE FAIL if the slot is empty or corrupted.\",\n  inputSchema: {\n    type: \"object\",\n    required: [\"slot\"],\n    properties: {\n      slot: { type: \"integer\", minimum: 0, maximum: 255, description: SLOT_PARAM_DESC },\n    },\n    additionalProperties: false,\n  },\n}\n```\n\n资料来源：[src/tools.ts:154-163]()\n\n#### Implementation\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}\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资料来源：[src/pine.ts:15-20]()\n\n## Tool Registration\n\nTools are registered with the MCP server through `registerTools()`:\n\n```typescript\nexport function registerTools(server: Server, pine: PineClient): void {\n  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));\n\n  server.setRequestHandler(CallToolRequestSchema, async (req) => {\n    const { name, arguments: args = {} } = req.params;\n    const p = args as Record<string, unknown>;\n    const addr = () => p.address as number;\n\n    switch (name) {\n      case \"pine_ping\": {\n        const v = await pine.getVersion();\n        return ok(`OK — emulator: ${v}`);\n      }\n      // ... other cases\n    }\n  });\n}\n```\n\n资料来源：[src/tools.ts:158-173]()\n\n### Tool Definition Schema\n\nEach tool follows a consistent structure:\n\n| Field | Purpose |\n|-------|---------|\n| `name` | Unique identifier for the tool |\n| `description` | PURPOSE / USAGE / BEHAVIOR / RETURNS template |\n| `inputSchema` | JSON Schema for parameters |\n\n## Error Handling\n\nAll tools implement consistent error handling:\n\n| Error Condition | Response |\n|-----------------|----------|\n| Connection failure | Tool call rejects with error |\n| PINE FAIL response | Error message returned |\n| Timeout (10s default) | Tool call rejects |\n| Invalid address | PINE FAIL response |\n\n```typescript\nconst ok = (text: string) => {\n  return { content: [{ type: \"text\" as const, text }] };\n};\n```\n\n资料来源：[src/tools.ts:144-147]()\n\n## Configuration\n\n| Environment Variable | Default | Purpose |\n|---------------------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator name for socket path |\n| `PINE_SLOT` | `28011` | PINE slot / port number |\n| `PINE_PIPELINE_BATCH` | `1` | Read range batch size |\n\n资料来源：[README.md](./README.md)\n\n---\n\n<a id='development-guide'></a>\n\n## Development Guide\n\n### 相关页面\n\n相关主题：[Troubleshooting Guide](#troubleshooting), [Project Overview](#overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\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- [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</details>\n\n# Development Guide\n\n## Overview\n\nThis guide covers the development workflow, architecture, and contribution guidelines for `mcp-pine`, an MCP (Model Context Protocol) server that bridges AI assistants like Claude to PlayStation 2/3 emulators via the PINE protocol.\n\nThe project enables read/write access to emulator memory, save state management, and game information retrieval through standardized MCP tool calls.\n\n## Project Structure\n\n```\nmcp-pine/\n├── src/\n│   ├── index.ts       # Entry point, MCP server initialization\n│   ├── pine.ts        # PineClient - low-level PINE protocol implementation\n│   └── tools.ts       # MCP tool definitions and handlers\n├── .scratch/\n│   └── smoke.cjs      # Quick smoke test script\n├── package.json\n├── tsconfig.json\n└── Dockerfile\n```\n\n### Key Modules\n\n| Module | Responsibility |\n|--------|----------------|\n| `src/index.ts` | MCP server bootstrap, connection lifecycle, signal handling |\n| `src/pine.ts` | Socket communication, PINE opcodes, read/write operations |\n| `src/tools.ts` | Tool definitions, input schemas, result formatting |\n\n## Architecture\n\n### System Components\n\n```mermaid\ngraph TD\n    A[\"MCP Client<br/>(Claude, etc.)\"] --> B[\"mcp-pine<br/>MCP Server\"]\n    B --> C[\"PineClient<br/>(TCP/Unix Socket)\"]\n    C --> D[\"Emulator PINE Server<br/>(PCSX2/RPCS3/Duckstation)\"]\n    \n    B --> E[\"Tool Definitions<br/>(src/tools.ts)\"]\n    C --> F[\"PINE Protocol<br/>(src/pine.ts)\"]\n```\n\n### PINE Protocol Flow\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Client\n    participant Bridge as mcp-pine\n    participant PINE as PINE Server\n    participant Emu as Emulator\n    \n    MCP->>Bridge: call_tool(pine_read32)\n    Bridge->>PINE: TCP/Unix Socket\n    PINE->>Emu: Memory Read Request\n    Emu-->>PINE: Memory Value\n    PINE-->>Bridge: PINE Response Frame\n    Bridge-->>MCP: {content: text}\n```\n\n## Development Setup\n\n### Prerequisites\n\n| Requirement | Version | Notes |\n|-------------|---------|-------|\n| Node.js | ≥ 22.0.0 | LTS recommended |\n| npm | Bundled with Node | For package management |\n| PCSX2 | ≥ 1.7.x | PINE-enabled build |\n| TypeScript | ^5.5.0 | Development dependency |\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\n\n# Install dependencies (runs build via prepare hook)\nnpm install\n```\n\nThe `prepare` script in `package.json` automatically runs the build after installation:\n\n```json\n\"scripts\": {\n  \"prepare\": \"tsc\"\n}\n```\n资料来源：[package.json:8-10]()\n\n### Development Workflow\n\n```bash\n# Watch mode - recompile on file changes\nnpm run dev\n\n# Manual build (if not using dev)\nnpm run build   # or npx tsc\n\n# Quick smoke test against running emulator\nnode .scratch/smoke.cjs\n```\n资料来源：[README.md:1]()\n\n## Source Code Analysis\n\n### Entry Point (src/index.ts)\n\nThe entry point initializes the MCP server with the SDK, creates a `PineClient` instance based on environment variables, and registers all tools.\n\n**Key initialization flow:**\n\n1. Parse environment variables for connection options\n2. Create `PineClient` with resolved socket/TCP descriptor\n3. Connect to emulator's PINE server\n4. Register tools with the MCP server\n5. Start server on stdio\n\n### PineClient (src/pine.ts)\n\nThe `PineClient` class handles low-level protocol communication.\n\n**Connection Modes:**\n\n| Platform | Method | Path/Address |\n|----------|--------|--------------|\n| Linux/macOS | Unix Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>` |\n| Linux fallback | Unix Socket | `/tmp/<target>.sock.<slot>` |\n| Windows | TCP | `127.0.0.1:<slot>` |\n\n**Supported Operations:**\n\n| Opcode | Operation | Description |\n|--------|-----------|-------------|\n| 0x01 | Version | Get emulator PINE version |\n| 0x02 | Title | Get loaded game title |\n| 0x03 | ID | Get game serial ID |\n| 0x04 | UUID | Get disc CRC |\n| 0x05 | GameVersion | Get game version string |\n| 0x10 | Status | Get emulator status |\n| 0x20 | Read8 | Read 8-bit value |\n| 0x21 | Read16 | Read 16-bit value |\n| 0x22 | Read32 | Read 32-bit value |\n| 0x23 | Read64 | Read 64-bit value |\n| 0x30 | Write8 | Write 8-bit value |\n| 0x31 | Write16 | Write 16-bit value |\n| 0x32 | Write32 | Write 32-bit value |\n| 0x33 | Write64 | Write 64-bit value |\n| 0x40 | SaveState | Save to slot |\n| 0x41 | LoadState | Load from slot |\n\n### Tool Definitions (src/tools.ts)\n\nEach MCP tool follows the TDQS (Tool Definition Quality Score) rubric with explicit:\n\n- **PURPOSE**: Single action sentence\n- **USAGE**: When to use vs. sibling tools\n- **BEHAVIOR**: Side effects, error conditions\n- **RETURNS**: Exact output shape\n\n**Tool Categories:**\n\n| Category | Tools |\n|----------|-------|\n| Connectivity | `pine_ping`, `pine_get_info` |\n| Read | `pine_read8`, `pine_read16`, `pine_read32`, `pine_read64`, `pine_read_range` |\n| Write | `pine_write8`, `pine_write16`, `pine_write32`, `pine_write64` |\n| State | `pine_save_state`, `pine_load_state` |\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `PINE_TARGET` | `pcsx2` | Emulator name prefix for Unix socket path |\n| `PINE_SLOT` | `28011` | PINE slot number (also TCP port on Windows) |\n| `PINE_PIPELINE_BATCH` | `1` | Number of pipelined requests (see Warning below) |\n| `XDG_RUNTIME_DIR` | - | Unix socket directory (Linux/macOS) |\n| `TMPDIR` | - | Unix socket fallback directory |\n\n资料来源：[README.md:1]()\n\n### Alignment Requirements\n\n**Critical**: PINE on PCSX2 does NOT enforce alignment. Multi-byte access at unaligned addresses silently returns corrupted data from the aligned-below address.\n\n| Access Width | Alignment Required |\n|--------------|-------------------|\n| 8-bit (write8/read8) | None |\n| 16-bit (write16/read16) | 2-byte |\n| 32-bit (write32/read32) | 4-byte |\n| 64-bit (write64/read64) | 8-byte |\n\n## Testing\n\n### Smoke Test\n\nRun the provided smoke test against a running emulator:\n\n```bash\n# Start PCSX2 with PINE enabled, load a game\nnode .scratch/smoke.cjs\n```\n\n### Manual Verification\n\n```bash\n# Test connection\nclaude mcp add pine --scope user mcp-pine\nclaude mcp list\n# pine: mcp-pine - ✓ Connected\n\n# Run a ping\nclaude -p \"call pine_ping\"\n```\n\n## Building\n\n### TypeScript Compilation\n\n```bash\nnpm run build\n# or\nnpx tsc\n```\n\nOutput is placed in `dist/` directory with the same structure as `src/`.\n\n### Docker\n\nA `Dockerfile` is provided for containerized deployment:\n\n```bash\ndocker build -t mcp-pine .\ndocker run mcp-pine\n```\n\n## Known Limitations\n\n### PCSX2 PINE Server Fragility\n\nPCSX2's PINE server has a **fragile request queue** that drops requests silently when too many are pipelined. This desyncs the reply pipeline, causing all subsequent requests to time out until emulator restart.\n\n| Setting | Safety | Latency |\n|---------|--------|---------|\n| `PINE_PIPELINE_BATCH=1` | Safe (default) | ~52ms for 4KB read |\n| `PINE_PIPELINE_BATCH=2+` | Risky | Lower latency |\n\n资料来源：[src/pine.ts:150-160]()\n\n### Error Modes\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running, PINE disabled, wrong slot | Check `PINE_SLOT` |\n| `PINE FAIL response` | No game loaded, unmapped address | Load game, check address |\n| Reads return zeros | Unallocated memory region | Try `0x00100000` (EE RAM) |\n| Tool calls work but values corrupted | Endianness mismatch | PINE returns little-endian |\n| `PINE call timed out (10s)` after heavy use | PCSX2 PINE queue desync | Full emulator restart |\n\n## Emulator Support\n\n### PCSX2 (Primary)\n\n1. Launch PCSX2 1.7.x Qt or newer\n2. **Settings → Advanced → Enable PINE Server**\n3. Default slot is **28011**\n4. Load any game\n\n资料来源：[README.md:1]()\n\n### RPCS3 (Experimental)\n\n```bash\nPINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine\n```\n\nWire-level compatibility with PINE protocol not thoroughly tested.\n\n### Duckstation\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=<port> mcp-pine\n```\n\nRequires PINE-enabled Duckstation build.\n\n## Contribution Guidelines\n\n1. **Tool descriptions**: Follow TDQS rubric in `src/tools.ts`\n2. **Error handling**: All async operations must handle rejection\n3. **Alignment**: Document alignment requirements in parameter descriptions\n4. **Testing**: Verify changes against live PCSX2 before submitting\n5. **Documentation**: Update CHANGELOG.md with changes\n\n## Version History\n\n| Version | Date | Key Changes |\n|---------|------|-------------|\n| 0.2.1 | 2026-05-15 | Tool description quality pass |\n| 0.2.0 | 2026-05-10 | Bulk read, 10s timeout, robustness |\n| 0.1.0 | Earlier | Initial release |\n\n资料来源：[CHANGELOG.md:1-30]()\n\n---\n\n<a id='troubleshooting'></a>\n\n## Troubleshooting Guide\n\n### 相关页面\n\n相关主题：[Emulator Setup](#emulator-setup), [Configuration Reference](#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- [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- [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# Troubleshooting Guide\n\nThis guide covers common issues encountered when using **mcp-pine**, an MCP server that bridges the Model Context Protocol to the PINE IPC system used by PlayStation 2/3 emulators like PCSX2, RPCS3, and Duckstation.\n\n## Connection Troubleshooting\n\n### Cannot Reach PINE Server\n\n**Symptom:** The MCP client reports it cannot connect to the PINE server.\n\n**Root Causes:**\n\n| Cause | Description | Fix |\n|-------|-------------|-----|\n| Emulator not running | PCSX2/RPCS3/Duckstation is not launched | Start the emulator with a game loaded |\n| PINE not enabled | The PINE server toggle is off in emulator settings | Enable it in emulator settings |\n| Slot/Port mismatch | `PINE_SLOT` doesn't match the emulator's configured port | Verify `PINE_SLOT` matches emulator configuration |\n| Game not loaded | Some PINE operations require an active game session | Load any game before using tools |\n\n**Verification Steps:**\n\n```bash\n# Check if mcp-pine is recognized by Claude Code\nclaude mcp list\n# Expected output: pine: mcp-pine - ✓ Connected\n\n# Test connection manually\nPINE_TARGET=pcsx2 PINE_SLOT=28011 node .scratch/smoke.cjs\n```\n\n**资料来源：** [README.md:70-73](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Transport Layer Differences\n\n| Platform | Transport | Path/Address |\n|----------|-----------|--------------|\n| Windows | TCP | `127.0.0.1:<PINE_SLOT>` |\n| Linux/macOS | Unix Socket | `$XDG_RUNTIME_DIR/<PINE_TARGET>.sock.<PINE_SLOT>` with `$TMPDIR`/`/tmp` fallbacks |\n\nThe connection transport is automatically selected based on the operating system. Windows uses TCP loopback while Unix-like systems use Unix domain sockets.\n\n**资料来源：** [src/pine.ts:80-88](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## PINE Response Errors\n\n### PINE FAIL Response (0xFF)\n\n**Symptom:** Tool returns \"PINE FAIL response\" error.\n\n**Common Causes:**\n\n1. **No game loaded** — Most PINE operations require an active game session\n2. **Unmapped address** — The memory address doesn't map to any allocated region\n3. **Invalid opcode** — The emulator doesn't support the requested operation\n\n**Diagnostic Approach:**\n\n```typescript\n// Try reading from a known-good address first (EE main RAM)\nconst test = await pine.read32(0x00100000);\n```\n\nThe address `0x00100000` is almost always inside loaded EE RAM and serves as a good sanity check.\n\n**资料来源：** [README.md:74-76](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Reads Return Zeros\n\n**Symptom:** Memory reads return all zeros instead of expected values.\n\n**Cause:** The address falls in an unallocated memory region.\n\n**Solution:** Start with `0x00100000` (EE main RAM base). The valid EE main RAM range is `0x00100000` to `0x01FFFFFF`.\n\n```typescript\n// Verify address is in valid range\n// EE main RAM: 0x00100000 - 0x01FFFFFF\n// IOP RAM: 0x1C000000+\n// Scratchpad: 0x1F800000 - 0x1F8003FF\n```\n\n**资料来源：** [src/tools.ts:55-60](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### Corrupted Values / Wrong Data\n\n**Symptom:** Read values appear garbled or incorrect.\n\n**Root Cause:** Endianness mismatch.\n\nPINE returns data in **little-endian** format. When interpreting multi-byte values or strings, ensure your code handles little-endian encoding.\n\n```typescript\n// For strings, use read_range (byte-level read)\nconst bytes = await pine.readRange(0x00100000, 64);\nconst str = bytes.toString('utf8').replace(/\\0+$/, '');\n\n// For multi-byte integers, PINE handles conversion automatically\nconst value = await pine.read32(0x00100000); // Already little-endian decoded\n```\n\n**资料来源：** [README.md:77-80](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## PCSX2-Specific Issues\n\n### PINE Server Wedging\n\n**Symptom:** `pine_ping` times out after heavy use, even though the emulator appears to be running.\n\n**Root Cause:** PCSX2's PINE server has a **fragile request queue** that silently drops requests when too many are pipelined. As few as 7 in-flight requests can trigger this behavior. When any request is dropped, the reply pipeline becomes desynchronized — every subsequent reply is delivered to the wrong waiting client.\n\n```mermaid\ngraph TD\n    A[Normal Operation] -->|~7 in-flight requests| B[Request Dropped]\n    B --> C[Reply Pipeline Desync]\n    C --> D[All Replies Misaligned]\n    D --> E[Every Call Times Out]\n    E --> F[Emulator Must Be Fully Restarted]\n```\n\n**Recovery Steps:**\n\n1. Fully quit PCSX2 (not just close the game)\n2. Restart PCSX2\n3. Load the game\n4. Reconnect the MCP client\n\n> **Note:** Simply reconnecting the client does NOT fix the desync — the corruption is on the emulator side.\n\n**资料来源：** [README.md:83-91](https://github.com/dmang-dev/mcp-pine/blob/main/README.md), [CHANGELOG.md:45-52](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n### Bulk Read Performance\n\n**Symptom:** `pine_read_range` feels slow compared to mGBA's `read_range`.\n\n**Explanation:** PINE has no native bulk read opcode. The client issues reads **serially** by default, choosing the largest aligned width at each step (read64 on 8-byte boundaries, falling back to 32/16/8).\n\n| Operation | Latency | Notes |\n|-----------|---------|-------|\n| Full 4096-byte read | ~52 ms | Measured on PCSX2 v2.6.3 over loopback |\n| Frame budget at 60fps | ~16.6 ms | Bulk read takes ~3 frames |\n\n**Optimization Option:** Set `PINE_PIPELINE_BATCH=2` to enable limited pipelining. This reduces latency but risks desyncing PCSX2's PINE server if the emulator's queue becomes overloaded.\n\n```bash\n# More aggressive pipelining (at your own risk)\nPINE_PIPELINE_BATCH=2 mcp-pine\n```\n\n**资料来源：** [README.md:92-95](https://github.com/dmang-dev/mcp-pine/blob/main/README.md), [src/pine.ts:95-105](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## Memory Access Issues\n\n### Alignment Requirements\n\n**Critical:** Multi-byte memory operations have alignment requirements that PCSX2 does NOT enforce.\n\n| Operation | Alignment | Unaligned Behavior |\n|-----------|-----------|-------------------|\n| `pine_read8` / `pine_write8` | None | Works correctly |\n| `pine_read16` / `pine_write16` | 2-byte | Silently returns corrupted data |\n| `pine_read32` / `pine_write32` | 4-byte | Silently returns corrupted data |\n| `pine_read64` / `pine_write64` | 8-byte | Silently returns corrupted data |\n\n**Safe Alternative:** For unaligned access, use `pine_read_range` and assemble the bytes manually.\n\n```typescript\n// Unaligned 32-bit read at 0x00100003\nconst bytes = await pine.readRange(0x00100003, 4);\nconst value = bytes.readUInt32LE(0);\n```\n\n**资料来源：** [src/tools.ts:42-50](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### 64-bit Value Precision\n\nJavaScript loses precision for integers beyond `2^53`. For 64-bit operations, values are exchanged as **decimal strings**.\n\n```typescript\n// Writing a large 64-bit value\nawait pine.write64(0x00100000, \"18446744073709551615\" as unknown as bigint);\n\n// Reading returns string-encoded decimal\nconst largeValue = await pine.read64(0x00100000);\n// Returns: \"18446744073709551615\" (as string)\n```\n\n**资料来源：** [CHANGELOG.md:28-30](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n## Timeout Issues\n\n### 10-Second Call Timeout\n\nEvery PINE call has a **10-second timeout**. If the emulator drops a reply (e.g., due to the wedging issue), the call rejects cleanly rather than hanging indefinitely.\n\n**Timeouts indicate:**\n- PCSX2 PINE server is wedged (most common)\n- Network/connection interruption\n- Emulator is unresponsive\n\n**If you experience frequent timeouts:**\n1. Check if PCSX2's PINE server has wedged\n2. Verify no other tool is aggressive pipelining\n3. Consider restarting the emulator\n\n**资料来源：** [CHANGELOG.md:26-29](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n## Emulator-Specific Setup\n\n### PCSX2 (Recommended)\n\n1. Launch PCSX2 1.7.x Qt or newer\n2. Navigate to **Settings → Advanced → Enable PINE Server**\n3. Default slot is **28011** — only change `PINE_SLOT` if you configure a different port\n4. Load any game\n\n> PINE is always-on once enabled; no scripts or console commands needed.\n\n**资料来源：** [README.md:44-54](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### RPCS3\n\nRPCS3 uses its own IPC implementation that mirrors PINE's opcode set. Wire-level compatibility hasn't been thoroughly tested.\n\n1. Enable IPC server in **Configuration → Advanced**\n2. Note the configured port\n3. Run with:\n   ```bash\n   PINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine\n   ```\n\n**资料来源：** [README.md:58-65](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Duckstation\n\nDuckstation includes a PINE server only in **specific builds**. Check whether your build includes it:\n\n1. Set `PINE_TARGET=duckstation`\n2. Configure `PINE_SLOT` to match the port shown in Duckstation's settings\n3. If connection fails, your build likely doesn't include PINE support\n\n**资料来源：** [README.md:5-9](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Environment Variables Reference\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator name — used as prefix in Unix socket path on Linux/macOS |\n| `PINE_SLOT` | `28011` | PINE slot / port number |\n| `PINE_HOST` | `127.0.0.1` | TCP host override (Windows always uses this) |\n| `PINE_SOCKET_PATH` | auto | Full Unix socket path override |\n| `PINE_PIPELINE_BATCH` | `1` | Number of serial reads to batch together (higher = faster but riskier) |\n\n**资料来源：** [README.md:34-40](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Diagnostic Checklist\n\nWhen reporting issues, include the following information:\n\n- [ ] Emulator name and version (e.g., PCSX2 v2.6.3)\n- [ ] Operating system and version\n- [ ] `PINE_TARGET` and `PINE_SLOT` values\n- [ ] Whether a game is currently loaded\n- [ ] Exact error message received\n- [ ] Steps to reproduce\n- [ ] Whether restarting the emulator resolves the issue\n\n## Getting Help\n\nIf issues persist after following this guide:\n\n1. Search existing [GitHub Issues](https://github.com/dmang-dev/mcp-pine/issues)\n2. File a new issue with diagnostic information\n3. Include the output of the smoke test:\n   ```bash\n   node .scratch/smoke.cjs\n   ```\n\n**资料来源：** [README.md:1-3](https://github.com/dmang-dev/mcp-pine/blob/main/README.md), [package.json:8-9](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n\n---\n\n---\n\n## Doramagic Pitfall Log\n\nProject: dmang-dev/mcp-pine\n\nSummary: Found 8 potential pitfall items; 0 are high/blocking. Highest priority: installation - 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers.\n\n## 1. installation · 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Submit listing PR to punkpeye/awesome-mcp-servers\n- User impact: 可能阻塞安装或首次运行。\n- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- Evidence: community_evidence:github | cevd_540ae479012f437fb2cb5e7d33636f1f | https://github.com/dmang-dev/mcp-pine/issues/2 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 2. configuration · 可能修改宿主 AI 配置\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: 项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- User impact: 安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- Suggested check: 列出会写入的配置文件、目录和卸载/回滚步骤。\n- Guardrail action: 涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- Evidence: capability.host_targets | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | host_targets=mcp_host, claude\n\n## 3. capability · 能力判断依赖假设\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: README/documentation is current enough for a first validation pass.\n- User impact: 假设不成立时，用户拿不到承诺的能力。\n- Suggested check: 将假设转成下游验证清单。\n- Guardrail action: 假设必须转成验证项；没有验证结果前不能写成事实。\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\n## 4. maintenance · 维护活跃度未知\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: 未记录 last_activity_observed。\n- User impact: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Suggested check: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Guardrail action: 维护活跃度未知时，推荐强度不能标为高信任。\n- Evidence: evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | last_activity_observed missing\n\n## 5. security_permissions · 下游验证发现风险项\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 下游已经要求复核，不能在页面中弱化。\n- Suggested check: 进入安全/权限治理复核队列。\n- Guardrail action: 下游风险存在时必须保持 review/recommendation 降级。\n- Evidence: downstream_validation.risk_items | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 6. security_permissions · 存在评分风险\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 风险会影响是否适合普通用户安装。\n- Suggested check: 把风险写入边界卡，并确认是否需要人工复核。\n- Guardrail action: 评分风险必须进入边界卡，不能只作为内部分数。\n- Evidence: risks.scoring_risks | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 7. maintenance · issue/PR 响应质量未知\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: issue_or_pr_quality=unknown。\n- User impact: 用户无法判断遇到问题后是否有人维护。\n- Suggested check: 抽样最近 issue/PR，判断是否长期无人处理。\n- Guardrail action: issue/PR 响应未知时，必须提示维护风险。\n- Evidence: evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | issue_or_pr_quality=unknown\n\n## 8. maintenance · 发布节奏不明确\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: release_recency=unknown。\n- User impact: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Suggested check: 确认最近 release/tag 和 README 安装命令是否一致。\n- Guardrail action: 发布节奏未知或过期时，安装说明必须标注可能漂移。\n- Evidence: 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 output with a Doramagic pitfall appendix.",
      "title": "mcp-pine 说明书",
      "toc": [
        "https://github.com/dmang-dev/mcp-pine 项目说明书",
        "目录",
        "Project Overview",
        "Project Purpose and Scope",
        "System Architecture",
        "Supported Emulators",
        "MCP Tools Reference",
        "Configuration",
        "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": true,
    "repo_commit": "4933690c461b67fa8f9561a974cc987936f34eaa",
    "repo_inspection_error": null,
    "repo_inspection_files": [
      "Dockerfile",
      "package.json",
      "README.md",
      "docs/RECIPES.md",
      "docs/SCOPE.md",
      "src/tools.ts",
      "src/pine.ts",
      "src/index.ts",
      "src/targets.ts"
    ],
    "repo_inspection_verified": true,
    "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\nThe following material strengthens the Repomix/AI Context Pack body. Human Manual is only a reading skeleton; pitfall logs become hard operating constraints for the host AI.\n\n## Human Manual Skeleton\n\nUsage rule: this is only a reading path and salience signal, not factual authority. Concrete facts must still come from repo evidence / Claim Graph.\n\nHard rules for the host AI:\n- Do not treat page titles, order, summaries, or importance as project facts.\n- When explaining the Human Manual skeleton, state that it is only a reading path / salience signal.\n- Capability, installation, compatibility, runtime status, and risk judgments must cite repo evidence, source paths, or Claim Graph.\n\n- **Project Overview**：importance `high`\n  - source_paths: README.md, package.json\n- **Installation Guide**：importance `high`\n  - source_paths: README.md, package.json\n- **Emulator Setup**：importance `high`\n  - source_paths: README.md, src/pine.ts\n- **System Architecture**：importance `high`\n  - source_paths: src/index.ts, src/pine.ts, src/tools.ts\n- **Configuration Reference**：importance `high`\n  - source_paths: README.md, src/pine.ts, package.json\n- **Memory Operations**：importance `high`\n  - source_paths: src/tools.ts, src/pine.ts, README.md\n- **Savestate Management**：importance `high`\n  - source_paths: src/tools.ts, src/pine.ts\n- **System Query Tools**：importance `medium`\n  - source_paths: src/tools.ts, src/pine.ts\n\n## Repo Inspection Evidence\n\n- repo_clone_verified: true\n- repo_inspection_verified: true\n- repo_commit: `4933690c461b67fa8f9561a974cc987936f34eaa`\n- inspected_files: `Dockerfile`, `package.json`, `README.md`, `docs/RECIPES.md`, `docs/SCOPE.md`, `src/tools.ts`, `src/pine.ts`, `src/index.ts`, `src/targets.ts`\n\nHard rules for the host AI:\n- Without repo_clone_verified=true, do not claim the source code has been read.\n- Without repo_inspection_verified=true, do not turn README/docs/package observations into facts.\n- Without quick_start_verified=true, do not claim the Quick Start has been successfully run.\n\n## Doramagic Pitfall Constraints\n\nThese rules come from Doramagic discovery, validation, or compilation pitfalls. The host AI must treat them as operating constraints, not general background notes.\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: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\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: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\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: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\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: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\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: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\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: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\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: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\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: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\n",
      "summary": "Context and operating boundaries for host AI agents.",
      "title": "AI Context Pack"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card\n\nProject: dmang-dev/mcp-pine\n\n## Doramagic Trial Decision\n\nCurrent decision: it can enter pre-publication recommendation checks. First use should still start with least privilege, a temporary directory, and reversible configuration.\n\n## What The User Can Do Now\n\n- Read the Human Manual first to understand the project purpose and main workflows.\n- Use Prompt Preview for pre-install exploration; it validates interaction shape, not real execution.\n- Run official Quick Start commands only inside an isolated environment, not a primary setup.\n\n## Do Not Do Yet\n\n- Do not treat Prompt Preview as a real project execution result.\n- Do not treat metadata-only validation as sandbox installation validation.\n- Do not describe unverified capabilities as supported, working, or safe to install.\n- Do not provide production data, private files, real secrets, or primary host configuration on first trial.\n\n## Pre-Install Checklist\n\n- Host AI match: mcp_host, claude\n- Official installation entry status: official entry point found\n- Isolated temporary directory, temporary host, or container validation: required\n- Configuration rollback path: required\n- API keys, network access, file access, or host configuration changes: treat as high risk until confirmed\n- Installation command, actual output, and failure logs: must be recorded\n\n## Current Blockers\n\n- review_required: community_discussion_evidence_below_public_threshold\n\n## Project-Specific Pitfalls\n\n- 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers (medium): 可能阻塞安装或首次运行。 Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 可能修改宿主 AI 配置 (medium): 安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。 Suggested check: 列出会写入的配置文件、目录和卸载/回滚步骤。\n- 能力判断依赖假设 (medium): 假设不成立时，用户拿不到承诺的能力。 Suggested check: 将假设转成下游验证清单。\n- 维护活跃度未知 (medium): 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。 Suggested check: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 下游验证发现风险项 (medium): 下游已经要求复核，不能在页面中弱化。 Suggested check: 进入安全/权限治理复核队列。\n\n## Risk And Permission Notes\n\n- no_demo: medium\n\n## Evidence Gaps\n\n- No structured evidence gaps are currently visible.\n",
      "summary": "Installation, permission, validation, and pre-recommendation risks.",
      "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:33:44 UTC\n\n## 目录\n\n- [Project Overview](#overview)\n- [Installation Guide](#installation)\n- [Emulator Setup](#emulator-setup)\n- [System Architecture](#system-architecture)\n- [Configuration Reference](#configuration)\n- [Memory Operations](#memory-operations)\n- [Savestate Management](#savestate-management)\n- [System Query Tools](#system-queries)\n- [Development Guide](#development-guide)\n- [Troubleshooting Guide](#troubleshooting)\n\n<a id='overview'></a>\n\n## Project Overview\n\n### 相关页面\n\n相关主题：[System Architecture](#system-architecture), [Emulator Setup](#emulator-setup)\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- [CHANGELOG.md](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n</details>\n\n# Project Overview\n\n`mcp-pine` is a Model Context Protocol (MCP) server that bridges AI coding assistants (primarily Claude) with PINE-enabled PlayStation emulators. It exposes a suite of memory reading, memory writing, and save state management tools, enabling AI agents to introspect and manipulate live game state in real-time.\n\n## Project Purpose and Scope\n\nThe project serves as an intermediary layer between an AI assistant and emulator internals. Instead of requiring manual memory hunting or external tools, developers and power users can query game state through natural language, with the MCP server translating those requests into PINE protocol calls.\n\n**Core capabilities include:**\n\n- Reading memory at arbitrary addresses (8/16/32/64-bit values and bulk byte ranges)\n- Writing memory values to live game state\n- Querying emulator metadata (game title, serial, CRC, status)\n- Saving and loading emulator states to named slots\n- Supporting multiple emulator backends through a unified interface\n\n资料来源：[README.md:1](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## System Architecture\n\n```mermaid\ngraph TD\n    subgraph \"MCP Host (Claude)\"\n        A[Claude AI Assistant]\n    end\n    \n    subgraph \"mcp-pine\"\n        B[MCP Server<br/>src/index.ts]\n        C[Tool Handler<br/>src/tools.ts]\n        D[PINE Client<br/>src/pine.ts]\n    end\n    \n    subgraph \"Emulator\"\n        E[PCSX2 / RPCS3 / Duckstation]\n        F[PINE Server]\n    end\n    \n    A -->|MCP Protocol| B\n    B --> C\n    C --> D\n    D -->|PINE Wire Protocol| F\n    F --> E\n    \n    style A fill:#e1f5fe\n    style E fill:#fff3e0\n    style D fill:#e8f5e9\n```\n\nThe system consists of three main layers:\n\n| Layer | Component | Purpose |\n|-------|-----------|---------|\n| MCP Host | Claude Desktop / Claude Code | User interface; issues tool calls via MCP |\n| Bridge | `mcp-pine` (Node.js) | Translates MCP requests to PINE protocol; manages connection lifecycle |\n| Emulator | PCSX2 / RPCS3 / Duckstation | Executes game; exposes PINE server for IPC |\n\n资料来源：[README.md:23-51](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Supported Emulators\n\n| Emulator | Platform | Status | Notes |\n|----------|----------|--------|-------|\n| PCSX2 | Windows / Linux / macOS | **Primary** | Full PINE support; default target |\n| RPCS3 | Windows / Linux | Compatible | IPC implementation mirrors PINE; wire-level compatibility untested |\n| Duckstation | Multi-platform | Compatible | Varies by build; requires PINE-enabled build |\n\nPCSX2 is the reference implementation. It is recommended to use PCSX2 1.7.x Qt or newer with PINE enabled via **Settings → Advanced → Enable PINE Server**.\n\n资料来源：[README.md:29-47](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## MCP Tools Reference\n\nThe server exposes 13 MCP tools organized into four functional categories.\n\n### Connectivity & Introspection\n\n| Tool | Description |\n|------|-------------|\n| `pine_ping` | Returns emulator version string. Use to verify connectivity. |\n| `pine_get_info` | Batch-retrieves title, serial, disc CRC, game version, and status in one round-trip. |\n| `pine_get_status` | Returns emulator run state: `running`, `paused`, `shutdown`, or `unknown`. |\n\n资料来源：[src/tools.ts:45-85](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### Memory Reads\n\n| Tool | Width | Alignment | Use Case |\n|------|-------|-----------|----------|\n| `pine_read8` | 8-bit | None | Status flags, counters, single bytes |\n| `pine_read16` | 16-bit | 2-byte | 16-bit counters, flags |\n| `pine_read32` | 32-bit | 4-byte | Pointers, flags, game state values |\n| `pine_read64` | 64-bit | 8-byte | Large IDs, EE pointers, double-word state |\n| `pine_read_range` | Variable | Adaptive | Bulk reads up to 4096 bytes; uses largest aligned width at each step |\n\n> **Important:** PCSX2 does not enforce alignment. Unaligned multi-byte reads silently return corrupted data from the aligned address below. Use `pine_read_range` for unaligned spans.\n\n资料来源：[src/tools.ts:87-200](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### Memory Writes\n\n| Tool | Width | Destructive | Notes |\n|------|-------|-------------|-------|\n| `pine_write8` | 8-bit | Yes | Single-byte overwrite |\n| `pine_write16` | 16-bit | Yes | Requires 2-byte alignment |\n| `pine_write32` | 32-bit | Yes | Requires 4-byte alignment |\n| `pine_write64` | 64-bit | Yes | Requires 8-byte alignment; values encoded as decimal strings |\n\n资料来源：[src/tools.ts:200-260](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### Save State Management\n\n| Tool | Description |\n|------|-------------|\n| `pine_save_state` | Serializes current emulator state to a numbered slot (0-255). **Overwrites existing slot.** |\n| `pine_load_state` | Restores emulator state from a numbered slot. |\n\nSave state files are stored in emulator-specific locations:\n\n- **PCSX2 Windows:** `%USERPROFILE%\\Documents\\PCSX2\\sstates`\n- **PCSX2 Linux:** `~/.config/PCSX2/sstates`\n- Filename format: `<serial> (<crc>).<slot>.p2s`\n\n资料来源：[src/tools.ts:260-310](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Default | Platform | Purpose |\n|----------|---------|----------|---------|\n| `PINE_TARGET` | `pcsx2` | Linux/macOS | Emulator name; used as Unix socket filename prefix (`<target>.sock.<slot>`) |\n| `PINE_SLOT` | `28011` | All | PINE slot number (also port for TCP on Windows) |\n| `PINE_HOST` | `127.0.0.1` | Windows | TCP host override |\n| `PINE_SOCKET_PATH` | Auto-resolved | Unix | Full socket path override |\n| `PINE_PIPELINE_BATCH` | `1` | All | Number of serial reads to batch; higher values risk desyncing PCSX2's PINE server |\n\n资料来源：[README.md:52-60](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Socket Resolution\n\n| Platform | Transport | Path Resolution |\n|----------|-----------|-----------------|\n| Linux/macOS | Unix Domain Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>` → `$TMPDIR/<target>.sock.<slot>` → `/tmp/<target>.sock.<slot>` |\n| Windows | TCP | `127.0.0.1:<PINE_SLOT>` |\n\n资料来源：[src/pine.ts:1-80](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## PINE Protocol Implementation\n\nThe `PineClient` class implements the binary PINE wire format:\n\n```mermaid\nsequenceDiagram\n    participant C as MCP Bridge\n    participant P as PineClient\n    participant E as Emulator PINE Server\n    \n    C->>P: pine_read32(0x00100000)\n    P->>P: Buffer.alloc(9)<br/>[4-byte size][opcode][4-byte addr]\n    P->>E: TCP/Unix Socket\n    E-->>P: Reply frame\n    P->>P: Parse response\n    P-->>C: number value\n```\n\n**Wire format per call:**\n\n| Field | Size | Encoding |\n|-------|------|----------|\n| Frame size | 4 bytes | UInt32LE (includes opcode + payload) |\n| Opcode | 1 byte | UInt8 |\n| Payload | Variable | Little-endian |\n\n**Opcodes:**\n\n| Opcode | Name | Direction | Payload |\n|--------|------|-----------|---------|\n| 0x01 | Version | Read | None |\n| 0x02 | Title | Read | None |\n| 0x03 | ID | Read | None |\n| 0x04 | UUID | Read | None |\n| 0x05 | GameVersion | Read | None |\n| 0x06 | SaveState | Write | 1 byte (slot) |\n| 0x07 | LoadState | Write | 1 byte (slot) |\n| 0x08 | Read8 | Read | 4 bytes (address) |\n| 0x09 | Read16 | Read | 4 bytes (address) |\n| 0x0A | Read32 | Read | 4 bytes (address) |\n| 0x0B | Read64 | Read | 4 bytes (address) |\n| 0x0C | Write8 | Write | 1 byte (value) + 4 bytes (address) |\n| 0x0D | Write16 | Write | 2 bytes (value) + 4 bytes (address) |\n| 0x0E | Write32 | Write | 4 bytes (value) + 4 bytes (address) |\n| 0x0F | Status | Read | None |\n| 0x10 | Write64 | Write | 8 bytes (value) + 4 bytes (address) |\n\n资料来源：[src/pine.ts:81-200](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## Installation\n\n### Package Distribution\n\n| Method | Command | Use Case |\n|--------|---------|----------|\n| npm global | `npm install -g mcp-pine` | System-wide installation |\n| npx (on-demand) | `npx -y mcp-pine` | Temporary testing |\n| Source | `git clone` + `npm install` | Development |\n\n资料来源：[README.md:61-72](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Claude Desktop Integration\n\nAdd to `claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\nConfig location by platform:\n\n| Platform | Path |\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资料来源：[README.md:14-35](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Technical Constraints and Known Issues\n\n### PCSX2 PINE Server Fragility\n\nPCSX2's PINE server has a **fragile request queue**. Dropping any single request (which occurs silently when too many requests are pipelined) desyncs the reply pipeline. Once desynced, every subsequent reply is misaligned, causing all tools to timeout until the emulator is restarted.\n\n| Setting | Value | Latency | Safety |\n|---------|-------|---------|--------|\n| `PINE_PIPELINE_BATCH=1` | Serial | ~52ms for 4096 bytes | Safe (default) |\n| `PINE_PIPELINE_BATCH=2+` | Batched | Lower | Risk of desync |\n\nThe default serial mode completes a full 4KB read in under two emulated frames, making pipelining unnecessary for most use cases.\n\n资料来源：[CHANGELOG.md:15-40](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n### Troubleshooting Reference\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running, PINE disabled, port mismatch | Check `PINE_SLOT` and emulator settings |\n| `PINE FAIL response (0xFF)` | No game loaded, address unmapped | Load a game; verify address range |\n| Reads return zeros | Address in unallocated region | Try `0x00100000` (EE main RAM) |\n| Values look corrupted | Endianness mismatch | PINE returns little-endian |\n| `PINE call timed out (10s)` after heavy use | PCSX2 PINE server desynced | **Fully restart PCSX2** |\n\n资料来源：[README.md:95-120](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Dependencies\n\n```json\n{\n  \"dependencies\": {\n    \"@modelcontextprotocol/sdk\": \"^1.12.0\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^22.0.0\",\n    \"typescript\": \"^5.5.0\"\n  }\n}\n```\n\nThe project targets Node.js and uses TypeScript for type safety. The `@modelcontextprotocol/sdk` package provides the MCP server infrastructure.\n\n资料来源：[package.json:1-30](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n\n## Related Projects\n\n| Project | Repository | Description |\n|---------|------------|-------------|\n| mcp-mgba | [dmang-dev/mcp-mgba](https://github.com/dmang-dev/mcp-mgba) | Sister MCP server for mGBA (Game Boy Advance); includes button input and screenshot support |\n| PINE Protocol | [GovanifY/pine](https://github.com/GovanifY/pine) | Underlying IPC specification |\n\n资料来源：[README.md:140-145](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n---\n\n<a id='installation'></a>\n\n## Installation Guide\n\n### 相关页面\n\n相关主题：[Configuration Reference](#configuration), [Troubleshooting Guide](#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- [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</details>\n\n# Installation Guide\n\nThis guide covers all supported methods for installing and configuring `mcp-pine`, a Model Context Protocol (MCP) server that bridges MCP clients to emulators via the PINE protocol.\n\n## Overview\n\n`mcp-pine` enables AI assistants like Claude to interact with PlayStation emulators (PCSX2, RPCS3, Duckstation) through the PINE IPC protocol. It exposes memory read/write tools, save state management, and emulator introspection as MCP tools.\n\n| Component | Technology | Purpose |\n|-----------|------------|---------|\n| MCP Server | TypeScript + Node.js | Bridges MCP clients to PINE protocol |\n| Transport | stdio | Standard MCP communication |\n| Emulator IPC | PINE protocol | Binary memory/state access |\n| Connections | TCP/Unix Socket | Platform-specific transport |\n\n资料来源：[README.md:1-10]()\n\n## Installation Methods\n\n### Method 1: Global npm Install\n\nInstall globally via npm for system-wide access:\n\n```bash\nnpm install -g mcp-pine\n```\n\nThis makes `mcp-pine` available as a command-line tool accessible from any terminal session.\n\n资料来源：[README.md:44-47]()\n\n### Method 2: Direct Execution with npx\n\nRun without installation using npx:\n\n```bash\nnpx -y mcp-pine\n```\n\nThis downloads and executes the package temporarily, useful for testing or one-off usage.\n\n资料来源：[README.md:49-51]()\n\n### Method 3: Clone and Develop\n\nFor development or customization:\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install        # also runs the build via the `prepare` hook\n```\n\nFor live development with TypeScript watching:\n\n```bash\nnpm run dev      # tsc --watch\n```\n\n资料来源：[README.md:53-60]()\n\n## Emulator Setup\n\n### PCSX2 (Recommended)\n\nPCSX2 1.7.x and newer include native PINE server support:\n\n1. Launch PCSX2 (1.7.x Qt or newer)\n2. Navigate to **Settings → Advanced → Enable PINE Server**\n3. Default slot is **28011**\n\n> **Note:** If the option is in a different submenu, search settings for \"PINE\".\n\nOnce enabled, PINE is always-on—no scripts or console commands required. Load any game to start interacting.\n\n资料来源：[README.md:23-33]()\n\n### RPCS3\n\nRPCS3 uses an IPC implementation that mirrors PINE's opcode set:\n\n1. Navigate to **Configuration → Advanced → Enable IPC server**\n2. Note the configured port\n3. Run with: `PINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine`\n\n> **Note:** Wire-level compatibility with RPCS3 hasn't been thoroughly tested. File issues if problems occur.\n\n资料来源：[README.md:35-44]()\n\n### Duckstation\n\nDuckstation builds vary in PINE support:\n\n1. Verify your build includes a PINE server\n2. Set `PINE_TARGET=duckstation PINE_SLOT=<port>`\n\n资料来源：[README.md:46-48]()\n\n## MCP Client Registration\n\n### Claude Code (CLI)\n\nRegister for user-wide access:\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\nVerify the connection:\n\n```bash\nclaude mcp list\n# pine: mcp-pine - ✓ Connected\n```\n\n资料来源：[README.md:11-17]()\n\n### Claude Desktop\n\nEdit the configuration file for your platform:\n\n| Platform | Path |\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\nAdd the server configuration:\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\nRestart Claude Desktop after editing.\n\n资料来源：[README.md:19-32]()\n\n### Other MCP Clients\n\n`mcp-pine` speaks standard MCP over stdio. Run the binary and connect any compatible client:\n\n```bash\nmcp-pine\n```\n\n资料来源：[README.md:45-46]()\n\n## Configuration\n\n### Environment Variables\n\n| Env Variable | Default | Purpose |\n|--------------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator name—used as Unix socket prefix on Linux/macOS (`<target>.sock.<slot>`). Ignored on Windows (TCP only). |\n| `PINE_SLOT` | `28011` | PINE slot number—also the TCP port on Windows. |\n| `PINE_HOST` | `127.0.0.1` | Override the connection host |\n| `PINE_SOCKET_PATH` | Auto-resolved | Override the Unix socket path |\n| `PINE_PIPELINE_BATCH` | `1` | Number of pipelined requests (see Performance Notes) |\n\n资料来源：[README.md:34-43]()\n\n### Socket Path Resolution\n\nConnection transport varies by platform:\n\n```mermaid\ngraph TD\n    A[Start] --> B{Platform?}\n    B -->|Windows| C[TCP 127.0.0.1:PINE_SLOT]\n    B -->|Linux/macOS| D{Look for XDG_RUNTIME_DIR}\n    D -->|Set| E[Use $XDG_RUNTIME_DIR/<target>.sock.<slot>]\n    D -->|Not Set| F{ TMPDIR set?}\n    F -->|Yes| G[Use $TMPDIR/<target>.sock.<slot>]\n    F -->|No| H[Use /tmp/<target>.sock.<slot>]\n```\n\n资料来源：[src/pine.ts:60-75]()\n\n## Smoke Testing\n\nTest against a running emulator:\n\n```bash\nnode .scratch/smoke.cjs\n```\n\n资料来源：[README.md:66-69]()\n\n## Troubleshooting\n\n### Common Issues\n\n| Symptom | Cause / Fix |\n|---------|-------------|\n| `Cannot reach PINE server` | Emulator isn't running, PINE isn't enabled in settings, or slot/port doesn't match. Check `PINE_SLOT`. |\n| `PINE FAIL response` (0xFF) | Emulator rejected request—usually no game loaded or address is unmapped. |\n| Reads return zeros | Address is in an unallocated region. Try `0x00100000` first (almost always inside EE RAM). |\n| Tool calls work but values look corrupted | Check endianness—PINE returns little-endian. Use `read_range`-style byte reads for strings. |\n| `pine_ping` times out after heavy use | **PCSX2 PINE server is wedged.** Only a full emulator restart recovers. Reconnecting alone won't help. |\n\n资料来源：[README.md:68-78]()\n\n### PCSX2 Pipeline Drop Bug\n\nPCSX2's PINE server has a fragile request queue. If more than ~6 in-flight requests are pipelined, it silently drops requests, desyncing the reply pipeline. Once desynced, every reply is misaligned—only an emulator restart fixes this.\n\n| Operation | Latency | Notes |\n|-----------|---------|-------|\n| Full 4096-byte read | ~52 ms | Fully serial requests over loopback TCP |\n| Pipelined requests | Faster but risky | `PINE_PIPELINE_BATCH=2` for experimental use |\n\n资料来源：[src/pine.ts:115-125]()\n\n## Project Structure\n\n```\nmcp-pine/\n├── src/\n│   ├── index.ts      # Main entry point, MCP server setup\n│   ├── pine.ts       # PINE protocol client implementation\n│   └── tools.ts      # MCP tool definitions\n├── .scratch/\n│   └── smoke.cjs     # Quick smoke test script\n├── package.json      # Dependencies and scripts\n└── README.md         # Documentation\n```\n\n## Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `@modelcontextprotocol/sdk` | ^1.12.0 | MCP server framework |\n| `@types/node` | ^22.0.0 | TypeScript types |\n| `typescript` | ^5.5.0 | Build tooling |\n\n资料来源：[package.json:8-14]()\n\n## See Also\n\n- [mcp-mgba](https://github.com/dmang-dev/mcp-mgba) — Sister MCP server for mGBA (includes button input + screenshot)\n- [PINE protocol spec](https://github.com/GovanifY/pine) — Underlying IPC standard\n- [docs/RECIPES.md](docs/RECIPES.md) — Cookbook for common workflows (RAM hunting, struct decoding, snapshot-experiment-restore)\n\n---\n\n<a id='emulator-setup'></a>\n\n## Emulator Setup\n\n### 相关页面\n\n相关主题：[Configuration Reference](#configuration), [Troubleshooting Guide](#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/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# Emulator Setup\n\nThis page documents how to configure and connect PlayStation 2 emulators to the mcp-pine MCP server. mcp-pine acts as a bridge between AI assistants (via the Model Context Protocol) and the PINE IPC (PlayStation 2 Interactive Interface) server embedded in compatible emulators.\n\n## Overview\n\nmcp-pine requires a running emulator with PINE server support enabled. The server communicates with the emulator through either TCP (Windows) or Unix domain sockets (Linux/macOS), allowing AI assistants to read/write memory, query game metadata, and manage save states.\n\n**Supported emulators:**\n\n| Emulator | Platform | PINE Support | Notes |\n|----------|----------|--------------|-------|\n| PCSX2 (1.7.x Qt+) | All | Native | Full support; recommended |\n| RPCS3 | All | Partial | IPC implementation mirrors PINE; wire compatibility untested |\n| Duckstation | All | Varies | Build-dependent; check your version |\n\n资料来源：[README.md:1-50](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Architecture\n\nThe connection flow between mcp-pine and the emulator follows a client-server pattern:\n\n```mermaid\ngraph LR\n    subgraph \"Host System\"\n        A[\"Claude / MCP Client\"] --> B[\"mcp-pine\"]\n        B --> C[\"Emulator PINE Server\"]\n    end\n    \n    D[\"PlayStation 2 Game\"] --> C\n    \n    C -->|TCP 127.0.0.1:28011<br/>Unix Socket<br/>/tmp/pcsx2.sock.28011| B\n    \n    style C fill:#90EE90\n    style B fill:#87CEEB\n```\n\n**Connection transport selection:**\n\n- **Windows:** TCP socket to `127.0.0.1:<PINE_SLOT>`\n- **Linux/macOS:** Unix domain socket at `<TMPDIR or /tmp>/<PINE_TARGET>.sock.<PINE_SLOT>`\n\n资料来源：[src/pine.ts:150-200](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator name—used as Unix socket filename prefix on Linux/macOS |\n| `PINE_SLOT` | `28011` | PINE slot number (port on Windows, socket suffix on Unix) |\n| `PINE_PIPELINE_BATCH` | `1` | Number of serial PINE requests to batch (higher = faster but riskier) |\n\n资料来源：[README.md:60-75](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Socket Path Resolution\n\nThe `PineClient` class resolves the socket path based on platform and options:\n\n```mermaid\ngraph TD\n    A[\"PineClient constructor\"] --> B{opts.kind explicitly set?}\n    B -->|Yes| C[\"Use opts.host/opts.path\"]\n    B -->|No| D{Platform = Windows?}\n    D -->|Yes| E[\"TCP: 127.0.0.1:PINE_SLOT\"]\n    D -->|No| F{Platform = Linux/macOS?}\n    F -->|Yes| G[\"Unix: XDG_RUNTIME_DIR<br/>or TMPDIR<br/>/<target>.sock.<slot>\"]\n    F -->|No| H[\"TCP fallback: localhost:PINE_SLOT\"]\n    \n    style G fill:#90EE90\n    style E fill:#87CEEB\n```\n\n资料来源：[src/pine.ts:100-180](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## PCSX2 Setup\n\nPCSX2 provides native, stable PINE server support starting from version 1.7.x Qt.\n\n### Prerequisites\n\n- PCSX2 1.7.x (Qt build) or newer\n- A loaded PlayStation 2 game\n\n### Configuration Steps\n\n1. Launch PCSX2\n2. Navigate to **Settings → Advanced → Enable PINE Server**\n   - The option location may vary slightly by build version\n   - Use the settings search function to find \"PINE\" if the menu structure differs\n3. Verify the default slot is **28011**\n4. Load any PlayStation 2 game\n\nNo console commands or external scripts are required—PINE is always-on once the toggle is enabled.\n\n资料来源：[README.md:30-45](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## RPCS3 Setup\n\nRPCS3 implements its own IPC mechanism that mirrors PINE's opcode set, but wire-level compatibility with this client has not been thoroughly tested.\n\n### Configuration Steps\n\n1. Navigate to **Configuration → Advanced → Enable IPC server**\n2. Note the configured port number\n3. Run mcp-pine with the target override:\n\n```bash\nPINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine\n```\n\n**Note:** Full compatibility is not guaranteed. If issues arise, please file a bug report with connection logs and emulator version information.\n\n资料来源：[README.md:46-55](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Duckstation Setup\n\nDuckstation includes PINE server support in some builds, but availability varies by version and distribution.\n\n### Configuration\n\nIf your Duckstation build includes PINE support:\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=<port> mcp-pine\n```\n\n**Note:** Check your Duckstation build version to confirm PINE server availability.\n\n资料来源：[README.md:56-60](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## MCP Client Registration\n\nAfter the emulator is configured, register mcp-pine with your MCP client.\n\n### Claude Code (CLI)\n\n```bash\nclaude mcp add pine --scope user mcp-pine\n```\n\nVerify registration:\n\n```bash\nclaude mcp list\n# pine: mcp-pine - ✓ Connected\n```\n\n资料来源：[README.md:85-95](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Claude Desktop\n\nEdit the configuration file at your platform-specific location:\n\n| Platform | Path |\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\nAdd the mcp-pine server entry:\n\n```json\n{\n  \"mcpServers\": {\n    \"pine\": {\n      \"command\": \"mcp-pine\"\n    }\n  }\n}\n```\n\nRestart Claude Desktop after editing.\n\n资料来源：[README.md:96-115](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Available Tools\n\nOnce connected, the following tools are available through the MCP interface:\n\n| Tool | Purpose | Call Type |\n|------|---------|-----------|\n| `pine_ping` | Verify connection to emulator | 1 round-trip |\n| `pine_get_info` | Get game title, serial, CRC, version, and status | 5 parallel calls |\n| `pine_get_status` | Get emulator run state (running/paused/shutdown) | 1 round-trip |\n| `pine_read8/16/32/64` | Read bytes from EE memory | 1 round-trip each |\n| `pine_read_range` | Bulk read up to 4096 bytes | Serial sequence |\n| `pine_write8/16/32/64` | Write bytes to EE memory | 1 round-trip each |\n| `pine_save_state` | Save emulator state to slot | 1 round-trip |\n| `pine_load_state` | Load emulator state from slot | 1 round-trip |\n\n### Address Parameter Notes\n\nAll address parameters reference the **EE main address space**. Key memory regions:\n\n| Region | Address Range | Description |\n|--------|---------------|-------------|\n| EE Main RAM | `0x00100000` – `0x01FFFFFF` | Primary game state memory (99% of use cases) |\n| IOP RAM | `0x1C000000`+ | Input/Output Processor memory |\n| Scratchpad | `0x70000000` – `0x70003FFF` | Fast local memory |\n\n**Alignment requirements:**\n\n| Width | Alignment | Notes |\n|-------|-----------|-------|\n| 8-bit | None | Safe to use at any address |\n| 16-bit | 2-byte | Misaligned access silently corrupts data |\n| 32-bit | 4-byte | Misaligned access silently corrupts data |\n| 64-bit | 8-byte | Misaligned access silently corrupts data |\n\n**Important:** PCSX2's PINE implementation does NOT enforce alignment. Misaligned multi-byte access returns bytes from the aligned address below, silently corrupting values.\n\n资料来源：[src/tools.ts:1-100](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## Troubleshooting\n\n### Common Issues\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running, PINE not enabled, or slot mismatch | Check `PINE_SLOT` matches emulator setting |\n| `PINE FAIL response` (0xFF) | No game loaded, or address unmapped | Load a game; try `0x00100000` first |\n| Reads return zeros | Address in unallocated region | Use `0x00100000` (EE RAM base) |\n| Values look corrupted | Wrong endianness or alignment | PINE returns little-endian; use `pine_read_range` for byte-level control |\n| `PINE call timed out (10s)` after heavy use | PCSX2 PINE queue desync | Full PCSX2 restart required—reconnecting alone won't help |\n\n资料来源：[README.md:130-150](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### PCSX2 PINE Queue Desync\n\nPCSX2's PINE server has a fragile request queue. If more than approximately 6 in-flight requests are issued, the server silently drops requests, corrupting the reply pipeline alignment. Once desynced, every subsequent reply is misaligned, causing timeouts on even simple operations like `pine_ping`.\n\n**Symptoms:**\n- Fresh `pine_ping` calls timing out after heavy use\n- Intermittent read/write failures\n- Non-deterministic response values\n\n**Fix:**\n1. Fully restart PCSX2\n2. Reconnect mcp-pine\n3. Reduce `PINE_PIPELINE_BATCH` to `1` (default)\n\n资料来源：[README.md:155-165](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)  \n资料来源：[src/pine.ts:60-90](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n### Performance Considerations\n\n`pine_read_range` issues PINE calls serially by default to avoid queue desync. Measured performance on PCSX2 v2.6.3:\n\n| Operation | Latency |\n|-----------|---------|\n| Full 4096-byte read | ~52 ms |\n| Per 64-bit word | ~13 ms |\n\nLoopback TCP is fast enough that serial reads complete in less than two emulated frames. For lower latency with acceptable risk, set `PINE_PIPELINE_BATCH=2` or higher.\n\n**Warning:** Higher batch values increase the probability of triggering PCSX2's queue drop behavior.\n\n资料来源：[README.md:166-175](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Development Setup\n\nFor testing against a running emulator:\n\n```bash\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\nnpm install        # Runs build via prepare hook\n\n# Development mode with TypeScript watching\nnpm run dev\n\n# Smoke test\nnode .scratch/smoke.cjs\n```\n\nThe project builds using TypeScript 5.5+ with Node 22+ support.\n\n资料来源：[README.md:175-190](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)  \n资料来源：[package.json:1-30](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n\n---\n\n<a id='system-architecture'></a>\n\n## System Architecture\n\n### 相关页面\n\n相关主题：[Memory Operations](#memory-operations), [Savestate Management](#savestate-management), [System Query Tools](#system-queries)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\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</details>\n\n# System Architecture\n\n## Overview\n\nmcp-pine is an MCP (Model Context Protocol) server that bridges AI assistants (such as Claude) with PlayStation 2 emulators (PCSX2, RPCS3, Duckstation) via the PINE (Platform Independent Networked Environment) protocol. It exposes emulator memory, save states, and game information as MCP tools, enabling AI-driven game analysis, memory hacking, and automation workflows.\n\nThe architecture follows a layered client-server model with three distinct subsystems: the MCP protocol layer, the PINE protocol client, and the cross-platform transport layer.\n\n## High-Level Architecture\n\n```mermaid\ngraph TD\n    subgraph \"MCP Host (Claude)\"\n        A[\"Claude AI\"]\n    end\n    \n    subgraph \"mcp-pine\"\n        B[\"MCP Server<br/>(@modelcontextprotocol/sdk)\"]\n        C[\"PineClient<br/>(Protocol Layer)\"]\n        D[\"Transport Layer<br/>(TCP / Unix Socket)\"]\n    end\n    \n    subgraph \"Emulator\"\n        E[\"PINE Server\"]\n        F[\"EE Memory<br/>IOP Memory<br/>Save States\"]\n    end\n    \n    A <-->|\"MCP stdio\"| B\n    B <-->|\"Tool Calls\"| C\n    C <-->|\"PINE Protocol\"| D\n    D <-->|\"TCP:127.0.0.1<br/>Unix:/tmp/*.sock\"| E\n    E <--> F\n```\n\n**资料来源：** [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md) - Project overview and configuration documentation\n\n## Component Architecture\n\n### Layer 1: MCP Server\n\nThe MCP server layer implements the Model Context Protocol specification using the `@modelcontextprotocol/sdk`. It registers tool handlers and routes incoming tool calls to the PINE client.\n\n| Component | File | Responsibility |\n|-----------|------|----------------|\n| `registerTools()` | `src/tools.ts` | Registers all 13 MCP tools with the SDK |\n| Tool dispatcher | `src/tools.ts` | Routes `CallToolRequest` to corresponding PINE operations |\n| Response formatter | `src/tools.ts` | Formats PINE responses for MCP protocol |\n\n**资料来源：** [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) - MCP tool registration and handler implementation\n\n### Layer 2: PINE Protocol Client\n\nThe `PineClient` class (`src/pine.ts`) implements the binary PINE wire format specification. It handles request encoding, response decoding, and protocol state management.\n\n```mermaid\ngraph LR\n    A[\"Tool Request\"] --> B[\"Encode Opcode<br/>+ Payload\"]\n    B --> C[\"Buffer<br/>(4-byte size prefix)\"]\n    C --> D[\"Socket Write\"]\n    D --> E[\"Response Read\"]\n    E --> F[\"Parse Size\"]\n    F --> G[\"Extract Opcode<br/>+ Data\"]\n    G --> H[\"Decode Value\"]\n    H --> I[\"Return to Tool\"]\n```\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - PINE client implementation\n\n#### Opcode Mapping\n\n| Operation | Opcode | Direction | Description |\n|-----------|--------|-----------|-------------|\n| `getVersion` | `Op.Version` | Read | Emulator version string |\n| `getTitle` | `Op.Title` | Read | Game title |\n| `getId` | `Op.ID` | Read | Game serial number |\n| `getUuid` | `Op.UUID` | Read | Disc CRC hash |\n| `getGameVersion` | `Op.GameVersion` | Read | Game version string |\n| `getStatus` | `Op.Status` | Read | Emulator state (running/paused/shutdown) |\n| `read8/16/32/64` | `Op.Read*` | Read | Memory reads at specified width |\n| `write8/16/32/64` | `Op.Write*` | Write | Memory writes at specified width |\n| `saveState` | `Op.SaveState` | Write | Save to slot (0-255) |\n| `loadState` | `Op.LoadState` | Write | Load from slot (0-255) |\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - Opcode constants and operation implementations\n\n### Layer 3: Transport Layer\n\nThe transport layer provides cross-platform connectivity using the appropriate socket type for each operating system.\n\n```mermaid\ngraph TD\n    A[\"Platform Detection\"] --> B{OS?}\n    B -->|Windows| C[\"TCP Socket<br/>127.0.0.1:SLOT\"]\n    B -->|Linux/macOS| D[\"Unix Domain Socket\"]\n    D --> E[\"$XDG_RUNTIME_DIR<br/>/<target>.sock.<slot>\"]\n    D --> F[\"$TMPDIR<br/>/<target>.sock.<slot>\"]\n    D --> G[\"/tmp<br/>/<target>.sock.<slot>\"]\n```\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - `resolveSocket()` function and transport abstraction\n\n#### Socket Resolution Strategy\n\n| Priority | Linux/macOS Path | Windows |\n|----------|------------------|---------|\n| 1 | `$XDG_RUNTIME_DIR/<target>.sock.<slot>` | TCP `127.0.0.1:<slot>` |\n| 2 | `$TMPDIR/<target>.sock.<slot>` | — |\n| 3 | `/tmp/<target>.sock.<slot>` | — |\n\n**资料来源：** [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md) - Configuration and transport documentation\n\n## Request Queue Management\n\nThe `PineClient` maintains an internal request queue to handle concurrent tool calls and ensure responses are matched to their originating requests.\n\n```mermaid\nsequenceDiagram\n    participant Tool1 as Tool Call 1\n    participant Tool2 as Tool Call 2\n    participant Queue as Request Queue\n    participant Client as PineClient\n    participant Socket as Network Socket\n    \n    Tool1->>Queue: Enqueue request\n    Tool2->>Queue: Enqueue request\n    Queue->>Socket: Write Request 1\n    Queue->>Socket: Write Request 2\n    Socket-->>Client: Receive Response 1\n    Client->>Queue: Resolve Promise 1\n    Socket-->>Client: Receive Response 2\n    Client->>Queue: Resolve Promise 2\n```\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - Request queue implementation\n\n### Pending Request Structure\n\n```typescript\ninterface Pending {\n  resolve: (value: Buffer) => void;\n  reject: (err: Error) => void;\n}\n```\n\nEach pending request holds references to its `resolve` and `reject` functions, allowing the response handler to deliver results to the correct caller even when multiple requests are in-flight.\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - Pending interface definition\n\n## Bulk Read Implementation\n\nThe `readRange()` method implements efficient bulk memory reads by combining multiple aligned PINE operations.\n\n```mermaid\ngraph TD\n    A[\"readRange(addr, length)\"] --> B[\"Calculate Steps\"]\n    B --> C{\"Aligned?\"}\n    C -->|8-byte| D[\"read64\"]\n    C -->|4-byte| E[\"read32\"]\n    C -->|2-byte| F[\"read16\"]\n    C -->|1-byte| G[\"read8\"]\n    D --> H[\"PIPELINE_BATCH\"]\n    E --> H\n    F --> H\n    G --> H\n    H --> I[\"Promise.all(batch)\"]\n    I --> J{\"More steps?\"}\n    J -->|Yes| H\n    J -->|No| K[\"Return Buffer\"]\n```\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - `readRange()` implementation\n\n### Pipelining Configuration\n\n| Env Variable | Default | Effect |\n|--------------|---------|--------|\n| `PINE_PIPELINE_BATCH` | `1` | Number of concurrent requests (1=serial, 2+=parallel) |\n\n> **Warning:** PCSX2's PINE server silently drops requests when too many are pipelined (~7+ in-flight). This desyncs the reply pipeline, causing all subsequent requests to time out until emulator restart.\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - Pipeline batch configuration\n\n## Tool Registration Flow\n\n```mermaid\ngraph LR\n    A[\"MCP Server<br/>Instantiation\"] --> B[\"PineClient<br/>Creation\"]\n    B --> C[\"registerTools()<br/>called\"]\n    C --> D[\"ListToolsRequestHandler<br/>registered\"]\n    C --> E[\"CallToolRequestHandler<br/>registered\"]\n    F[\"MCP Host<br/>connects\"] --> G[\"ListTools<br/>request\"]\n    G --> H[\"TOOLS[]<br/>schema returned\"]\n    F --> I[\"Tool Call<br/>invoked\"]\n    I --> J[\"switch(name)<br/>dispatch\"]\n    J --> K[\"PineClient<br/>operation\"]\n```\n\n**资料来源：** [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) - Tool registration and dispatch\n\n## Memory Address Space\n\nThe PINE protocol operates on PlayStation 2 memory regions. All address parameters use absolute byte addresses in the EE (Emotion Engine) main address space.\n\n| Region | Address Range | Size | Description |\n|--------|---------------|------|-------------|\n| EE Main RAM | `0x00100000` - `0x01FFFFFF` | ~31 MB | Primary game state storage |\n| IOP RAM | `0x1C000000`+ | Variable | I/O Processor memory |\n| Scratchpad | Special range | 16 KB | Fast-access cache |\n\n> **Alignment Note:** Multi-byte reads/writes (16/32/64-bit) must be aligned to their width. PINE on PCSX2 does NOT enforce alignment — unaligned access silently returns corrupted data.\n\n**资料来源：** [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) - Address parameter descriptions\n\n## 64-bit Value Handling\n\nJavaScript's `Number` type loses precision beyond `2^53`. The implementation handles 64-bit values as decimal strings.\n\n| Operation | Input Format | Output Format | Reason |\n|-----------|-------------|---------------|--------|\n| `pine_write64` | Decimal string (`\"18446744073709551615\"`) | — | Preserve full u64 range |\n| `pine_read64` | — | Decimal string | Preserve full u64 range |\n\n**资料来源：** [src/tools.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) - 64-bit parameter descriptions\n\n## Configuration Environment Variables\n\n| Variable | Default | Platform | Purpose |\n|----------|---------|----------|---------|\n| `PINE_TARGET` | `pcsx2` | All | Emulator name prefix for Unix socket path |\n| `PINE_SLOT` | `28011` | All | PINE slot number (also port on Windows) |\n| `PINE_HOST` | `127.0.0.1` | Windows | TCP host override |\n| `PINE_SOCKET_PATH` | Auto | All | Custom Unix socket path |\n| `PINE_PIPELINE_BATCH` | `1` | All | Concurrent request batching |\n| `PIPELINE_BATCH` | `1` | All | Alias for `PINE_PIPELINE_BATCH` |\n\n**资料来源：** [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md) - Configuration table\n\n## Error Handling\n\n| Error | Cause | Fix |\n|-------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running or PINE disabled | Check `PINE_SLOT` matches emulator settings |\n| `PINE FAIL response (0xFF)` | No game loaded or address unmapped | Load a game; verify address range |\n| Reads return zeros | Address in unallocated region | Try `0x00100000` first (EE RAM base) |\n| Values look corrupted | Endianness mismatch | PINE returns little-endian; check parsing |\n| `PINE call timed out (10s)` | PCSX2 PINE server wedged | Full emulator restart required |\n\n**资料来源：** [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md) - Troubleshooting section\n\n## Lazy Reconnect Behavior\n\nThe MCP server implements lazy reconnection — if the emulator is restarted, the PINE client automatically reconnects without requiring the MCP host to restart.\n\n```mermaid\ngraph TD\n    A[\"Tool Call\"] --> B{\"Connected?\"}\n    B -->|No| C[\"Connect()\"]\n    C --> D{\"Success?\"}\n    D -->|Yes| E[\"Send Request\"]\n    D -->|No| F[\"Error (retry next call)\"]\n    B -->|Yes| E\n    E --> G[\"Response\"]\n```\n\n**资料来源：** [src/pine.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts) - Connection management\n\n## Package Dependencies\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `@modelcontextprotocol/sdk` | `^1.12.0` | MCP protocol implementation |\n| `typescript` | `^5.5.0` | TypeScript compilation (dev) |\n| `@types/node` | `^22.0.0` | Node.js type definitions (dev) |\n\n**资料来源：** [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json) - Dependencies section\n\n## Supported Emulators\n\n| Emulator | Platform | Status | Notes |\n|----------|----------|--------|-------|\n| PCSX2 | All | Primary | Full PINE support; Qt 1.7.x+ |\n| RPCS3 | All | Experimental | IPC implementation mirrors PINE; wire compatibility untested |\n| Duckstation | All | Varies | Depends on build; PINE server availability varies |\n\n**资料来源：** [README.md](https://github.com/dmang-dev/mcp-pine/blob/main/README.md) - Emulator setup documentation\n\n---\n\n<a id='configuration'></a>\n\n## Configuration Reference\n\n### 相关页面\n\n相关主题：[Emulator Setup](#emulator-setup), [System Architecture](#system-architecture)\n\n<details>\n<summary>Related Source Files</summary>\n\nThe following source files were used to generate this page:\n\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- [src/index.ts](https://github.com/dmang-dev/mcp-pine/blob/main/src/index.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# Configuration Reference\n\n## Overview\n\nThe `mcp-pine` project provides a Model Context Protocol (MCP) server that bridges MCP clients (such as Claude Code or Claude Desktop) to PlayStation 2/3 emulators via the PINE (Platform Independent Networked Environment) protocol. Configuration is driven entirely through environment variables, allowing users to customize connection targets, communication protocols, and runtime behavior without modifying code.\n\nThis reference documents all supported environment variables, their default values, acceptable ranges, and behavioral implications.\n\n---\n\n## Environment Variables Summary\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator identifier for socket path resolution |\n| `PINE_SLOT` | `28011` | PINE slot/port number for connection |\n| `PINE_HOST` | `127.0.0.1` | Host address for TCP connections |\n| `PINE_SOCKET_PATH` | auto-generated | Override Unix socket or TCP path |\n| `PINE_PIPELINE_BATCH` | `1` | Number of concurrent in-flight PINE requests |\n\n---\n\n## Connection Configuration\n\n### `PINE_TARGET`\n\nSpecifies the target emulator name, which determines the Unix socket file prefix on Linux/macOS systems.\n\n**Type:** string  \n**Default:** `pcsx2`  \n**Valid Values:** `pcsx2`, `rpcs3`, `duckstation`\n\n```mermaid\ngraph LR\n    A[PINE_TARGET] --> B{Platform?}\n    B -->|Linux/macOS| C[Unix Socket Path]\n    B -->|Windows| D[TCP Connection]\n    C --> E[\"<target>.sock.<slot>\"]\n    D --> F[\"127.0.0.1:<slot>\"]\n```\n\nOn Linux/macOS, the socket path follows the pattern `<target>.sock.<slot>`. The system resolves the directory using:\n\n1. `$XDG_RUNTIME_DIR` (Linux common)\n2. `$TMPDIR` (macOS common)\n3. `/tmp` (fallback)\n\n**Example:**\n\n```bash\nPINE_TARGET=pcsx2 PINE_SLOT=28011 mcp-pine\n# Linux socket: /run/user/1000/pcsx2.sock.28011\n```\n\n资料来源：[README.md:45-50]()\n\n### `PINE_SLOT`\n\nDefines the PINE slot number used for communication. This value serves as:\n\n- The TCP port number on Windows (`127.0.0.1:<slot>`)\n- The Unix socket suffix on Linux/macOS (`<target>.sock.<slot>`)\n\n**Type:** integer  \n**Default:** `28011`  \n**Valid Range:** 0–65535 (though PINE protocol reserves 0–255 for official slot semantics)\n\n```mermaid\ngraph TD\n    A[Emulator PINE Server] --> B{Slot Configured?}\n    B -->|Default 28011| C[PCSX2 Qt 1.7.x]\n    B -->|Custom Port| D[RPCS3 / Duckstation]\n    A --> E[PCSX2 Settings]\n    E --> F[Settings > Advanced > Enable PINE Server]\n```\n\n资料来源：[README.md:46-47]()\n\n### `PINE_HOST`\n\nSpecifies the hostname or IP address for TCP connections on Windows systems.\n\n**Type:** string  \n**Default:** `127.0.0.1`  \n**Valid Values:** Any valid IPv4/IPv6 address or hostname\n\nOn Windows, TCP is used exclusively instead of Unix sockets. This variable allows connection to remote emulators if needed.\n\n```typescript\n// Connection resolution logic (src/pine.ts)\nconst descriptor = resolveSocket(opts);\n// Returns { kind: \"tcp\", host, port } or { kind: \"unix\", path }\n```\n\n资料来源：[src/pine.ts:100-110]()\n\n### `PINE_SOCKET_PATH`\n\nProvides a complete override for the socket path, bypassing automatic resolution based on `PINE_TARGET` and `PINE_SLOT`.\n\n**Type:** string  \n**Default:** auto-generated  \n**Format:** Absolute path for Unix sockets, or `host:port` for TCP\n\nThis variable is useful for:\n\n- Custom socket locations\n- Docker containers with volume-mounted sockets\n- Testing with mock PINE servers\n\n资料来源：[package.json:5-10]()\n\n---\n\n## Runtime Behavior Configuration\n\n### `PINE_PIPELINE_BATCH`\n\nControls the number of concurrent in-flight PINE requests when performing bulk reads via `pine_read_range`.\n\n```mermaid\ngraph TD\n    A[pine_read_range call] --> B{How many steps?}\n    B --> C[Split into steps]\n    C --> D{PIPELINE_BATCH}\n    D -->|1 (default)| E[Serial execution<br/>Safe: no queue corruption]\n    D -->|2+| F[Batch execution<br/>⚠️ Risk: PCSX2 queue desync]\n    E --> G[~52ms for 4KB]\n    F --> H[Lower latency<br/>Potential reply misalignment]\n```\n\n**Type:** integer  \n**Default:** `1`  \n**Valid Range:** Positive integers\n\n| Value | Behavior | Latency | Risk Level |\n|-------|----------|---------|------------|\n| `1` | Fully serial execution | ~52ms for 4KB | None |\n| `2` | Batches of 2 concurrent requests | Lower | Low |\n| `>6` | Aggressive pipelining | Lowest | High (queue corruption) |\n\n#### Why Pipelining Can Break PCSX2\n\nPCSX2's PINE server has a **fragile request queue**. When more than approximately 6-9 requests are in-flight simultaneously, the server silently drops requests. This causes the reply pipeline to become desynchronized, and every subsequent request times out—even `pine_ping`.\n\n**Symptoms of queue corruption:**\n\n```\nPINE call timed out (10s) from pine_ping\n```\n\n**Recovery:** Complete PCSX2 restart required. Reconnecting alone does not fix the desync.\n\n资料来源：[src/pine.ts:70-85]()\n\n---\n\n## Connection Flow Architecture\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Client\n    participant Server as mcp-pine Server\n    participant Pine as PINE Client\n    participant Emu as Emulator PINE Server\n\n    MCP->>Server: Stdio connection\n    Server->>Pine: Connect via resolveSocket()\n    Note over Server,Pine: Platform detection<br/>TCP vs Unix socket\n\n    Pine->>Emu: Initial connection\n    Emu-->>Pine: Connected\n\n    loop Per tool call\n        MCP->>Server: CallToolRequest\n        Server->>Pine: Typed method (read8, write32, etc.)\n        Pine->>Emu: PINE binary frame\n        Emu-->>Pine: PINE reply frame\n        Pine-->>Server: Parsed result\n        Server-->>MCP: ToolResponse\n    end\n```\n\n### Socket Resolution Logic\n\n```mermaid\ngraph TD\n    A[resolveSocket options] --> B{Target platform?}\n    B -->|Windows| C[Use TCP]\n    B -->|Linux/macOS| D[Use Unix Socket]\n\n    C --> E[\"net.createConnection<br/>host:port\"]\n    D --> F{PINE_SOCKET_PATH set?}\n    F -->|Yes| G[\"Use custom path\"]\n    F -->|No| H[\"Build from TARGET + SLOT\"]\n    H --> I[XDG_RUNTIME_DIR]\n    H --> J[TMPDIR]\n    H --> K[/tmp fallback]\n\n    I --> L[\"<dir>/<target>.sock.<slot>\"]\n    J --> L\n    K --> L\n```\n\n资料来源：[src/pine.ts:95-120]()\n\n---\n\n## Timeout Configuration\n\nEach PINE call has a **10-second timeout** enforced by the client. This prevents the MCP server from hanging indefinitely if:\n\n- The emulator drops a reply\n- The PINE server becomes unresponsive\n- Network latency exceeds normal bounds\n\n**Implementation:**\n\n```typescript\n// From src/pine.ts\nprivate readonly TIMEOUT_MS = 10_000;\n\nconst result = await Promise.race([\n    this.call(Op.Read64, args),\n    new Promise((_, reject) =>\n        setTimeout(() => reject(new Error(\"PINE call timed out\")), TIMEOUT_MS)\n    )\n]);\n```\n\n资料来源：[src/pine.ts:25-30]()\n\n---\n\n## Environment Variable Precedence\n\nWhen multiple variables could affect the same aspect of connection, the following precedence applies:\n\n| Priority | Variable | Override Behavior |\n|----------|----------|-------------------|\n| 1 (highest) | `PINE_SOCKET_PATH` | Complete path override |\n| 2 | `PINE_HOST` + `PINE_SLOT` | TCP connection details |\n| 3 | `PINE_TARGET` + `PINE_SLOT` | Auto-generated Unix socket |\n\n---\n\n## Configuration Examples\n\n### PCSX2 (Default)\n\n```bash\n# Uses defaults: pcsx2.sock.28011 on Linux, 127.0.0.1:28011 on Windows\nmcp-pine\n```\n\n### RPCS3\n\n```bash\nPINE_TARGET=rpcs3 PINE_SLOT=28012 mcp-pine\n```\n\n### Duckstation\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=28013 mcp-pine\n```\n\n### Custom Socket Path\n\n```bash\nPINE_SOCKET_PATH=/tmp/custom-pine.sock.28011 mcp-pine\n```\n\n### Aggressive Pipelining (Not Recommended)\n\n```bash\nPINE_PIPELINE_BATCH=4 mcp-pine\n# ⚠️ May cause PCSX2 queue corruption\n```\n\n### Remote Connection\n\n```bash\nPINE_HOST=192.168.1.100 PINE_SLOT=28011 mcp-pine\n```\n\n---\n\n## Quick Reference Card\n\n| Scenario | Recommended Variables |\n|----------|----------------------|\n| PCSX2 on Linux | None (defaults work) |\n| PCSX2 on Windows | None (defaults work) |\n| RPCS3 | `PINE_TARGET=rpcs3` |\n| Duckstation | `PINE_TARGET=duckstation` |\n| Custom port | `PINE_SLOT=<port>` |\n| Docker/special socket | `PINE_SOCKET_PATH=<path>` |\n| Performance testing | `PINE_PIPELINE_BATCH=2` |\n| Debugging queue issues | `PINE_PIPELINE_BATCH=1` (default) |\n\n---\n\n## Error States and Diagnostics\n\n| Error Message | Cause | Fix |\n|---------------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running, PINE disabled, port mismatch | Verify emulator PINE settings |\n| `PINE FAIL response (0xFF)` | No game loaded, unmapped address | Load game, check address |\n| Reads return zeros | Unmapped memory region | Try `0x00100000` (EE RAM start) |\n| Values look corrupted | Endianness mismatch | PINE is little-endian |\n| `PINE call timed out (10s)` | Queue desync | Full PCSX2 restart required |\n\n资料来源：[README.md:80-95]()\n\n---\n\n<a id='memory-operations'></a>\n\n## Memory Operations\n\n### 相关页面\n\n相关主题：[Savestate Management](#savestate-management), [System Query Tools](#system-queries)\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</details>\n\n# Memory Operations\n\n## Overview\n\nMemory Operations in mcp-pine provide read and write access to the emulated PlayStation 2's (PS2) Emotion Engine (EE) address space through the PINE (Plugin Interface for Networked Emulation) protocol. These operations enable AI assistants and MCP clients to inspect and modify game state in real-time while an emulator runs.\n\nThe primary use cases include:\n\n- **Game state inspection** — reading RAM to discover health, score, position, or other variables\n- **Cheat development** — writing values to memory addresses to create or test cheats\n- **Debugging** — inspecting memory regions during gameplay to understand game logic\n- **Save state management** — snapshotting and restoring emulator state through specific slots\n\nMemory operations in mcp-pine are exposed as MCP tools that bridge the AI assistant to the underlying PINE protocol implementation in `src/pine.ts`.\n\n资料来源：[src/tools.ts:1-50]()\n\n## Architecture\n\n### Component Hierarchy\n\n```mermaid\ngraph TD\n    subgraph \"MCP Client Layer\"\n        A[\"AI Assistant / Claude\"]\n    end\n    \n    subgraph \"MCP Bridge (mcp-pine)\"\n        B[\"src/tools.ts<br/>Tool Definitions\"]\n        C[\"src/pine.ts<br/>PineClient\"]\n        D[\"PINE Protocol Encoder/Decoder\"]\n    end\n    \n    subgraph \"Transport Layer\"\n        E[\"Unix Socket<br/>Linux/macOS\"]\n        F[\"TCP Socket<br/>Windows\"]\n    end\n    \n    subgraph \"Emulator\"\n        G[\"PCSX2 / RPCS3 / Duckstation<br/>PINE Server\"]\n    end\n    \n    A --> B\n    B --> C\n    C --> D\n    D --> E\n    D --> F\n    E --> G\n    F --> G\n```\n\n### Request-Response Flow\n\n```mermaid\nsequenceDiagram\n    participant AI as AI Assistant\n    participant MCP as MCP Bridge\n    participant PC as PineClient\n    participant PINE as PINE Server\n    \n    AI->>MCP: pine_read32(0x00100000)\n    MCP->>PC: read32() call\n    PC->>PINE: Op.Read32 + addr (12 bytes)\n    PINE-->>PC: Reply frame (12 bytes)\n    PC-->>MCP: number value\n    MCP-->>AI: \"0x00100000: 1234 (0x4D2)\"\n```\n\n### Key Components\n\n| Component | File | Responsibility |\n|-----------|------|-----------------|\n| `PineClient` | `src/pine.ts` | Socket management, request queuing, protocol encoding/decoding |\n| Tool definitions | `src/tools.ts` | MCP tool schemas, parameter validation, response formatting |\n| Opcode enum | `src/pine.ts` | PINE protocol opcodes (Op.Read32, Op.Write8, etc.) |\n\n资料来源：[src/pine.ts:1-80]()\n\n## Read Operations\n\nmcp-pine provides four aligned read operations for accessing EE memory:\n\n| Tool | Width | Opcode | Alignment |\n|------|-------|--------|-----------|\n| `pine_read8` | 8-bit / 1 byte | `Op.Read8` | None required |\n| `pine_read16` | 16-bit / 2 bytes | `Op.Read16` | 2-byte |\n| `pine_read32` | 32-bit / 4 bytes | `Op.Read32` | 4-byte |\n| `pine_read64` | 64-bit / 8 bytes | `Op.Read64` | 8-byte |\n\nAll read operations return values as little-endian unsigned integers. The return format follows a consistent pattern: `ADDR_HEX: VAL_DEC (0xVAL_HEX)`.\n\n### Address Parameter\n\nThe `address` parameter for all read/write operations accepts an absolute byte address in the EE main address space:\n\n```\nAbsolute byte address in the EE main address space (NOT a per-domain offset).\nPass as a number; hex literals like 0x00200000 are fine.\n```\n\n**PS2 Memory Landmarks:**\n\n| Region | Address Range | Description |\n|--------|---------------|-------------|\n| EE Main RAM | `0x00100000` - `0x01FFFFFF` | Where 99% of game state lives |\n| IOP RAM | `0x1C000000`+ | Input/Output Processor memory |\n| Scratchpad | `0x70000000` - `0x70003FFF` | Fast 16KB scratchpad |\n\n资料来源：[src/tools.ts:30-45]()\n\n### Usage Examples\n\n```javascript\n// Read 32-bit value at game state pointer\npine_read32(0x00200000)\n\n// Read 8-bit byte for flag detection\npine_read8(0x00201004)\n\n// Read 64-bit EE pointer\npine_read64(0x00203000)\n```\n\n### Alignment Caveats\n\n> **Important:** PINE on PCSX2 does NOT enforce alignment. Unaligned multi-byte access returns whatever bytes are at the aligned address below, silently corrupting the value.\n\n| Operation | Required Alignment | Misaligned Behavior |\n|-----------|-------------------|---------------------|\n| `read8` | None | Correct |\n| `read16` | 2-byte | Returns wrong value silently |\n| `read32` | 4-byte | Returns wrong value silently |\n| `read64` | 8-byte | Returns wrong value silently |\n\nIf you need an unaligned multi-byte read, use `pine_read_range` and assemble the bytes yourself.\n\n资料来源：[src/tools.ts:30-40]()\n\n## Write Operations\n\nWrite operations modify memory in the emulated EE address space:\n\n| Tool | Width | Opcode | Value Encoding |\n|------|-------|--------|----------------|\n| `pine_write8` | 8-bit | `Op.Write8` | Number `0-255` |\n| `pine_write16` | 16-bit | `Op.Write16` | Number `0-65535` |\n| `pine_write32` | 32-bit | `Op.Write32` | Number `0-4294967295` |\n| `pine_write64` | 64-bit | `Op.Write64` | Decimal string `0-18446744073709551615` |\n\n### Destructive Behavior Notes\n\n- Writes **bypass TLB protection** and DMA mediation\n- Writes to **read-only regions** (BIOS, IOP ROM) are silently dropped\n- **No undo mechanism** — changes are permanent until emulator restart or explicit restoration\n\n### 64-bit Value Encoding\n\n64-bit values use decimal string encoding because JavaScript's number type cannot represent the full `uint64` range (max safe integer is `2^53 - 1`):\n\n```javascript\n// Write maximum 64-bit value\npine_write64(0x00200000, \"18446744073709551615\")\n```\n\nThe schema enforces this with `pattern: \"^[0-9]+$\"` to reject non-numeric input.\n\n资料来源：[src/tools.ts:140-180]()\n\n### Usage Examples\n\n```javascript\n// Infinite health cheat\npine_write32(0x00201000, 9999)\n\n// Set RGBA color (packed 32-bit)\npine_write32(0x00300000, 0xFFFFFFFF)\n\n// Write large 64-bit ID\npine_write64(0x00204000, \"12345678901234567\")\n```\n\n## Bulk Read Operation\n\n### `pine_read_range`\n\nReads up to 4096 consecutive bytes in a single tool call. Since PINE has no native bulk read opcode, this is implemented client-side as a serial sequence of aligned reads.\n\n**Implementation Strategy:**\n\n```mermaid\ngraph TD\n    A[\"read_range(addr, length)\"] --> B[\"Calculate read steps\"]\n    B --> C{\"Remaining bytes?\"}\n    C -->|≥8 & addr%8==0| D[\"read64\"]\n    C -->|≥4 & addr%4==0| E[\"read32\"]\n    C -->|≥2 & addr%2==0| F[\"read16\"]\n    C -->|else| G[\"read8\"]\n    D --> H[\"cursor += 8\"]\n    E --> I[\"cursor += 4\"]\n    F --> J[\"cursor += 2\"]\n    G --> K[\"cursor += 1\"]\n    H --> C\n    I --> C\n    J --> C\n    K --> C\n    C -->|0| L[\"Return Buffer\"]\n```\n\n**Performance Characteristics:**\n\n| Configuration | Measured Time (4KB) |\n|---------------|---------------------|\n| Serial (`PINE_PIPELINE_BATCH=1`) | ~52 ms |\n| With pipelining (`PINE_PIPELINE_BATCH=2+`) | Lower latency, higher risk |\n\n> Measured on PCSX2 v2.6.3 over loopback TCP.\n\n### Pipelining and PCSX2 Fragility\n\nPCSX2's PINE server has a **fragile request queue**: dropping any single request silently desyncs the reply pipeline, causing all subsequent requests to timeout until the emulator restarts.\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant PCSX2 as PCSX2 PINE Server\n    \n    Note over Client,PCSX2: Normal operation (≤6 in-flight)\n    Client->>PCSX2: Request 1\n    Client->>PCSX2: Request 2\n    Client->>PCSX2: Request 3\n    PCSX2-->>Client: Reply 1\n    PCSX2-->>Client: Reply 2\n    PCSX2-->>Client: Reply 3\n    \n    Note over Client,PCSX2: Pipeline saturation (≥7 in-flight)\n    Client->>PCSX2: Request 1\n    Client->>PCSX2: Request 2\n    Client->>PCSX2: Request 3\n    Client->>PCSX2: Request 4\n    Client->>PCSX2: Request 5\n    Client->>PCSX2: Request 6\n    Client->>PCSX2: Request 7\n    PCSX2->>PCSX2: Dropped!\n    Note over Client,PCSX2: All subsequent replies misaligned!\n```\n\n**Recommendation:** Use serial mode by default. Only set `PINE_PIPELINE_BATCH=2` or higher if you can tolerate occasional emulator restarts.\n\n资料来源：[src/pine.ts:60-100]()\n\n## Save State Operations\n\nThe save state operations provide snapshot and restore functionality through PINE slots:\n\n| Tool | Opcode | Description |\n|------|--------|-------------|\n| `pine_save_state` | `Op.SaveState` | Save current emulator state to slot |\n| `pine_load_state` | `Op.LoadState` | Load emulator state from slot |\n\n### Slot Numbering\n\n- **Range:** 0-255\n- **PCSX2 convention:** Slots 0-9 mapped to F1-F10 in GUI\n- **Storage location:** Per-game savestate folder\n\n### Slot File Naming\n\n```\n<serial> (<crc>).<slot>.p2s\n```\n\nExample: `SCUS-97211 (ABC12345).3.p2s`\n\n资料来源：[src/tools.ts:180-220]()\n\n## Error Handling\n\n### Connection Failures\n\n| Error | Cause | Fix |\n|-------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running, PINE disabled, wrong slot | Check `PINE_SLOT` setting |\n| `PINE FAIL response (0xFF)` | Emulator rejected request | Ensure game loaded, check address validity |\n| Timeout (10s) | Reply dropped | Restart emulator if PCSX2 PINE is wedged |\n\n### Data Corruption\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| Reads return zeros | Address in unallocated region | Try `0x00100000` first |\n| Values look corrupted | Wrong endianness interpretation | PINE returns little-endian |\n| Silent wrong values | Unaligned access | Align addresses or use `read_range` |\n\n资料来源：[README.md:80-100]()\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator name prefix for Unix socket path |\n| `PINE_SLOT` | `28011` | PINE slot / port number |\n| `PINE_PIPELINE_BATCH` | `1` | Parallel request count (use with caution) |\n\n### Socket Path Resolution\n\n```mermaid\ngraph TD\n    A[\"Start\"] --> B{\"OS?\"}\n    B -->|Windows| C[\"TCP 127.0.0.1:<PINE_SLOT>\"]\n    B -->|Linux/macOS| D{\"XDG_RUNTIME_DIR set?\"}\n    D -->|Yes| E[\"$XDG_RUNTIME_DIR/<PINE_TARGET>.sock.<PINE_SLOT>\"]\n    D -->|No| F{\"TMPDIR set?\"}\n    F -->|Yes| G[\"$TMPDIR/<PINE_TARGET>.sock.<PINE_SLOT>\"]\n    F -->|No| H[\"/tmp/<PINE_TARGET>.sock.<PINE_SLOT>\"]\n```\n\n资料来源：[src/pine.ts:20-50]()\n\n## Tool Reference Summary\n\n| Tool | Input Schema | Return Format |\n|------|--------------|---------------|\n| `pine_ping` | None | `OK — emulator: <version>` |\n| `pine_get_info` | None | Multi-line status with title, serial, CRC, version |\n| `pine_get_status` | None | `Status: running\\|paused\\|shutdown` |\n| `pine_read8` | `{address: integer}` | `ADDR_HEX: VAL (0xVAL_HEX)` |\n| `pine_read16` | `{address: integer}` | `ADDR_HEX: VAL (0xVAL_HEX)` |\n| `pine_read32` | `{address: integer}` | `ADDR_HEX: VAL (0xVAL_HEX)` |\n| `pine_read64` | `{address: integer}` | `ADDR_HEX: VAL (0xVAL_HEX)` |\n| `pine_read_range` | `{address: integer, length: 1-4096}` | Raw bytes (base64 or hex) |\n| `pine_write8` | `{address: integer, value: number}` | `Wrote VAL → ADDR` |\n| `pine_write16` | `{address: integer, value: number}` | `Wrote VAL → ADDR` |\n| `pine_write32` | `{address: integer, value: number}` | `Wrote VAL → ADDR` |\n| `pine_write64` | `{address: integer, value: string}` | `Wrote VAL → ADDR` |\n| `pine_save_state` | `{slot: 0-255}` | `Saved state to slot <N>` |\n| `pine_load_state` | `{slot: 0-255}` | `Loaded state from slot <N>` |\n\n资料来源：[src/tools.ts:50-250]()\n\n---\n\n<a id='savestate-management'></a>\n\n## Savestate Management\n\n### 相关页面\n\n相关主题：[Memory Operations](#memory-operations), [System Query Tools](#system-queries)\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</details>\n\n# Savestate Management\n\n## Overview\n\nSavestate Management provides MCP clients with the ability to programmatically save and load emulator states for PlayStation 2 games running in PCSX2 (or other PINE-compatible emulators). This enables workflows such as checkpoint-based experimentation, automated testing, and stateful memory analysis where the user can snapshot game state, perform operations, and restore to a known baseline.\n\nThe feature is implemented through two MCP tools (`pine_save_state` and `pine_load_state`) that wrap the PINE protocol's `SaveState` and `LoadState` opcodes. These tools interact directly with the emulator's running instance, writing savestate files to the emulator's native storage location.\n\n## Architecture\n\n### Component Overview\n\n```mermaid\ngraph TD\n    A[\"MCP Client<br/>(Claude Code, Claude Desktop)\"] --> B[\"mcp-pine Bridge\"]\n    B --> C[\"PineClient<br/>(src/pine.ts)\"]\n    C --> D[\"PINE Protocol<br/>(TCP/Unix Socket)\"]\n    D --> E[\"PCSX2 PINE Server\"]\n    E --> F[\"Savestate Files<br/>(~/.config/PCSX2/sstates)\"]\n    \n    G[\"src/tools.ts\"] -->|Tool Definitions| B\n```\n\n### Savestate Workflow\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Client\n    participant Bridge as mcp-pine Bridge\n    participant Pine as PineClient\n    participant Emu as PCSX2 PINE Server\n    participant FS as File System\n\n    Note over MCP, FS: Save State Flow\n    MCP->>Bridge: pine_save_state(slot: N)\n    Bridge->>Pine: saveState(slot)\n    Pine->>Emu: PINE SaveState opcode + slot byte\n    Emu->>FS: Write <serial>.<crc>.<slot>.p2s\n    Emu-->>Pine: PINE OK response\n    Pine-->>Bridge: Promise resolves\n    Bridge-->>MCP: \"State saved to slot N\"\n\n    Note over MCP, FS: Load State Flow\n    MCP->>Bridge: pine_load_state(slot: N)\n    Bridge->>Pine: loadState(slot)\n    Pine->>Emu: PINE LoadState opcode + slot byte\n    Emu->>FS: Read <serial>.<crc>.<slot>.p2s\n    Emu-->>Pine: PINE OK response\n    Pine-->>Bridge: Promise resolves\n    Bridge-->>MCP: \"State loaded from slot N\"\n```\n\n## MCP Tools\n\n### pine_save_state\n\nSaves the current emulator state to a specified slot.\n\n| Property | Value |\n|----------|-------|\n| **Tool Name** | `pine_save_state` |\n| **Source** | [src/tools.ts:1-20](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) |\n\n**Parameters:**\n\n| Parameter | Type | Constraints | Description |\n|-----------|------|-------------|-------------|\n| `slot` | integer | 0-255 | Save state slot number |\n\n**Description (from source):**\n\n```\nPURPOSE: Atomically snapshot the full emulator state (CPU registers, RAM, VRAM, \n         SPU, device states) to the specified slot and persist it to disk. USAGE: \n         Save checkpoints before risky operations (memory edits, patch applications, \n         speedrun route branches). Use pine_load_state to restore. Slot 0 is \n         conventional for \"current run\", slots 1-9 map to F1-F10 in PCSX2's GUI. \n         BEHAVIOR: DESTRUCTIVE — overwrites any existing savestate in the same \n         slot without prompting. Requires a game to be loaded; returns PINE FAIL \n         if invoked from the BIOS. Emulator retains the saved data across sessions \n         (survives emulator restart). RETURNS: \"State saved to slot N\" on success.\n```\n\n### pine_load_state\n\nRestores the emulator state from a specified slot.\n\n| Property | Value |\n|----------|-------|\n| **Tool Name** | `pine_load_state` |\n| **Source** | [src/tools.ts:1-20](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts) |\n\n**Parameters:**\n\n| Parameter | Type | Constraints | Description |\n|-----------|------|-------------|-------------|\n| `slot` | integer | 0-255 | Save state slot number |\n\n**Description (from source):**\n\n```\nPURPOSE: Atomically restore the full emulator state (CPU registers, RAM, VRAM, \n         SPU, device states) from a previously saved slot. USAGE: Restore after \n         experimental memory edits, reset to a known checkpoint, or implement \n         trial-and-error workflows (save → modify → load → try again). \n         BEHAVIOR: DESTRUCTIVE — immediately overwrites all emulator state with \n         the slot's contents. Does not verify the slot contains a valid savestate \n         before restoring (PINE FAIL if slot is empty/missing). The restored state \n         reflects the exact game position at the time of save, including any \n         unsaved progress. RETURNS: \"State loaded from slot N\" on success.\n```\n\n## Implementation\n\n### PineClient Methods\n\nThe `PineClient` class in `src/pine.ts` implements the savestate operations:\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**资料来源:** [src/pine.ts:1-10](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n### Tool Registration\n\nThe tools are registered in `registerTools()` which handles the MCP request routing:\n\n```typescript\ncase \"pine_save_state\": {\n  await pine.saveState(p.slot as number);\n  return ok(`State saved to slot ${p.slot}`);\n}\ncase \"pine_load_state\": {\n  await pine.loadState(p.slot as number);\n  return ok(`State loaded from slot ${p.slot}`);\n}\n```\n\n**资料来源:** [src/tools.ts:1-20](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n## Slot Management\n\n### Slot Number Conventions\n\n| Slot Range | Conventional Use | GUI Mapping |\n|------------|------------------|-------------|\n| 0 | Current run / temporary checkpoint | Manual |\n| 1-9 | Quick save slots | F1-F10 |\n| 10-99 | Scene-specific saves | Named folders |\n| 100-255 | Long-term snapshots | Archive |\n\nPCSX2 conventionally uses slots 0-9 mapped to function keys F1-F10 in the GUI. The PINE protocol accepts the full 0-255 range, but slots beyond 9 are only accessible programmatically.\n\n### File Location\n\nSavestate files are stored in the emulator's per-game savestate folder:\n\n| Platform | Path |\n|----------|------|\n| Linux | `~/.config/PCSX2/sstates/` |\n| macOS | `~/.config/PCSX2/sstates/` |\n| Windows | `%USERPROFILE%\\Documents\\PCSX2\\sstates\\` |\n\n**Filename format:** `<serial> (<crc>).<slot>.p2s`\n\n## Usage Patterns\n\n### Checkpoint Workflow\n\n```mermaid\ngraph LR\n    A[Game Running] --> B[\"pine_save_state<br/>slot=0\"]\n    B --> C[Perform Memory Edits]\n    C --> D{Results OK?}\n    D -->|Yes| E[Continue Playing]\n    D -->|No| F[\"pine_load_state<br/>slot=0\"]\n    F --> A\n```\n\n### Memory Analysis Workflow\n\n```mermaid\ngraph TD\n    A[Save Baseline] -->|\"slot=0\"| B\n    B[Find Target Address] -->|\"pine_read32\"| C\n    C[Edit Memory] -->|\"pine_write32\"| D\n    D[Verify Change] -->|\"pine_read32\"| E\n    E{Correct?} -->|Yes| F[Continue]\n    E{No} -->|\"pine_load_state slot=0\"| B\n```\n\n### Example Tool Calls\n\n**Save state:**\n```json\n{\n  \"name\": \"pine_save_state\",\n  \"arguments\": { \"slot\": 0 }\n}\n```\n\n**Load state:**\n```json\n{\n  \"name\": \"pine_load_state\",\n  \"arguments\": { \"slot\": 0 }\n}\n```\n\n## Error Handling\n\n### Common Failure Modes\n\n| Error | Cause | Fix |\n|-------|-------|-----|\n| PINE FAIL response | No game loaded, or slot is invalid | Load a game before saving |\n| Slot contains garbage | Corrupted savestate file | Delete file and re-save |\n| Load restores wrong game | Serial/CRC mismatch | Use correct game or different slot |\n\n### Connection Requirements\n\nThe emulator must be running with PINE enabled:\n\n1. Launch PCSX2 (1.7.x Qt or newer)\n2. Navigate to **Settings → Advanced → Enable PINE Server**\n3. Default slot is **28011** (configurable via `PINE_SLOT`)\n\n**资料来源:** [README.md:1-20](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Configuration\n\nSavestate operations are affected by the following environment variables:\n\n| Variable | Default | Effect |\n|----------|---------|--------|\n| `PINE_SLOT` | `28011` | Sets the PINE slot used for communication |\n| `PINE_TARGET` | `pcsx2` | Emulator name prefix for Unix socket path |\n| `PINE_TIMEOUT` | `10000` (ms) | Per-call timeout; affects savestate operations |\n\n## Related Tools\n\n| Tool | Purpose |\n|------|---------|\n| `pine_get_info` | Get game metadata before saving (title, serial, CRC) |\n| `pine_get_status` | Check if emulator is running/paused before operations |\n| `pine_read_*` | Read memory from restored state |\n| `pine_write_*` | Modify memory after loading a state |\n\n## See Also\n\n- [mcp-mgba](https://github.com/dmang-dev/mcp-mgba) — sister MCP server for mGBA with button input support\n- [PINE protocol spec](https://github.com/GovanifY/pine) — underlying IPC standard\n\n---\n\n<a id='system-queries'></a>\n\n## System Query Tools\n\n### 相关页面\n\n相关主题：[Memory Operations](#memory-operations), [Savestate Management](#savestate-management)\n\n<details>\n<summary>Relevant Source Files</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</details>\n\n# System Query Tools\n\nThe System Query Tools in mcp-pine provide MCP (Model Context Protocol) clients with a comprehensive interface to query and interact with PINE-enabled PlayStation 2 emulators. These tools expose low-level emulator introspection capabilities—including game metadata retrieval, memory reading/writing, and save state management—through the standardized MCP tool interface.\n\n## Overview\n\nmcp-pine bridges the gap between AI assistants (primarily Claude) and PlayStation 2 emulators by implementing the PINE (Platform for Interactive Nintendo/Network Environments) protocol. The System Query Tools form the public API layer that MCP clients interact with.\n\n### Architecture\n\n```mermaid\ngraph TD\n    subgraph \"MCP Client Layer\"\n        A[Claude / MCP Host]\n    end\n    \n    subgraph \"mcp-pine Bridge\"\n        B[tools.ts<br/>Tool Definitions]\n        C[pine.ts<br/>PineClient]\n    end\n    \n    subgraph \"Emulator Layer\"\n        D[PCSX2 / RPCS3 / Duckstation]\n    end\n    \n    A -->|CallToolRequest| B\n    B -->|PINE Protocol| C\n    C -->|TCP / Unix Socket| D\n    \n    style B fill:#f9f,color:#000\n    style C fill:#9ff,color:#000\n```\n\n### Tool Categories\n\n| Category | Tools | Purpose |\n|----------|-------|---------|\n| **Connectivity** | `pine_ping` | Verify emulator connection and retrieve version |\n| **Introspection** | `pine_get_info`, `pine_get_status` | Query game metadata and emulator state |\n| **Memory Read** | `pine_read8`, `pine_read16`, `pine_read32`, `pine_read64`, `pine_read_range` | Read from emulator's EE address space |\n| **Memory Write** | `pine_write8`, `pine_write16`, `pine_write32`, `pine_write64` | Write to emulator's memory |\n| **State Management** | `pine_save_state`, `pine_load_state` | Manipulate emulator save states |\n\n资料来源：[src/tools.ts:47-140]()\n\n## Connectivity & Introspection\n\n### pine_ping\n\nA lightweight health check that retrieves the emulator's PINE protocol version.\n\n```typescript\n{\n  name: \"pine_ping\",\n  description:\n    \"PURPOSE: Verify connectivity to the emulator's PINE server and retrieve its version string. \" +\n    \"USAGE: Call first when starting a session or debugging connection issues. Unlike pine_get_info, \" +\n    \"this makes only one PINE round-trip (Status opcode) — fastest way to confirm the link is alive. \" +\n    \"BEHAVIOR: No side effects. Issues PINE Version opcode (0x08). Times out after ~10s if the \" +\n    \"emulator is unresponsive or the PINE queue is desynced. \" +\n    \"RETURNS: 'OK — emulator: VERSION_STRING'.\",\n  inputSchema: { type: \"object\", properties: {} },\n}\n```\n\n资料来源：[src/tools.ts:48-54]()\n\n**Returns:** `OK — emulator: <version_string>`\n\n### pine_get_info\n\nRetrieves comprehensive game and emulator metadata in a single batched call.\n\n```typescript\n{\n  name: \"pine_get_info\",\n  description:\n    \"PURPOSE: Fetch all available game metadata (title, serial, disc CRC, game version, run state) in one tool call. \" +\n    \"USAGE: Use at session start to identify the loaded game. For repeated status-only checks, pine_get_status is cheaper (1 opcode vs 5). \" +\n    \"BEHAVIOR: No side effects — pure reads. Batches PINE opcodes: Title (0x01), ID (0x02), UUID (0x03), GameVersion (0x05), Status (0x0F). \" +\n    \"Each field falls back to '(unavailable)' if the emulator returns PINE FAIL. \" +\n    \"RETURNS: Multi-line string with Title, Serial, Disc CRC, Game version, Status.\",\n  inputSchema: { type: \"object\", properties: {} },\n}\n```\n\n资料来源：[src/tools.ts:56-62]()\n\n**Implementation:**\n\n```typescript\ncase \"pine_get_info\": {\n  const [title, id, uuid, gameVer, status] = await Promise.all([\n    pine.getTitle().catch(() => \"(unavailable)\"),\n    pine.getId().catch(() => \"(unavailable)\"),\n    pine.getUuid().catch(() => \"(unavailable)\"),\n    pine.getGameVersion().catch(() => \"(unavailable)\"),\n    pine.getStatus(),\n  ]);\n  return ok(\n    `Title:        ${title}\\n` +\n    `Serial:       ${id}\\n` +\n    `Disc CRC:     ${uuid}\\n` +\n    `Game version: ${gameVer}\\n` +\n    `Status:       ${status}`,\n  );\n}\n```\n\n资料来源：[src/tools.ts:16-27]()\n\n**Returns:**\n```\nTitle:        <game title>\nSerial:       <game serial>\nDisc CRC:     <disc CRC UUID>\nGame version: <version string>\nStatus:       <running|paused|shutdown|unknown>\n```\n\n### pine_get_status\n\nQueries only the emulator's run state, optimized for repeated checks.\n\n```typescript\n{\n  name: \"pine_get_status\",\n  description:\n    \"PURPOSE: Get the emulator run state — 'running', 'paused', 'shutdown', or 'unknown'. \" +\n    \"USAGE: Cheap (1 PINE round-trip) check before timing-sensitive sequences — writes work while paused but only take visible effect after unpause. \" +\n    \"For game metadata (title, serial, CRC) use pine_get_info. PINE has no pause/resume opcode; this tool only reports state. \" +\n    \"BEHAVIOR: No side effects. Issues PINE Status opcode (0x0F), decodes the 32-bit response (0=running, 1=paused, 2=shutdown). \" +\n    \"RETURNS: 'Status: STATE' where STATE ∈ {running, paused, shutdown, unknown}.\",\n  inputSchema: { type: \"object\", properties: {} },\n}\n```\n\n资料来源：[src/tools.ts:95-101]()\n\n**Status Mapping:**\n\n| PINE Response | Emulator Status |\n|---------------|-----------------|\n| `0` | `running` |\n| `1` | `paused` |\n| `2` | `shutdown` |\n| Other | `unknown` |\n\n资料来源：[src/pine.ts:20-22]()\n\n## Memory Read Operations\n\n### Single-Value Reads\n\nThe `pine_read8`, `pine_read16`, `pine_read32`, and `pine_read64` tools read fixed-width values from the emulator's EE (Emotion Engine) address space.\n\n```typescript\ncase \"pine_read8\":  return ok(`${addrHex(addr())}: ${fmtHex(await pine.read8(addr()))}`);\ncase \"pine_read16\": return ok(`${addrHex(addr())}: ${fmtHex(await pine.read16(addr()))}`);\ncase \"pine_read32\": return ok(`${addrHex(addr())}: ${fmtHex(await pine.read32(addr()))}`);\ncase \"pine_read64\": return ok(`${addrHex(addr())}: ${fmtHex(await pine.read64(addr()))}`);\n```\n\n资料来源：[src/tools.ts:29-32]()\n\n#### Address Parameter\n\n```typescript\nconst ADDRESS_PARAM_DESC = (widthBytes: number) => {\n  const alignNote = widthBytes === 1\n    ? \"No alignment requirement for byte access.\"\n    : `MUST be ${widthBytes}-byte aligned (address % ${widthBytes} === 0). PINE on PCSX2 does NOT enforce ` +\n      `alignment — unaligned ${widthBytes * 8}-bit access typically returns whatever bytes are at the ` +\n      `aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, ` +\n      `use pine_read_range and assemble the bytes yourself.`;\n  return (\n    `Absolute byte address in the EE main address space (NOT a per-domain offset).\n    ...\n    Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives).`\n  );\n};\n```\n\n资料来源：[src/tools.ts:1-18]()\n\n#### Alignment Requirements\n\n| Tool | Width | Alignment | Corruption Risk |\n|------|-------|-----------|-----------------|\n| `pine_read8` | 1 byte | None | None |\n| `pine_read16` | 2 bytes | 2-byte | Silently returns wrong value |\n| `pine_read32` | 4 bytes | 4-byte | Silently returns wrong value |\n| `pine_read64` | 8 bytes | 8-byte | Silently returns wrong value |\n\n资料来源：[src/tools.ts:3-9]()\n\n#### Tool Descriptions\n\n**pine_read8**\n```typescript\ndescription:\n  \"PURPOSE: Read an unsigned 8-bit byte from the emulator's EE address space at the given absolute address. \" +\n  \"USAGE: Use for single-byte fields — status flags, counters, 8-bit enums, character bytes...\"\n```\n\n**pine_read16**\n```typescript\ndescription:\n  \"PURPOSE: Read an unsigned 16-bit little-endian value from the emulator's EE address space...\"\n```\n\n**pine_read32**\n```typescript\ndescription:\n  \"PURPOSE: Read an unsigned 32-bit little-endian value from the emulator's EE address space...\" +\n  \"little-endian (LSB at `address`, MSB at `address+3`). Address MUST be 4-byte aligned...\"\n```\n\n**pine_read64**\n```typescript\ndescription:\n  \"PURPOSE: Read an unsigned 64-bit little-endian value from the emulator's EE address space...\" +\n  \"The PS2 EE is a 128-bit MIPS (Emotion Engine), and a lot of game state genuinely lives in 64-bit slots...\"\n```\n\n资料来源：[src/tools.ts:103-134]()\n\n**Returns Format:** `ADDR_HEX: VAL_DEC (0xVAL_HEX)`\n\n**64-bit Value Encoding:** Due to JavaScript's number precision limit (2^53), 64-bit values are returned as decimal strings to preserve full precision.\n\n### pine_read_range (Bulk Read)\n\nReads a contiguous byte span up to 4096 bytes in a single tool call.\n\n```typescript\n{\n  name: \"pine_read_range\",\n  description:\n    \"PURPOSE: Read a contiguous byte span (1-4096 bytes) from the emulator's EE address space in one tool call. \" +\n    \"USAGE: Use for structs, strings, buffers, or any multi-byte region. Prefer over multiple single reads to minimize round-trips (1 call vs N). \" +\n    \"BEHAVIOR: No side effects — pure read. Internally dispatches read64/read32/read16/read8 calls, choosing the largest aligned width at each step...\",\n}\n```\n\n资料来源：[src/tools.ts:136-140]()\n\n#### Implementation\n\n```typescript\nasync readRange(address: number, length: number): Promise<Buffer> {\n  const out = Buffer.alloc(length);\n  let cursor = address;\n  let outOffset = 0;\n  let remaining = length;\n  \n  while (remaining > 0) {\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    steps.push({ op: n, addr: cursor, outOffset });\n    cursor    += n;\n    outOffset += n;\n    remaining -= n;\n  }\n  // ...\n}\n```\n\n资料来源：[src/pine.ts:24-45]()\n\n#### Pipelining Behavior\n\n```mermaid\ngraph LR\n    A[read_range call] --> B{env: PINE_PIPELINE_BATCH}\n    B -->|1| C[Fully Serial]\n    B -->|2+| D[Batched Pipeline]\n    C --> E[Safe<br/>~52ms for 4KB]\n    D --> F[Fast but risky<br/>May desync PCSX2]\n```\n\n资料来源：[src/pine.ts:47-60]()\n\n**Performance:** ~52 ms for full 4096-byte read on PCSX2 v2.6.3 over loopback TCP.\n\n**Pipeline Warning:** PCSX2's PINE server has a fragile request queue. Dropping ANY request (occurs with ~7+ in-flight requests) desyncs the reply pipeline, causing all subsequent requests to timeout. Default is fully serial (`PINE_PIPELINE_BATCH=1`).\n\n## Memory Write Operations\n\n### pine_write8 through pine_write64\n\nWrite fixed-width little-endian values to the emulator's EE address space.\n\n```typescript\ncase \"pine_write8\": {\n  await pine.write8(addr(), p.value as number);\n  return ok(`Wrote ${fmtHex(p.value as number)} → ${addrHex(addr())}`);\n}\ncase \"pine_write16\": {\n  await pine.write16(addr(), p.value as number);\n  return ok(`Wrote ${fmtHex(p.value as number)} → ${addrHex(addr())}`);\n}\ncase \"pine_write32\": {\n  await pine.write32(addr(), p.value as number);\n  return ok(`Wrote ${fmtHex(p.value as number)} → ${addrHex(addr())}`);\n}\n```\n\n资料来源：[src/tools.ts:34-41]()\n\n#### Write Tool Parameters\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `address` | integer | Absolute byte address in EE address space |\n| `value` | integer | Value to write (decimal or hex) |\n\n#### Alignment Requirements\n\nSame as read operations—multi-byte writes must be aligned, or data corruption occurs silently.\n\n#### Behavior Notes\n\n- **DESTRUCTIVE:** Overwrites existing memory contents\n- Side effects persist after the call completes\n- Writes work while emulator is paused but changes only take effect after unpause\n- Returns PINE FAIL on unmapped addresses\n\n资料来源：[src/tools.ts:75-82]()\n\n## Save State Management\n\n### pine_save_state\n\nSaves the current emulator state to a numbered slot.\n\n```typescript\n{\n  name: \"pine_save_state\",\n  description:\n    \"PURPOSE: Capture a full emulator snapshot and write it to a numbered save-state slot. \" +\n    \"USAGE: Use before experimental memory writes or to bookmark a checkpoint for later restoration. \" +\n    \"Save states are emulator-process snapshots — they persist across emulator restarts. \" +\n    \"BEHAVIOR: DESTRUCTIVE: Overwrites any existing state in the target slot. Issues PINE SaveState opcode (0x10). \" +\n    \"Slot files are stored in PCSX2's per-game savestate folder...\",\n  inputSchema: {\n    type: \"object\",\n    required: [\"slot\"],\n    properties: {\n      slot: { type: \"integer\", minimum: 0, maximum: 255, description: SLOT_PARAM_DESC },\n    },\n    additionalProperties: false,\n  },\n}\n```\n\n资料来源：[src/tools.ts:143-152]()\n\n#### Slot Parameter\n\n```typescript\nconst SLOT_PARAM_DESC =\n  \"Save state slot number (0-255). PCSX2 conventionally uses slots 0-9 (mapped to F1-F10 in the GUI), \" +\n  \"but the PINE protocol accepts the full 0-255 range. Slot files live in PCSX2's per-game savestate \" +\n  \"folder (typically %USERPROFILE%/Documents/PCSX2/sstates on Windows, ~/.config/PCSX2/sstates on Linux) \" +\n  \"with filenames like '<serial> (<crc>).<slot>.p2s'. Slot numbers are independent of any path.\";\n```\n\n资料来源：[src/tools.ts:21-25]()\n\n### pine_load_state\n\nRestores the emulator state from a numbered slot.\n\n```typescript\n{\n  name: \"pine_load_state\",\n  description:\n    \"PURPOSE: Load a previously saved emulator snapshot from a save-state slot. \" +\n    \"USAGE: Use to restore a checkpoint (e.g., after experimental memory writes that didn't work as expected). \" +\n    \"BEHAVIOR: DESTRUCTIVE: Replaces the current running state with the saved snapshot. \" +\n    \"Issues PINE LoadState opcode (0x11). Returns PINE FAIL if the slot is empty or corrupted.\",\n  inputSchema: {\n    type: \"object\",\n    required: [\"slot\"],\n    properties: {\n      slot: { type: \"integer\", minimum: 0, maximum: 255, description: SLOT_PARAM_DESC },\n    },\n    additionalProperties: false,\n  },\n}\n```\n\n资料来源：[src/tools.ts:154-163]()\n\n#### Implementation\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}\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资料来源：[src/pine.ts:15-20]()\n\n## Tool Registration\n\nTools are registered with the MCP server through `registerTools()`:\n\n```typescript\nexport function registerTools(server: Server, pine: PineClient): void {\n  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));\n\n  server.setRequestHandler(CallToolRequestSchema, async (req) => {\n    const { name, arguments: args = {} } = req.params;\n    const p = args as Record<string, unknown>;\n    const addr = () => p.address as number;\n\n    switch (name) {\n      case \"pine_ping\": {\n        const v = await pine.getVersion();\n        return ok(`OK — emulator: ${v}`);\n      }\n      // ... other cases\n    }\n  });\n}\n```\n\n资料来源：[src/tools.ts:158-173]()\n\n### Tool Definition Schema\n\nEach tool follows a consistent structure:\n\n| Field | Purpose |\n|-------|---------|\n| `name` | Unique identifier for the tool |\n| `description` | PURPOSE / USAGE / BEHAVIOR / RETURNS template |\n| `inputSchema` | JSON Schema for parameters |\n\n## Error Handling\n\nAll tools implement consistent error handling:\n\n| Error Condition | Response |\n|-----------------|----------|\n| Connection failure | Tool call rejects with error |\n| PINE FAIL response | Error message returned |\n| Timeout (10s default) | Tool call rejects |\n| Invalid address | PINE FAIL response |\n\n```typescript\nconst ok = (text: string) => {\n  return { content: [{ type: \"text\" as const, text }] };\n};\n```\n\n资料来源：[src/tools.ts:144-147]()\n\n## Configuration\n\n| Environment Variable | Default | Purpose |\n|---------------------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator name for socket path |\n| `PINE_SLOT` | `28011` | PINE slot / port number |\n| `PINE_PIPELINE_BATCH` | `1` | Read range batch size |\n\n资料来源：[README.md](./README.md)\n\n---\n\n<a id='development-guide'></a>\n\n## Development Guide\n\n### 相关页面\n\n相关主题：[Troubleshooting Guide](#troubleshooting), [Project Overview](#overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [package.json](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\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- [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</details>\n\n# Development Guide\n\n## Overview\n\nThis guide covers the development workflow, architecture, and contribution guidelines for `mcp-pine`, an MCP (Model Context Protocol) server that bridges AI assistants like Claude to PlayStation 2/3 emulators via the PINE protocol.\n\nThe project enables read/write access to emulator memory, save state management, and game information retrieval through standardized MCP tool calls.\n\n## Project Structure\n\n```\nmcp-pine/\n├── src/\n│   ├── index.ts       # Entry point, MCP server initialization\n│   ├── pine.ts        # PineClient - low-level PINE protocol implementation\n│   └── tools.ts       # MCP tool definitions and handlers\n├── .scratch/\n│   └── smoke.cjs      # Quick smoke test script\n├── package.json\n├── tsconfig.json\n└── Dockerfile\n```\n\n### Key Modules\n\n| Module | Responsibility |\n|--------|----------------|\n| `src/index.ts` | MCP server bootstrap, connection lifecycle, signal handling |\n| `src/pine.ts` | Socket communication, PINE opcodes, read/write operations |\n| `src/tools.ts` | Tool definitions, input schemas, result formatting |\n\n## Architecture\n\n### System Components\n\n```mermaid\ngraph TD\n    A[\"MCP Client<br/>(Claude, etc.)\"] --> B[\"mcp-pine<br/>MCP Server\"]\n    B --> C[\"PineClient<br/>(TCP/Unix Socket)\"]\n    C --> D[\"Emulator PINE Server<br/>(PCSX2/RPCS3/Duckstation)\"]\n    \n    B --> E[\"Tool Definitions<br/>(src/tools.ts)\"]\n    C --> F[\"PINE Protocol<br/>(src/pine.ts)\"]\n```\n\n### PINE Protocol Flow\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Client\n    participant Bridge as mcp-pine\n    participant PINE as PINE Server\n    participant Emu as Emulator\n    \n    MCP->>Bridge: call_tool(pine_read32)\n    Bridge->>PINE: TCP/Unix Socket\n    PINE->>Emu: Memory Read Request\n    Emu-->>PINE: Memory Value\n    PINE-->>Bridge: PINE Response Frame\n    Bridge-->>MCP: {content: text}\n```\n\n## Development Setup\n\n### Prerequisites\n\n| Requirement | Version | Notes |\n|-------------|---------|-------|\n| Node.js | ≥ 22.0.0 | LTS recommended |\n| npm | Bundled with Node | For package management |\n| PCSX2 | ≥ 1.7.x | PINE-enabled build |\n| TypeScript | ^5.5.0 | Development dependency |\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/dmang-dev/mcp-pine\ncd mcp-pine\n\n# Install dependencies (runs build via prepare hook)\nnpm install\n```\n\nThe `prepare` script in `package.json` automatically runs the build after installation:\n\n```json\n\"scripts\": {\n  \"prepare\": \"tsc\"\n}\n```\n资料来源：[package.json:8-10]()\n\n### Development Workflow\n\n```bash\n# Watch mode - recompile on file changes\nnpm run dev\n\n# Manual build (if not using dev)\nnpm run build   # or npx tsc\n\n# Quick smoke test against running emulator\nnode .scratch/smoke.cjs\n```\n资料来源：[README.md:1]()\n\n## Source Code Analysis\n\n### Entry Point (src/index.ts)\n\nThe entry point initializes the MCP server with the SDK, creates a `PineClient` instance based on environment variables, and registers all tools.\n\n**Key initialization flow:**\n\n1. Parse environment variables for connection options\n2. Create `PineClient` with resolved socket/TCP descriptor\n3. Connect to emulator's PINE server\n4. Register tools with the MCP server\n5. Start server on stdio\n\n### PineClient (src/pine.ts)\n\nThe `PineClient` class handles low-level protocol communication.\n\n**Connection Modes:**\n\n| Platform | Method | Path/Address |\n|----------|--------|--------------|\n| Linux/macOS | Unix Socket | `$XDG_RUNTIME_DIR/<target>.sock.<slot>` |\n| Linux fallback | Unix Socket | `/tmp/<target>.sock.<slot>` |\n| Windows | TCP | `127.0.0.1:<slot>` |\n\n**Supported Operations:**\n\n| Opcode | Operation | Description |\n|--------|-----------|-------------|\n| 0x01 | Version | Get emulator PINE version |\n| 0x02 | Title | Get loaded game title |\n| 0x03 | ID | Get game serial ID |\n| 0x04 | UUID | Get disc CRC |\n| 0x05 | GameVersion | Get game version string |\n| 0x10 | Status | Get emulator status |\n| 0x20 | Read8 | Read 8-bit value |\n| 0x21 | Read16 | Read 16-bit value |\n| 0x22 | Read32 | Read 32-bit value |\n| 0x23 | Read64 | Read 64-bit value |\n| 0x30 | Write8 | Write 8-bit value |\n| 0x31 | Write16 | Write 16-bit value |\n| 0x32 | Write32 | Write 32-bit value |\n| 0x33 | Write64 | Write 64-bit value |\n| 0x40 | SaveState | Save to slot |\n| 0x41 | LoadState | Load from slot |\n\n### Tool Definitions (src/tools.ts)\n\nEach MCP tool follows the TDQS (Tool Definition Quality Score) rubric with explicit:\n\n- **PURPOSE**: Single action sentence\n- **USAGE**: When to use vs. sibling tools\n- **BEHAVIOR**: Side effects, error conditions\n- **RETURNS**: Exact output shape\n\n**Tool Categories:**\n\n| Category | Tools |\n|----------|-------|\n| Connectivity | `pine_ping`, `pine_get_info` |\n| Read | `pine_read8`, `pine_read16`, `pine_read32`, `pine_read64`, `pine_read_range` |\n| Write | `pine_write8`, `pine_write16`, `pine_write32`, `pine_write64` |\n| State | `pine_save_state`, `pine_load_state` |\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `PINE_TARGET` | `pcsx2` | Emulator name prefix for Unix socket path |\n| `PINE_SLOT` | `28011` | PINE slot number (also TCP port on Windows) |\n| `PINE_PIPELINE_BATCH` | `1` | Number of pipelined requests (see Warning below) |\n| `XDG_RUNTIME_DIR` | - | Unix socket directory (Linux/macOS) |\n| `TMPDIR` | - | Unix socket fallback directory |\n\n资料来源：[README.md:1]()\n\n### Alignment Requirements\n\n**Critical**: PINE on PCSX2 does NOT enforce alignment. Multi-byte access at unaligned addresses silently returns corrupted data from the aligned-below address.\n\n| Access Width | Alignment Required |\n|--------------|-------------------|\n| 8-bit (write8/read8) | None |\n| 16-bit (write16/read16) | 2-byte |\n| 32-bit (write32/read32) | 4-byte |\n| 64-bit (write64/read64) | 8-byte |\n\n## Testing\n\n### Smoke Test\n\nRun the provided smoke test against a running emulator:\n\n```bash\n# Start PCSX2 with PINE enabled, load a game\nnode .scratch/smoke.cjs\n```\n\n### Manual Verification\n\n```bash\n# Test connection\nclaude mcp add pine --scope user mcp-pine\nclaude mcp list\n# pine: mcp-pine - ✓ Connected\n\n# Run a ping\nclaude -p \"call pine_ping\"\n```\n\n## Building\n\n### TypeScript Compilation\n\n```bash\nnpm run build\n# or\nnpx tsc\n```\n\nOutput is placed in `dist/` directory with the same structure as `src/`.\n\n### Docker\n\nA `Dockerfile` is provided for containerized deployment:\n\n```bash\ndocker build -t mcp-pine .\ndocker run mcp-pine\n```\n\n## Known Limitations\n\n### PCSX2 PINE Server Fragility\n\nPCSX2's PINE server has a **fragile request queue** that drops requests silently when too many are pipelined. This desyncs the reply pipeline, causing all subsequent requests to time out until emulator restart.\n\n| Setting | Safety | Latency |\n|---------|--------|---------|\n| `PINE_PIPELINE_BATCH=1` | Safe (default) | ~52ms for 4KB read |\n| `PINE_PIPELINE_BATCH=2+` | Risky | Lower latency |\n\n资料来源：[src/pine.ts:150-160]()\n\n### Error Modes\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| `Cannot reach PINE server` | Emulator not running, PINE disabled, wrong slot | Check `PINE_SLOT` |\n| `PINE FAIL response` | No game loaded, unmapped address | Load game, check address |\n| Reads return zeros | Unallocated memory region | Try `0x00100000` (EE RAM) |\n| Tool calls work but values corrupted | Endianness mismatch | PINE returns little-endian |\n| `PINE call timed out (10s)` after heavy use | PCSX2 PINE queue desync | Full emulator restart |\n\n## Emulator Support\n\n### PCSX2 (Primary)\n\n1. Launch PCSX2 1.7.x Qt or newer\n2. **Settings → Advanced → Enable PINE Server**\n3. Default slot is **28011**\n4. Load any game\n\n资料来源：[README.md:1]()\n\n### RPCS3 (Experimental)\n\n```bash\nPINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine\n```\n\nWire-level compatibility with PINE protocol not thoroughly tested.\n\n### Duckstation\n\n```bash\nPINE_TARGET=duckstation PINE_SLOT=<port> mcp-pine\n```\n\nRequires PINE-enabled Duckstation build.\n\n## Contribution Guidelines\n\n1. **Tool descriptions**: Follow TDQS rubric in `src/tools.ts`\n2. **Error handling**: All async operations must handle rejection\n3. **Alignment**: Document alignment requirements in parameter descriptions\n4. **Testing**: Verify changes against live PCSX2 before submitting\n5. **Documentation**: Update CHANGELOG.md with changes\n\n## Version History\n\n| Version | Date | Key Changes |\n|---------|------|-------------|\n| 0.2.1 | 2026-05-15 | Tool description quality pass |\n| 0.2.0 | 2026-05-10 | Bulk read, 10s timeout, robustness |\n| 0.1.0 | Earlier | Initial release |\n\n资料来源：[CHANGELOG.md:1-30]()\n\n---\n\n<a id='troubleshooting'></a>\n\n## Troubleshooting Guide\n\n### 相关页面\n\n相关主题：[Emulator Setup](#emulator-setup), [Configuration Reference](#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- [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- [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# Troubleshooting Guide\n\nThis guide covers common issues encountered when using **mcp-pine**, an MCP server that bridges the Model Context Protocol to the PINE IPC system used by PlayStation 2/3 emulators like PCSX2, RPCS3, and Duckstation.\n\n## Connection Troubleshooting\n\n### Cannot Reach PINE Server\n\n**Symptom:** The MCP client reports it cannot connect to the PINE server.\n\n**Root Causes:**\n\n| Cause | Description | Fix |\n|-------|-------------|-----|\n| Emulator not running | PCSX2/RPCS3/Duckstation is not launched | Start the emulator with a game loaded |\n| PINE not enabled | The PINE server toggle is off in emulator settings | Enable it in emulator settings |\n| Slot/Port mismatch | `PINE_SLOT` doesn't match the emulator's configured port | Verify `PINE_SLOT` matches emulator configuration |\n| Game not loaded | Some PINE operations require an active game session | Load any game before using tools |\n\n**Verification Steps:**\n\n```bash\n# Check if mcp-pine is recognized by Claude Code\nclaude mcp list\n# Expected output: pine: mcp-pine - ✓ Connected\n\n# Test connection manually\nPINE_TARGET=pcsx2 PINE_SLOT=28011 node .scratch/smoke.cjs\n```\n\n**资料来源：** [README.md:70-73](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Transport Layer Differences\n\n| Platform | Transport | Path/Address |\n|----------|-----------|--------------|\n| Windows | TCP | `127.0.0.1:<PINE_SLOT>` |\n| Linux/macOS | Unix Socket | `$XDG_RUNTIME_DIR/<PINE_TARGET>.sock.<PINE_SLOT>` with `$TMPDIR`/`/tmp` fallbacks |\n\nThe connection transport is automatically selected based on the operating system. Windows uses TCP loopback while Unix-like systems use Unix domain sockets.\n\n**资料来源：** [src/pine.ts:80-88](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## PINE Response Errors\n\n### PINE FAIL Response (0xFF)\n\n**Symptom:** Tool returns \"PINE FAIL response\" error.\n\n**Common Causes:**\n\n1. **No game loaded** — Most PINE operations require an active game session\n2. **Unmapped address** — The memory address doesn't map to any allocated region\n3. **Invalid opcode** — The emulator doesn't support the requested operation\n\n**Diagnostic Approach:**\n\n```typescript\n// Try reading from a known-good address first (EE main RAM)\nconst test = await pine.read32(0x00100000);\n```\n\nThe address `0x00100000` is almost always inside loaded EE RAM and serves as a good sanity check.\n\n**资料来源：** [README.md:74-76](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Reads Return Zeros\n\n**Symptom:** Memory reads return all zeros instead of expected values.\n\n**Cause:** The address falls in an unallocated memory region.\n\n**Solution:** Start with `0x00100000` (EE main RAM base). The valid EE main RAM range is `0x00100000` to `0x01FFFFFF`.\n\n```typescript\n// Verify address is in valid range\n// EE main RAM: 0x00100000 - 0x01FFFFFF\n// IOP RAM: 0x1C000000+\n// Scratchpad: 0x1F800000 - 0x1F8003FF\n```\n\n**资料来源：** [src/tools.ts:55-60](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### Corrupted Values / Wrong Data\n\n**Symptom:** Read values appear garbled or incorrect.\n\n**Root Cause:** Endianness mismatch.\n\nPINE returns data in **little-endian** format. When interpreting multi-byte values or strings, ensure your code handles little-endian encoding.\n\n```typescript\n// For strings, use read_range (byte-level read)\nconst bytes = await pine.readRange(0x00100000, 64);\nconst str = bytes.toString('utf8').replace(/\\0+$/, '');\n\n// For multi-byte integers, PINE handles conversion automatically\nconst value = await pine.read32(0x00100000); // Already little-endian decoded\n```\n\n**资料来源：** [README.md:77-80](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## PCSX2-Specific Issues\n\n### PINE Server Wedging\n\n**Symptom:** `pine_ping` times out after heavy use, even though the emulator appears to be running.\n\n**Root Cause:** PCSX2's PINE server has a **fragile request queue** that silently drops requests when too many are pipelined. As few as 7 in-flight requests can trigger this behavior. When any request is dropped, the reply pipeline becomes desynchronized — every subsequent reply is delivered to the wrong waiting client.\n\n```mermaid\ngraph TD\n    A[Normal Operation] -->|~7 in-flight requests| B[Request Dropped]\n    B --> C[Reply Pipeline Desync]\n    C --> D[All Replies Misaligned]\n    D --> E[Every Call Times Out]\n    E --> F[Emulator Must Be Fully Restarted]\n```\n\n**Recovery Steps:**\n\n1. Fully quit PCSX2 (not just close the game)\n2. Restart PCSX2\n3. Load the game\n4. Reconnect the MCP client\n\n> **Note:** Simply reconnecting the client does NOT fix the desync — the corruption is on the emulator side.\n\n**资料来源：** [README.md:83-91](https://github.com/dmang-dev/mcp-pine/blob/main/README.md), [CHANGELOG.md:45-52](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n### Bulk Read Performance\n\n**Symptom:** `pine_read_range` feels slow compared to mGBA's `read_range`.\n\n**Explanation:** PINE has no native bulk read opcode. The client issues reads **serially** by default, choosing the largest aligned width at each step (read64 on 8-byte boundaries, falling back to 32/16/8).\n\n| Operation | Latency | Notes |\n|-----------|---------|-------|\n| Full 4096-byte read | ~52 ms | Measured on PCSX2 v2.6.3 over loopback |\n| Frame budget at 60fps | ~16.6 ms | Bulk read takes ~3 frames |\n\n**Optimization Option:** Set `PINE_PIPELINE_BATCH=2` to enable limited pipelining. This reduces latency but risks desyncing PCSX2's PINE server if the emulator's queue becomes overloaded.\n\n```bash\n# More aggressive pipelining (at your own risk)\nPINE_PIPELINE_BATCH=2 mcp-pine\n```\n\n**资料来源：** [README.md:92-95](https://github.com/dmang-dev/mcp-pine/blob/main/README.md), [src/pine.ts:95-105](https://github.com/dmang-dev/mcp-pine/blob/main/src/pine.ts)\n\n## Memory Access Issues\n\n### Alignment Requirements\n\n**Critical:** Multi-byte memory operations have alignment requirements that PCSX2 does NOT enforce.\n\n| Operation | Alignment | Unaligned Behavior |\n|-----------|-----------|-------------------|\n| `pine_read8` / `pine_write8` | None | Works correctly |\n| `pine_read16` / `pine_write16` | 2-byte | Silently returns corrupted data |\n| `pine_read32` / `pine_write32` | 4-byte | Silently returns corrupted data |\n| `pine_read64` / `pine_write64` | 8-byte | Silently returns corrupted data |\n\n**Safe Alternative:** For unaligned access, use `pine_read_range` and assemble the bytes manually.\n\n```typescript\n// Unaligned 32-bit read at 0x00100003\nconst bytes = await pine.readRange(0x00100003, 4);\nconst value = bytes.readUInt32LE(0);\n```\n\n**资料来源：** [src/tools.ts:42-50](https://github.com/dmang-dev/mcp-pine/blob/main/src/tools.ts)\n\n### 64-bit Value Precision\n\nJavaScript loses precision for integers beyond `2^53`. For 64-bit operations, values are exchanged as **decimal strings**.\n\n```typescript\n// Writing a large 64-bit value\nawait pine.write64(0x00100000, \"18446744073709551615\" as unknown as bigint);\n\n// Reading returns string-encoded decimal\nconst largeValue = await pine.read64(0x00100000);\n// Returns: \"18446744073709551615\" (as string)\n```\n\n**资料来源：** [CHANGELOG.md:28-30](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n## Timeout Issues\n\n### 10-Second Call Timeout\n\nEvery PINE call has a **10-second timeout**. If the emulator drops a reply (e.g., due to the wedging issue), the call rejects cleanly rather than hanging indefinitely.\n\n**Timeouts indicate:**\n- PCSX2 PINE server is wedged (most common)\n- Network/connection interruption\n- Emulator is unresponsive\n\n**If you experience frequent timeouts:**\n1. Check if PCSX2's PINE server has wedged\n2. Verify no other tool is aggressive pipelining\n3. Consider restarting the emulator\n\n**资料来源：** [CHANGELOG.md:26-29](https://github.com/dmang-dev/mcp-pine/blob/main/CHANGELOG.md)\n\n## Emulator-Specific Setup\n\n### PCSX2 (Recommended)\n\n1. Launch PCSX2 1.7.x Qt or newer\n2. Navigate to **Settings → Advanced → Enable PINE Server**\n3. Default slot is **28011** — only change `PINE_SLOT` if you configure a different port\n4. Load any game\n\n> PINE is always-on once enabled; no scripts or console commands needed.\n\n**资料来源：** [README.md:44-54](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### RPCS3\n\nRPCS3 uses its own IPC implementation that mirrors PINE's opcode set. Wire-level compatibility hasn't been thoroughly tested.\n\n1. Enable IPC server in **Configuration → Advanced**\n2. Note the configured port\n3. Run with:\n   ```bash\n   PINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine\n   ```\n\n**资料来源：** [README.md:58-65](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n### Duckstation\n\nDuckstation includes a PINE server only in **specific builds**. Check whether your build includes it:\n\n1. Set `PINE_TARGET=duckstation`\n2. Configure `PINE_SLOT` to match the port shown in Duckstation's settings\n3. If connection fails, your build likely doesn't include PINE support\n\n**资料来源：** [README.md:5-9](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Environment Variables Reference\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `PINE_TARGET` | `pcsx2` | Emulator name — used as prefix in Unix socket path on Linux/macOS |\n| `PINE_SLOT` | `28011` | PINE slot / port number |\n| `PINE_HOST` | `127.0.0.1` | TCP host override (Windows always uses this) |\n| `PINE_SOCKET_PATH` | auto | Full Unix socket path override |\n| `PINE_PIPELINE_BATCH` | `1` | Number of serial reads to batch together (higher = faster but riskier) |\n\n**资料来源：** [README.md:34-40](https://github.com/dmang-dev/mcp-pine/blob/main/README.md)\n\n## Diagnostic Checklist\n\nWhen reporting issues, include the following information:\n\n- [ ] Emulator name and version (e.g., PCSX2 v2.6.3)\n- [ ] Operating system and version\n- [ ] `PINE_TARGET` and `PINE_SLOT` values\n- [ ] Whether a game is currently loaded\n- [ ] Exact error message received\n- [ ] Steps to reproduce\n- [ ] Whether restarting the emulator resolves the issue\n\n## Getting Help\n\nIf issues persist after following this guide:\n\n1. Search existing [GitHub Issues](https://github.com/dmang-dev/mcp-pine/issues)\n2. File a new issue with diagnostic information\n3. Include the output of the smoke test:\n   ```bash\n   node .scratch/smoke.cjs\n   ```\n\n**资料来源：** [README.md:1-3](https://github.com/dmang-dev/mcp-pine/blob/main/README.md), [package.json:8-9](https://github.com/dmang-dev/mcp-pine/blob/main/package.json)\n\n---\n\n---\n\n## Doramagic Pitfall Log\n\nProject: dmang-dev/mcp-pine\n\nSummary: Found 8 potential pitfall items; 0 are high/blocking. Highest priority: installation - 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers.\n\n## 1. installation · 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Submit listing PR to punkpeye/awesome-mcp-servers\n- User impact: 可能阻塞安装或首次运行。\n- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- Evidence: community_evidence:github | cevd_540ae479012f437fb2cb5e7d33636f1f | https://github.com/dmang-dev/mcp-pine/issues/2 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 2. configuration · 可能修改宿主 AI 配置\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: 项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- User impact: 安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- Suggested check: 列出会写入的配置文件、目录和卸载/回滚步骤。\n- Guardrail action: 涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- Evidence: capability.host_targets | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | host_targets=mcp_host, claude\n\n## 3. capability · 能力判断依赖假设\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: README/documentation is current enough for a first validation pass.\n- User impact: 假设不成立时，用户拿不到承诺的能力。\n- Suggested check: 将假设转成下游验证清单。\n- Guardrail action: 假设必须转成验证项；没有验证结果前不能写成事实。\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\n## 4. maintenance · 维护活跃度未知\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: 未记录 last_activity_observed。\n- User impact: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Suggested check: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Guardrail action: 维护活跃度未知时，推荐强度不能标为高信任。\n- Evidence: evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | last_activity_observed missing\n\n## 5. security_permissions · 下游验证发现风险项\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 下游已经要求复核，不能在页面中弱化。\n- Suggested check: 进入安全/权限治理复核队列。\n- Guardrail action: 下游风险存在时必须保持 review/recommendation 降级。\n- Evidence: downstream_validation.risk_items | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 6. security_permissions · 存在评分风险\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 风险会影响是否适合普通用户安装。\n- Suggested check: 把风险写入边界卡，并确认是否需要人工复核。\n- Guardrail action: 评分风险必须进入边界卡，不能只作为内部分数。\n- Evidence: risks.scoring_risks | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 7. maintenance · issue/PR 响应质量未知\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: issue_or_pr_quality=unknown。\n- User impact: 用户无法判断遇到问题后是否有人维护。\n- Suggested check: 抽样最近 issue/PR，判断是否长期无人处理。\n- Guardrail action: issue/PR 响应未知时，必须提示维护风险。\n- Evidence: evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | issue_or_pr_quality=unknown\n\n## 8. maintenance · 发布节奏不明确\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: release_recency=unknown。\n- User impact: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Suggested check: 确认最近 release/tag 和 README 安装命令是否一致。\n- Guardrail action: 发布节奏未知或过期时，安装说明必须标注可能漂移。\n- Evidence: 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 output with a Doramagic pitfall appendix.",
      "title": "Human Manual"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log\n\nProject: dmang-dev/mcp-pine\n\nSummary: Found 8 potential pitfall items; 0 are high/blocking. Highest priority: installation - 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers.\n\n## 1. installation · 来源证据：Submit listing PR to punkpeye/awesome-mcp-servers\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Submit listing PR to punkpeye/awesome-mcp-servers\n- User impact: 可能阻塞安装或首次运行。\n- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- Evidence: community_evidence:github | cevd_540ae479012f437fb2cb5e7d33636f1f | https://github.com/dmang-dev/mcp-pine/issues/2 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 2. configuration · 可能修改宿主 AI 配置\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: 项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- User impact: 安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- Suggested check: 列出会写入的配置文件、目录和卸载/回滚步骤。\n- Guardrail action: 涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- Evidence: capability.host_targets | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | host_targets=mcp_host, claude\n\n## 3. capability · 能力判断依赖假设\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: README/documentation is current enough for a first validation pass.\n- User impact: 假设不成立时，用户拿不到承诺的能力。\n- Suggested check: 将假设转成下游验证清单。\n- Guardrail action: 假设必须转成验证项；没有验证结果前不能写成事实。\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\n## 4. maintenance · 维护活跃度未知\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: 未记录 last_activity_observed。\n- User impact: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Suggested check: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Guardrail action: 维护活跃度未知时，推荐强度不能标为高信任。\n- Evidence: evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | last_activity_observed missing\n\n## 5. security_permissions · 下游验证发现风险项\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 下游已经要求复核，不能在页面中弱化。\n- Suggested check: 进入安全/权限治理复核队列。\n- Guardrail action: 下游风险存在时必须保持 review/recommendation 降级。\n- Evidence: downstream_validation.risk_items | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 6. security_permissions · 存在评分风险\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 风险会影响是否适合普通用户安装。\n- Suggested check: 把风险写入边界卡，并确认是否需要人工复核。\n- Guardrail action: 评分风险必须进入边界卡，不能只作为内部分数。\n- Evidence: risks.scoring_risks | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | no_demo; severity=medium\n\n## 7. maintenance · issue/PR 响应质量未知\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: issue_or_pr_quality=unknown。\n- User impact: 用户无法判断遇到问题后是否有人维护。\n- Suggested check: 抽样最近 issue/PR，判断是否长期无人处理。\n- Guardrail action: issue/PR 响应未知时，必须提示维护风险。\n- Evidence: evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | issue_or_pr_quality=unknown\n\n## 8. maintenance · 发布节奏不明确\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: release_recency=unknown。\n- User impact: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Suggested check: 确认最近 release/tag 和 README 安装命令是否一致。\n- Guardrail action: 发布节奏未知或过期时，安装说明必须标注可能漂移。\n- Evidence: evidence.maintainer_signals | github_repo:1234265030 | https://github.com/dmang-dev/mcp-pine | release_recency=unknown\n",
      "summary": "Identity, installation, configuration, runtime, and safety pitfalls before user trial.",
      "title": "Pitfall Log"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# mcp-pine - Prompt Preview\n\n> Copy the prompt below into your AI host before installing anything.\n> Its purpose is to let you safely feel the project's workflow, not to claim the project has already run.\n\n## Copy this prompt\n\n```text\nYou are using an independent Doramagic capability pack for dmang-dev/mcp-pine.\n\nProject:\n- Name: mcp-pine\n- Repository: https://github.com/dmang-dev/mcp-pine\n- Summary: MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control\n- Host target: mcp_host, claude\n\nGoal:\nHelp me evaluate this project for the following task without installing it yet: MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control\n\nBefore taking action:\n1. Restate my task, success standard, and boundary.\n2. Identify whether the next step requires tools, browser access, network access, filesystem access, credentials, package installation, or host configuration.\n3. Use only the Doramagic Project Pack, the upstream repository, and the source-linked evidence listed below.\n4. If a real command, install step, API call, file write, or host integration is required, mark it as \"requires post-install verification\" and ask for approval first.\n5. If evidence is missing, say \"evidence is missing\" instead of filling the gap.\n\nPreviewable capabilities:\n- Capability 1: MCP server for PINE-speaking emulators (PCSX2, RPCS3, etc.) — exposes memory r/w and savestate control\n\nCapabilities that require post-install verification:\n- Capability 1: Use the source-backed project context to guide one small, checkable workflow step.\n\nCore service flow:\n1. overview: Project Overview. Produce one small intermediate artifact and wait for confirmation.\n2. emulator-setup: Emulator Setup. Produce one small intermediate artifact and wait for confirmation.\n3. system-architecture: System Architecture. Produce one small intermediate artifact and wait for confirmation.\n4. configuration: Configuration Reference. Produce one small intermediate artifact and wait for confirmation.\n5. memory-operations: Memory Operations. Produce one small intermediate artifact and wait for confirmation.\n\nSource-backed evidence to keep in mind:\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/pine.ts\n- src/index.ts\n- src/tools.ts\n\nFirst response rules:\n1. Start Step 1 only.\n2. Explain the one service action you will perform first.\n3. Ask exactly three questions about my target workflow, success standard, and sandbox boundary.\n4. Stop and wait for my answers.\n\nStep 1 follow-up protocol:\n- After I answer the first three questions, stay in Step 1.\n- Produce six parts only: clarified task, success standard, boundary conditions, two or three options, tradeoffs for each option, and one recommendation.\n- End by asking whether I confirm the recommendation.\n- Do not move to Step 2 until I explicitly confirm.\n\nConversation rules:\n- Advance one step at a time and wait for confirmation after each small artifact.\n- Write outputs as recommendations or planned checks, not as completed execution.\n- Do not claim tests passed, files changed, commands ran, APIs were called, or the project was installed.\n- If the user asks for execution, first provide the sandbox setup, expected output, rollback, and approval checkpoint.\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start\n\nProject: dmang-dev/mcp-pine\n\n## Official Entry Points\n\n### Node.js / npm · 官方安装入口\n\n```bash\nnpm install -g mcp-pine\n```\n\nSource：https://github.com/dmang-dev/mcp-pine#readme\n\n## Sources\n\n- repo: https://github.com/dmang-dev/mcp-pine\n- docs: https://github.com/dmang-dev/mcp-pine#readme\n",
      "summary": "Entry points extracted from official README or installation documentation.",
      "title": "Quick Start"
    }
  },
  "validation_id": "dval_99340a3d39b8461282fe507952ba5142"
}
