PinAppAI

Visual website feedback your coding agent applies: pin change requests on the live site over MCP.

使うべきか

品質と安全性

B
説明の品質
99%
スキーマの完全性
85%
命名の品質
92%
ポイズニングのリスク
40%
権限の一致
100%
プロトコルへの準拠
100%

検出事項(6)

  • HIGHTool poisoning patterns detected
  • LOWTool 'update_workspace' description lacks action verbupdate_workspace 内
  • LOWTool 'pinappai_get_iteration_coverage' name length outside 3-30 rangepinappai_get_iteration_coverage 内
  • LOWTool description contains role marker that could confuse chat modelspinappai_list_apply_inbox 内
  • LOWTool description contains role marker that could confuse chat modelspinappai_reset_review_data 内
  • LOWTool description contains role marker that could confuse chat modelspinappai_get_workflow 内

ツール定義とプロトコルへの準拠に関する自動分析に基づいています。

コンテキストコスト

~7,018トークン数(ツール定義)
~1.2 KB一般的なレスポンスサイズ
注意への影響は大きい(128k コンテキストの 5.48%)

これは、サーバーのツールがモデルのコンテキストに読み込まれるたびに消費されるおおよそのトークン数です。数が多いほど、ほかのタスクに使える注意が減ります。

インストール

ワンクリックインストール

これを `claude_desktop_config.json` ファイルに追加してください:

{
  "mcpServers": {
    "mcp": {
      "command": "npx",
      "args": [
        "@pinappai/mcp"
      ]
    }
  }
}

実行可能なパッケージ

npm@pinappai/mcp0.9.9stdio

リモートエンドポイント

https://mcp.pinappai.com/mcpstreamable-http

できること

ツール一覧

ツール(38)

🟢 読み取り専用🟡 書き込み🔴 削除⚪ 不明
🟢list_projects

List PinAppAI projects this API key can access. Returns one entry per project in the key's workspace, with slug, name, derived domain, and created_at. Call this first to see what projects are available before drilling into specific ones.

入力スキーマ

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🟢get_review_summary(project)

Cheap one-call summary of change-request state for a project. Returns totals + by-page + by-reviewer breakdowns + oldest/newest unresolved timestamps. Call this BEFORE drilling into individual CRs to frame the work.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    }
  },
  "required": [
    "project"
  ],
  "additionalProperties": false
}
🟢list_change_requests(project, include, page_url, since, reviewer, ...)

List change requests for a project with filters + cursor pagination. Defaults to include=['change_requested'] (highest-signal subset). Returns digest fields per row (including element_kind=text|mixed|field|null and suggested_text — a literal text replacement on text/field picks); no inline images at this tier (token-cheap by design). Use get_change_request for full detail + screenshots.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "include": {
      "description": "Which feedback kinds to include: change_requested (a decision requesting a change), rejected (a decision rejecting the pick), approved (a decision approving the pick), comment (a comment-only pin, no decision). Defaults to ['change_requested'].",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "change_requested",
          "rejected",
          "approved",
          "comment"
        ]
      }
    },
    "page_url": {
      "description": "Filter to change requests captured on this exact page URL.",
      "type": "string"
    },
    "since": {
      "description": "ISO 8601 timestamp. Only return change requests created after this time.",
      "type": "string"
    },
    "reviewer": {
      "description": "Filter by reviewer name or email (matches either field).",
      "type": "string"
    },
    "limit": {
      "description": "Max rows to return per page. Defaults to 50, maximum 200.",
      "type": "integer",
      "minimum": 1,
      "maximum": 200
    },
    "cursor": {
      "description": "Opaque pagination cursor from a previous response's next_cursor. Pass it to fetch the next page.",
      "type": "string"
    }
  },
  "required": [
    "project"
  ],
  "additionalProperties": false
}
🟢get_change_request(project, id, include_image)

Full detail for one change request. Returns the CR (including element_kind=text|mixed|field|null and suggested_text — a literal text-replacement the reviewer typed when picking a text/field element), plus related[] (other CRs on the same selector + same page) so you can detect patterns from a single fetch. Set include_image=true to embed the screenshot inline as an MCP image content block. When suggested_text is non-null on a text/field pick, paste it verbatim — do not interpret or rewrite. When element_kind=mixed, the element contains more than text (icons/images/structure) — rely on the comment + screenshot, not just the visible text.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "id": {
      "type": "string",
      "minLength": 1,
      "description": "The FEEDBACK id (fb_*), NOT a change-request id (cr_*). When you have a CR row from pinappai_list_apply_inbox / list_change_requests, pass its `source_feedback_id` (or just `id` in list_change_requests' response — same field) here. Passing a cr_* value returns 404."
    },
    "include_image": {
      "description": "When true, also returns the change request's screenshot inline as an MCP image content block, in addition to the JSON text response. Defaults to false (JSON only).",
      "type": "boolean"
    }
  },
  "required": [
    "project",
    "id"
  ],
  "additionalProperties": false
}
🟢analyze_patterns(project, include, group_by, ai_clusters, ai_model_preference)

Server-side deterministic groupings (by selector / page / reviewer / keyword) plus heuristic suggested_clusters of change requests. Set ai_clusters="auto" (default) to also request semantic clustering via the host's MCP sampling capability — returns ai_clustering_hint for the host AI to apply inline if sampling is unsupported. Use this BEFORE drilling into individual CRs to find patterns across the dataset.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "include": {
      "description": "Which feedback kinds to pull into the analysis: change_requested (a decision requesting a change), rejected (a decision rejecting the pick), approved (a decision approving the pick), comment (a comment-only pin, no decision). Defaults to ['change_requested'].",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "change_requested",
          "rejected",
          "approved",
          "comment"
        ]
      }
    },
    "group_by": {
      "description": "Which deterministic groupings to compute: selector (by CSS selector), page (by page URL), reviewer (by reviewer). Defaults to ['selector', 'page']. Keyword extraction (common_keywords) is always computed regardless of this setting.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "selector",
          "page",
          "reviewer",
          "keyword"
        ]
      }
    },
    "ai_clusters": {
      "description": "Controls semantic clustering via the host's MCP sampling capability. off skips it and returns only the deterministic groupings. auto (default) attempts it and falls back to an ai_clustering_hint for the calling AI to apply inline if the host doesn't support sampling. on requires sampling support and returns a sampling_unsupported error if the host doesn't provide it.",
      "type": "string",
      "enum": [
        "off",
        "auto",
        "on"
      ]
    },
    "ai_model_preference": {
      "description": "Optional model preference hint for the sampling request. Currently accepted but not forwarded to the host's createMessage call (the sampling request always uses a fixed speed/intelligence preference); reserved for future use.",
      "type": "string"
    }
  },
  "required": [
    "project"
  ],
  "additionalProperties": false
}
🟢get_screenshot(project, id)

Return the screenshot for a change request as an inline MCP image content block. Use when you want vision context without the full JSON envelope from get_change_request.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "id": {
      "type": "string",
      "minLength": 1,
      "description": "The FEEDBACK id (fb_*), NOT a change-request id (cr_*). When you have a CR row from pinappai_list_apply_inbox, pass its `source_feedback_id` here. Passing a cr_* value returns 404."
    }
  },
  "required": [
    "project",
    "id"
  ],
  "additionalProperties": false
}
🟢get_project(project)

Get a single project by slug — name, allowed_origins, archive state, and the embeddable widget api_key. Scoped to the API key's workspace.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    }
  },
  "required": [
    "project"
  ],
  "additionalProperties": false
}
🟡create_project(slug, name, allowed_origins)

Create a new PinAppAI project inside the API key's workspace. Returns the project plus its widget api_key for embedding. Requires editor role on the workspace.

入力スキーマ

{
  "type": "object",
  "properties": {
    "slug": {
      "type": "string",
      "minLength": 2,
      "maxLength": 64,
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "description": "Project slug (lowercase, hyphens). Must be unique across all PinAppAI projects."
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120,
      "description": "Human-readable project name."
    },
    "allowed_origins": {
      "description": "Origins where the widget will load (e.g. https://example.com or *.example.com). Up to 20 entries.",
      "maxItems": 20,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 255
      }
    }
  },
  "required": [
    "slug",
    "name"
  ],
  "additionalProperties": false
}
🟡update_project(project, slug, name, owner_email, allowed_origins, ...)

Update editable fields on a project — slug, name, owner_email, allowed_origins, allow_anonymous_reviewers, primary_origin (review link), preview_origin (preview review link). Requires editor role.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "Current project slug (the lookup key)."
    },
    "slug": {
      "description": "New slug (renames the project; widget snippets keep working since they reference api_key, not slug).",
      "type": "string",
      "minLength": 2,
      "maxLength": 64,
      "pattern": "^[a-z0-9][a-z0-9-]*$"
    },
    "name": {
      "description": "New display name for the project.",
      "type": "string",
      "minLength": 1,
      "maxLength": 120
    },
    "owner_email": {
      "description": "Reassign project ownership to a different email (for display only — does not change permissions).",
      "type": "string",
      "maxLength": 254,
      "format": "email",
      "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
    },
    "allowed_origins": {
      "description": "REPLACES the existing list. Pass an empty array [] to clear all allowed origins.",
      "maxItems": 20,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 255
      }
    },
    "allow_anonymous_reviewers": {
      "description": "When true, any verified email on a CORS-allowed origin can submit feedback. When false, the email must be on the workspace or project_reviewers list.",
      "type": "boolean"
    },
    "primary_origin": {
      "description": "Canonical site origin powering the no-install review link (review.pinappai.com/p/<slug>/). Any URL is normalized down to its origin. null (or an empty string) clears it and disables the link.",
      "anyOf": [
        {
          "type": "string",
          "maxLength": 255,
          "format": "uri"
        },
        {
          "type": "null"
        }
      ]
    },
    "preview_origin": {
      "description": "Optional branch/preview deploy origin. review.pinappai.com/p/<slug>~preview/ serves it so reviewers can check APPLIED changes before they ship — records still write against primary_origin. Set this after publishing an apply round to a preview deploy; null (or an empty string) clears it.",
      "anyOf": [
        {
          "type": "string",
          "maxLength": 255,
          "format": "uri"
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": [
    "project"
  ],
  "additionalProperties": false
}
🔴archive_project(project)

Soft-archive a project — the widget stops accepting new feedback but the project + history is preserved. Reversible via unarchive_project. Owner role required.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug to archive."
    }
  },
  "required": [
    "project"
  ],
  "additionalProperties": false
}
⚪unarchive_project(project)

Restore an archived project — the widget starts accepting feedback again on pages that still embed the snippet. Owner role required.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug to unarchive."
    }
  },
  "required": [
    "project"
  ],
  "additionalProperties": false
}
🟢list_workspaces

List all workspaces the API key's user is a member of, with role per workspace. The api-key remains bound to its original workspace — to operate on another, mint a new key for that workspace in the admin UI.

入力スキーマ

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🟡create_workspace(slug, name)

Create a new workspace owned by the API key's user. Free/Pro plans cap at 1 workspace; Team/Business unlimited. To use the new workspace from MCP, mint a fresh key for it in the admin UI.

入力スキーマ

{
  "type": "object",
  "properties": {
    "slug": {
      "type": "string",
      "minLength": 2,
      "maxLength": 64,
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "description": "Workspace slug (lowercase, hyphens). Globally unique."
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120,
      "description": "Human-readable workspace name."
    }
  },
  "required": [
    "slug",
    "name"
  ],
  "additionalProperties": false
}
🟢get_workspace

Get the API key's workspace details (slug, name, plan, tier) plus the user's role in that workspace. Useful as a permissions probe.

入力スキーマ

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🔴update_workspace(name, slug)

Rename or re-slug the API key's workspace. Owner role required. Slug changes break existing dashboard URLs.

入力スキーマ

{
  "type": "object",
  "properties": {
    "name": {
      "description": "New display name for the workspace.",
      "type": "string",
      "minLength": 1,
      "maxLength": 120
    },
    "slug": {
      "description": "Renaming slug breaks every URL pointing at the old slug — use sparingly.",
      "type": "string",
      "minLength": 2,
      "maxLength": 64,
      "pattern": "^[a-z0-9][a-z0-9-]*$"
    }
  },
  "additionalProperties": false
}
🔴delete_workspace

Schedule the API key's workspace for permanent deletion (7-day grace window). Reversible only via the email magic-link sent to the owner. Subsequent MCP calls with this key will fail not_found until cancelled.

入力スキーマ

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🟢list_members

List members of the API key's workspace with their roles, sorted owner → admin → editor → viewer. The user_id field is the lookup key for update_member_role and remove_member.

入力スキーマ

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
⚪invite_member(email, name, role)

Invite a user to the API key's workspace as admin / editor / viewer (default editor). Admin role required to call. Sends a welcome email.

入力スキーマ

{
  "type": "object",
  "properties": {
    "email": {
      "type": "string",
      "maxLength": 254,
      "format": "email",
      "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
      "description": "Invitee's email address."
    },
    "name": {
      "description": "Optional display name; defaults to the email's local-part.",
      "type": "string",
      "maxLength": 120
    },
    "role": {
      "description": "Defaults to editor. Admins can't invite owners — that requires an existing owner.",
      "type": "string",
      "enum": [
        "admin",
        "editor",
        "viewer"
      ]
    }
  },
  "required": [
    "email"
  ],
  "additionalProperties": false
}
🔴update_member_role(user_id, role)

Change a workspace member's role. Caller must outrank both the current role and the new role; promoting to owner requires owner role. Last-owner demotion is rejected with last_owner.

入力スキーマ

{
  "type": "object",
  "properties": {
    "user_id": {
      "type": "string",
      "minLength": 1,
      "description": "The member's user_id (from list_members)."
    },
    "role": {
      "type": "string",
      "enum": [
        "owner",
        "admin",
        "editor",
        "viewer"
      ],
      "description": "The new role."
    }
  },
  "required": [
    "user_id",
    "role"
  ],
  "additionalProperties": false
}
🔴remove_member(user_id)

Remove a member from the API key's workspace. Self-removal works for any role; cross-removal requires admin+ and outranking the target. Last-owner removal returns last_owner.

入力スキーマ

{
  "type": "object",
  "properties": {
    "user_id": {
      "type": "string",
      "minLength": 1,
      "description": "The member's user_id (from list_members)."
    }
  },
  "required": [
    "user_id"
  ],
  "additionalProperties": false
}
🟢list_reviewers(project)

List external reviewers on a project (people invited via invite_reviewer). Workspace members are implicitly authorized and not listed here. Status: pending / verified / revoked.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    }
  },
  "required": [
    "project"
  ],
  "additionalProperties": false
}
🟢invite_reviewer(project, email, name)

Invite an external reviewer to a project. They'll get a welcome email; status starts pending and flips to verified when they OTP through the widget. Editor role required.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "email": {
      "type": "string",
      "maxLength": 254,
      "format": "email",
      "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
      "description": "Reviewer's email address."
    },
    "name": {
      "description": "Optional display name; defaults to the email's local-part.",
      "type": "string",
      "maxLength": 120
    }
  },
  "required": [
    "project",
    "email"
  ],
  "additionalProperties": false
}
🔴revoke_reviewer(project, reviewer_id)

Revoke an external reviewer's access. First call soft-revokes (status=revoked, audit trail preserved); second call hard-deletes (status=removed). Editor role required.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "reviewer_id": {
      "type": "string",
      "minLength": 1,
      "description": "The project_reviewers row id (from list_reviewers)."
    }
  },
  "required": [
    "project",
    "reviewer_id"
  ],
  "additionalProperties": false
}
🟢list_audit_events(action, actor, from, to, limit, ...)

Read audit log entries for the API key's workspace. Owner role + Business tier required. Returns newest-first; supports filters action / actor (email substring) / from / to (Unix ms).

入力スキーマ

{
  "type": "object",
  "properties": {
    "action": {
      "description": "Exact dotted action name (e.g. \"feedback.update\", \"member.invite\").",
      "type": "string"
    },
    "actor": {
      "description": "Substring match on actor_email.",
      "type": "string"
    },
    "from": {
      "description": "Start of time range (Unix ms, inclusive).",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "to": {
      "description": "End of time range (Unix ms, exclusive).",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "limit": {
      "description": "Default 100, max 500.",
      "type": "integer",
      "minimum": 1,
      "maximum": 500
    },
    "offset": {
      "description": "Default 0.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "additionalProperties": false
}
🟢list_api_keys

List API keys (active + recently-revoked) in the calling key's workspace. Plaintext / hash never returned. Owner or admin role required.

入力スキーマ

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🟢get_api_key(id)

Get a single API key's metadata by id (no plaintext / hash). Owner or admin role required. Wrong-role and nonexistent-id both surface as not_found.

入力スキーマ

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "minLength": 1,
      "description": "The api_keys.id (from list_api_keys)."
    }
  },
  "required": [
    "id"
  ],
  "additionalProperties": false
}
🔴revoke_api_key(id)

Soft-revoke an API key (reversible via restore_api_key for 7 days). Owner or admin role required. Refuses to revoke the calling key with cannot_revoke_self.

入力スキーマ

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "minLength": 1,
      "description": "The api_keys.id to revoke."
    }
  },
  "required": [
    "id"
  ],
  "additionalProperties": false
}
⚪restore_api_key(id)

Restore a soft-revoked API key (within 7 days of revocation). Owner or admin role required. Returns restore_window_expired if the row was never revoked or was revoked > 7 days ago.

入力スキーマ

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "minLength": 1,
      "description": "The api_keys.id to restore."
    }
  },
  "required": [
    "id"
  ],
  "additionalProperties": false
}
🟢get_me

Whoami probe — returns the user behind the API key, the workspace it's bound to, the user's role in that workspace, and the API key's metadata. Run this first to establish context.

入力スキーマ

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🟡update_me_profile(name)

Update the API key user's display name. Email is identity and not editable.

入力スキーマ

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120,
      "description": "The new display name."
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false
}
🟢export_my_data

GDPR Art. 15 right-of-access export — every row PinAppAI holds about the API key's user. Sensitive columns (password hash, OAuth tokens) are server-side redacted. Personal data of OTHER reviewers is NOT included.

入力スキーマ

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🟢pinappai_get_iteration_coverage(project, iteration_id)

Read coverage metrics for an iteration: items_decided / manifest_size + items_undecided + per-reviewer decided_count + disagreement_count. Useful for the AI to summarize "you have N items still waiting on M reviewers" and identify CRs needing admin attention. Read-only.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "iteration_id": {
      "type": "string",
      "minLength": 1,
      "description": "The iteration id (it_*)."
    }
  },
  "required": [
    "project",
    "iteration_id"
  ],
  "additionalProperties": false
}
🟢pinappai_list_iterations(project, limit, before_seq)

Paginated history of iterations for a project, newest first. Each entry includes seq_no, opened_at, applied_at (NULL while open), bundle_summary, and the frozen manifest_cr_ids_json + manifest_reviewer_ids_json. Pair with pinappai_get_iteration_coverage to summarize outcomes per iteration.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "limit": {
      "description": "Max iterations to return (default 50, max 200).",
      "type": "integer",
      "minimum": 1,
      "maximum": 200
    },
    "before_seq": {
      "description": "Pagination cursor — return iterations with seq_no strictly less than this.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "project"
  ],
  "additionalProperties": false
}
🟢pinappai_list_apply_inbox(project, limit)

v3 Apply-inbox listing. Returns every change request in an Apply-eligible inbox substate (inbox_new / inbox_rejected / inbox_change_requested) with the prior cr_marked_applied event payload AND the latest reviewer/admin decision payload inlined per row. Used by /pinappai:apply to drive substate-specific edits (new = standard apply; rejected = revert via swap; change_requested = apply with new wording) in one round-trip.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "limit": {
      "description": "Max rows to return (default 100).",
      "type": "integer",
      "minimum": 1,
      "maximum": 500
    }
  },
  "required": [
    "project"
  ],
  "additionalProperties": false
}
🔴pinappai_apply_change_requests(project, applies, bundle_summary)

v3 atomic apply primitive. Takes a list of {cr_id, before_text, after_text} after the AI has edited source for each. Creates one iteration record (audit trail visible in the Project history page) and transitions every eligible CR from inbox_* state to 'in_review' atomically. Per-CR errors (CR not in eligible state, e.g. someone deferred it mid-session) are returned in the response without failing the whole batch. Editor role required.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "applies": {
      "minItems": 1,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "cr_id": {
            "type": "string",
            "minLength": 1,
            "description": "The change-request id (cr_*)."
          },
          "before_text": {
            "type": "string",
            "maxLength": 4000,
            "description": "The source-file content this CR targeted BEFORE you edited it. Stored on the cr_marked_applied event payload so admin Revert can swap byte-for-byte later. For 'inbox_rejected' CRs the AI should have already done the swap (after_text → before_text from the CR's previous cr_marked_applied event); the new before_text is the pre-revert source and after_text is the post-revert source."
          },
          "after_text": {
            "type": "string",
            "maxLength": 4000,
            "description": "The source-file content AFTER your edit."
          }
        },
        "required": [
          "cr_id",
          "before_text",
          "after_text"
        ],
        "additionalProperties": false
      },
      "description": "List of CRs to mark applied in one atomic batch."
    },
    "bundle_summary": {
      "description": "Short human-readable summary of this Apply batch — shows up in the project history page. e.g. \"applied 7 CRs across 3 pages\".",
      "type": "string",
      "maxLength": 2000
    }
  },
  "required": [
    "project",
    "applies"
  ],
  "additionalProperties": false
}
🔴pinappai_reset_review_data(project, confirm)

Permanently deletes a project's review data: all change requests (+ their event history), iterations, reviewer decisions, ALL freeform pins/comments with their screenshots, and the /changes/-page registration tables. NOT recoverable — no grace window. Requires admin role. Ask the user for explicit confirmation before calling, and prefer the /pinappai:reset-project prompt, which also offers to clean up the repo's static /changes/ page and .pinappai/last-applied.json.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "confirm": {
      "type": "boolean",
      "const": true,
      "description": "Must be literally true. The caller must have shown the user what will be deleted and received explicit confirmation first — there is no grace window; this is not recoverable."
    }
  },
  "required": [
    "project",
    "confirm"
  ],
  "additionalProperties": false
}
🔴pinappai_register_change_items(project, page_path, items)

Register the items of a freshly written /changes/ review page with the server — REQUIRED after generating or regenerating the page, or the in-page review chip and decision bars have no data. Pass every [data-pp-item] in document order with the same attribute values you put in the markup. This replaces the removed client-side self-registration: the page itself can no longer register anything. Editor role required.

入力スキーマ

{
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "minLength": 1,
      "description": "The project slug."
    },
    "page_path": {
      "description": "Path of the /changes/ page on the site. Default '/changes'.",
      "type": "string",
      "minLength": 1,
      "maxLength": 2048,
      "pattern": "^\\/[\\w\\-./]*$"
    },
    "items": {
      "minItems": 1,
      "maxItems": 2000,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "The data-pp-item value — e.g. \"pricing:hero-title\"."
          },
          "title": {
            "description": "The data-pp-title value.",
            "type": "string",
            "maxLength": 300
          },
          "target_page_url": {
            "description": "Root-relative URL of the ACTUAL page the change lives on (data-pp-page-url).",
            "type": "string",
            "maxLength": 2048
          },
          "target_source_selector": {
            "description": "CSS selector to the element on the source page (data-pp-source-selector).",
            "type": "string",
            "maxLength": 2048
          },
          "target_source_files": {
            "description": "Comma-separated source-repo file paths (data-pp-source-files).",
            "type": "string",
            "maxLength": 2048
          },
          "before_text": {
            "description": "The BEFORE text, verbatim from the page.",
            "type": "string",
            "maxLength": 4000
          },
          "after_text": {
            "description": "The AFTER text, verbatim from the page.",
            "type": "string",
            "maxLength": 4000
          },
          "applied_cr_id": {
            "description": "The originating CR id (data-pp-applied-cr-id). Items whose CR no longer exists are dropped server-side; omit only for hand-authored items.",
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      },
      "description": "Every [data-pp-item] on the page you just wrote, in DOCUMENT ORDER (order drives the review queue). The FULL active set — items you omit are deactivated server-side."
    }
  },
  "required": [
    "project",
    "items"
  ],
  "additionalProperties": false
}
🟢pinappai_get_workflow(name)

Return the full procedure for a PinAppAI guided workflow, rendered exactly as the /pinappai:<name> prompt delivers it. Call this when the user asks for one of these and this client does not surface MCP prompts. Follow the returned text verbatim and do not improvise a workflow from its name or description. Available workflows: analyze Read-only pattern analysis of change requests apply v3 PinAppAI Apply — drain the project Inbox by editing source for every Apply-eligible change… audit-review Pull recent audit-log events for the workspace and summarize unusual activity auth-help Walk through PinAppAI MCP authentication — recommend the browser-flow login first, fall back… embed-widget Embed the PinAppAI widget snippet into an EXISTING project's site, then bootstrap the… generate-changes-page Generate a temporary /changes/ review page for a multi-page rewrite remove Remove ALL PinAppAI integration from this repository (widget script, /changes/ pages, optional… reset-project Reset a project's review data to zero — permanently delete its change requests, iterations,… setup-project Walk the user through creating a new PinAppAI project from scratch — pick or create a… summarize Generate a PR description / changelog / customer email from completed work, referencing the…

入力スキーマ

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "enum": [
        "analyze",
        "apply",
        "audit-review",
        "auth-help",
        "embed-widget",
        "generate-changes-page",
        "remove",
        "reset-project",
        "setup-project",
        "summarize"
      ],
      "description": "The workflow to fetch. See the description for what each does."
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false
}

コミュニティ

このサーバーを評価する

エビデンス

最近の観測

検証済みバージョンは記録されていませんツール 38 件
検証済みバージョンは記録されていませんツール 38 件