App Development
This reference is auto-generated from the registered MCP tool providers in perspectapiworkers.
It reflects the tools exposed by the per-site Perspect MCP server.
Connection
Use the per-site MCP endpoint:
https://perspect.com/mcp/{siteName}
Authenticate with OAuth or an MCP API key using Authorization: Bearer sk_mcp_....
Tools
app_build_status
Title: Check Build Status
Check the status of the most recent build for this site. Returns status (pending, deploying, deployed, failed) and any error details. Avoid rapid loops: check no more than once every 30-60 seconds while deploying. Server enforces poll throttling while deploying. Build logs are compact by default; request full logs only when needed. Pass build_id from release_deploy when available.
Required permission: app.read
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
build_id |
string | No | — | Optional build ID from release_deploy to read a specific build log key directly |
include_full_log |
boolean | No | false |
When true, return the entire build log (can be large). Default: false |
tail_lines |
number | No | 60 |
Number of log lines to return when include_full_log=false (default: 60, max: 200) |
force_log_refresh |
boolean | No | false |
Force an immediate status+log read even if polled recently. Default: false |
Example call
{
"tool": "app_build_status",
"arguments": {
"include_full_log": false,
"tail_lines": 60,
"force_log_refresh": false
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_cancel_build
Title: Cancel Build
Cancel in-flight build(s) for this site. With build_id, cancels that build; otherwise cancels ALL queued/running builds. Cancellation flags the build(s) in the ledger (so they will not deploy) and destroys their build containers. Safety guard: cancellations are blocked while a build is fresh (<10 minutes) unless force=true is provided. After canceling, fix issues and use the security-gated release flow again.
Required permission: app.deploy
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
build_id |
string | No | — | Optional specific build to cancel (from app_build_status). If omitted, cancels all in-flight builds for the site. |
force |
boolean | No | false |
Override cancellation safety guard for emergency aborts. Default: false |
reason |
string | No | — | Optional cancellation reason recorded in deployment status/logs |
Example call
{
"tool": "app_cancel_build",
"arguments": {
"force": false
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_candidate_diff
Title: Candidate Diff
Show the immutable source delta for code review. For a build_id, compares that build's source with the live source captured when it was created. Without build_id, compares an unpublished current authored source with the live source, or falls back to the latest source-changing build. Returns candidate.sourceHandle for candidate/after-side inspection and, when a baseline exists, candidate.baseSourceHandle for before-side, deleted-file, and truncated-diff inspection. Pass either as source_handle to app_read_file and app_search so follow-up inspection remains pinned to that exact immutable archive. Use this—not app_workspace_diff—as the source of truth for Code Reviewer scope, including direct Git-triggered builds.
Required permission: app.read
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
build_id |
string | No | — | Optional immutable build candidate ID. Omit for the current authored candidate or latest source-changing build. |
max_chars |
number | No | 60000 |
Maximum diff characters to include. Default: 60000, max: 200000. |
Example call
{
"tool": "app_candidate_diff",
"arguments": {
"max_chars": 60000
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_check
Title: Check App
Run deterministic app validation after a coherent change set. fast runs route registration checks plus SDK misuse scans without full TypeScript compilation. release runs fast checks plus React Router typegen/local TypeScript and a workspace diff summary against the current R2 source checkpoint.
Required permission: app.read
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
level |
string | No | "fast" |
Validation depth. Default: fast. Allowed: fast, release. |
diff_max_chars |
number | No | 60000 |
Maximum diff characters to include when level=release. Default: 60000. |
Example call
{
"tool": "app_check",
"arguments": {
"level": "fast",
"diff_max_chars": 60000
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_delete_file
Title: Delete App File
Delete one existing app source file. Read the file with app_read_file before deleting it, then pass the returned read_token or metadata.sha256 so stale deletes are rejected. Only deletes regular files, not directories or symlinks. The tool returns a removal diff and rolls the sandbox file back if durable source checkpointing fails.
Required permission: app.write
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path |
string | Yes | — | File path relative to workspace root (e.g., 'app/routes/old.tsx') |
read_token |
string | No | — | read_token returned by app_read_file for this path. Required unless expected_sha256 is supplied. |
expected_sha256 |
string | No | — | metadata.sha256 returned by app_read_file. May be used instead of read_token for staleness checking. |
dry_run |
boolean | No | false |
When true, validate and return the deletion diff without deleting. Default false. |
Example call
{
"tool": "app_delete_file",
"arguments": {
"path": "string",
"dry_run": false
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_dependency_audit
Title: Audit App Dependencies
Run a bounded npm dependency vulnerability audit in an isolated sandbox workspace copy without applying fixes or persisting source changes. Use this for security reviews of package.json/package-lock.json; the audit validates the checked-in dependency graph, including required platform production dependencies when present, and fails closed if platform dependency injection would require lockfile regeneration. The result identifies the exact authoritative source key, source ETag, and package.json SHA-256 it inspected. When it reports a platform dependency or lockfile mismatch, have an App Developer pass remediation.arguments unchanged to app_sync_platform_dependencies before retrying the audit. scope=production runs npm audit with --omit=dev; scope=all includes dev dependencies. This tool never runs npm audit fix. Execution is restricted to the site's ready Security Auditor agent or a ready agent whose role explicitly grants this tool by exact name; calls from any other agent are rejected.
Required permission: app.audit
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
scope |
string | No | "production" |
Dependency scope to audit. production omits dev dependencies. Default: production. Allowed: production, all. |
audit_level |
string | No | "high" |
npm audit failure threshold. The report still includes all severities. Default: high. Allowed: info, low, moderate, high, critical. |
timeout_seconds |
number | No | 120 |
Timeout in seconds. Default: 120, max: 180. |
Example call
{
"tool": "app_dependency_audit",
"arguments": {
"scope": "production",
"audit_level": "high",
"timeout_seconds": 120
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_edit_file
Title: Edit App File
Perform exact-string replacements in app source files — one replacement via the top-level fields, or MANY replacements (across one or more files) in a single call via edits[]. PREFER edits[] whenever a change needs more than one replacement: the whole batch validates first, applies all-or-nothing, and persists once, so it is far faster than one call per replacement. Read a file with app_read_file before its first edit and pass the returned read_token or metadata.sha256; within a batch, only the first edit touching a file needs it, and every response returns a fresh read_token per file, so re-reading after edits is unnecessary. Each old_string must match the normalized file content exactly and uniquely unless replace_all=true. Use old_string="" only to create a missing file or fill an empty file. The tool rejects stale reads, ambiguous matches, notebooks, binary content, symlinks, unsupported paths, and no-op edits; on any failing edit in a batch, nothing is written.
Required permission: app.write
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path |
string | Yes | — | Single-edit mode: file path relative to workspace root (e.g., 'app/routes/home.tsx'). Omit when using edits[]. |
old_string |
string | Yes | — | Single-edit mode: exact text to replace from app_read_file output. Use an empty string only when creating a missing file or filling an empty file. |
new_string |
string | Yes | — | Single-edit mode: replacement text. |
replace_all |
boolean | No | false |
When true, replace every occurrence. Default false requires old_string to be unique. |
read_token |
string | No | — | read_token returned by app_read_file for this path. Required for existing files unless expected_sha256 is supplied. |
expected_sha256 |
string | No | — | metadata.sha256 returned by app_read_file. May be used instead of read_token for staleness checking. |
edits |
array<object> | No | — | Batch mode: ordered list of replacements applied in sequence, across one or more files, validated together and written all-or-nothing with a single persistence checkpoint. Do not combine with the top-level path/old_string/new_string fields. Later edits to the same file operate on the result of earlier ones; only the first edit touching an existing file needs read_token/expected_sha256. |
dry_run |
boolean | No | false |
When true, validate and return the diff without writing. Default false. Applies to the whole batch when edits[] is used. |
Example call
{
"tool": "app_edit_file",
"arguments": {
"path": "string",
"old_string": "string",
"new_string": "string",
"replace_all": false,
"dry_run": false
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_exec
Title: Run Shell Command
Run a shell command in the sandbox workspace. Use only for tasks not covered by dedicated tools: sandbox dependency installation/verification, package diagnostics, or package scripts. Do not use for reading files, listing files, searching, or writing files; use app_read_file, app_list_files, app_search, app_edit_file, and app_write_file instead. app_exec does not persist source-file mutations: shell commands that change app source files are rejected and rolled back. Only add dependencies that are compatible with React Router v7 on Cloudflare Workers; avoid Node-only/general-purpose runtime tooling. Commands run in the /workspace directory. Default timeout is 120 seconds; set timeout_seconds for longer operations.
Required permission: app.write
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
command |
string | Yes | — | Shell command to execute (e.g., 'npm ls', 'ls -la build/') |
timeout_seconds |
number | No | — | Timeout in seconds (default: 120, max: 600) |
Example call
{
"tool": "app_exec",
"arguments": {
"command": "string"
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_git_status
Title: Git Integration Status
Check if git integration is enabled and view sync status. Returns repo URL, branch, last synced commit, and sync direction. Read-only — does not modify anything.
Required permission: app.read
Parameters
This tool accepts no arguments.
Example call
{
"tool": "app_git_status",
"arguments": {}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_init
Title: Initialize App Workspace
Optionally call upfront to prefetch the file list and common context files (app/routes.ts, app/root.tsx, package metadata, and .perspect scaffold state). Other app_* tools initialize the workspace automatically on first use — call app_init only when you want this context returned explicitly at the start of a session. NOT required for CMS tools (page_*, product_*, category_*, media_*) — those work independently.
Required permission: app.read
Parameters
This tool accepts no arguments.
Example call
{
"tool": "app_init",
"arguments": {}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_list_files
Title: List App Files
List all files in the app workspace. Returns paths relative to the workspace root. Use to explore the project structure before reading or writing files.
Required permission: app.read
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
directory |
string | No | — | Subdirectory to list (e.g., 'app/routes'). Defaults to root. |
Example call
{
"tool": "app_list_files",
"arguments": {}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_read_file
Title: Read App File
Read the contents of a file in the app workspace, or from an immutable candidate when source_handle or build_id is provided. For a byte-sensitive Git filename returned by app_candidate_diff or app_search (for example raw bytes, controls, bidi marks, quotes, backslashes, or surrounding whitespace), pass its pathBytesBase64 as path_bytes_base64 instead of path. Pass candidate.sourceHandle from app_candidate_diff for the candidate/after side, or candidate.baseSourceHandle for the immutable baseline/before side (including deleted files and omitted hunks in a truncated diff); build_id is the historical candidate alternative and is mutually exclusive. Without either selector, exact-byte reads target the current workspace and are read-only. Ordinary current-workspace reads return normalized UTF-8 file content, metadata, and a read_token required for safe edits or overwrites of existing files; exact-byte current-workspace reads are read-only and return no mutation token. Immutable candidate reads are read-only and return sourceHandle or candidateBuildId instead of a mutation read_token. You do not need to re-read a file after editing it: app_edit_file and app_write_file return a fresh read_token for the updated content. Pass offset/limit to inspect a line range of a large file WITHOUT pulling the whole thing into context. A ranged read is read-only: it returns no whole-file sha256 and its read_token is rejected by every mutation tool, so read the file in full before editing, overwriting or deleting it.
Required permission: app.read
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path |
string | Yes | — | UTF-8 file path relative to workspace root (e.g., 'app/routes/home.tsx'). Mutually exclusive with path_bytes_base64. |
path_bytes_base64 |
string | No | — | Exact base64-encoded relative filename bytes from app_candidate_diff or app_search pathBytesBase64. Mutually exclusive with path. Include source_handle (preferred) or build_id for an immutable candidate; omit both for a read-only current-workspace read. |
build_id |
string | No | — | Optional immutable build candidate ID. Mutually exclusive with source_handle. |
source_handle |
string | No | — | Expiring opaque candidate.sourceHandle or candidate.baseSourceHandle returned by app_candidate_diff. It is scoped to this site and MCP session and pins that exact immutable source. Mutually exclusive with build_id. |
offset |
integer | No | — | 1-based line number to start reading from. Omit to read from the top. |
limit |
integer | No | — | Maximum number of lines to return. Omit to read to the end. |
Example call
{
"tool": "app_read_file",
"arguments": {
"path": "string"
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_scaffold_feature
Title: Scaffold Feature Routes
Generate ready-to-use React Router routes wired to perspectapi-ts-sdk for common features. Supported features: blog, newsletter, page. Also updates app/routes.ts to register generated routes and the Perspect webhook route, and ensures the shared Perspect SDK client/cache wiring files are present (including PERSPECT_CACHE-backed caching support).
Required permission: app.write
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
feature |
string | Yes | — | Feature to scaffold Allowed: blog, newsletter, page. |
overwrite |
boolean | No | false |
When true, overwrite existing generated route files and managed platform files |
allow_rerun |
boolean | No | false |
When true, allow re-running scaffold after the feature has already been scaffolded. Existing files are still preserved unless overwrite=true. |
Example call
{
"tool": "app_scaffold_feature",
"arguments": {
"feature": "blog",
"overwrite": false,
"allow_rerun": false
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_search
Title: Search Code
Search across current source files, or an immutable candidate when source_handle or build_id is provided, using ripgrep. Fast, regex-capable code search. Returns structured matches with display path, exact pathBytesBase64/pathEncoding identity, line number, and content, so delimiter-bearing or byte-sensitive filenames remain unambiguous. Pass candidate.sourceHandle from app_candidate_diff to search the candidate/after side, or candidate.baseSourceHandle to search the immutable baseline/before side; build_id is the historical candidate alternative and is mutually exclusive. Automatically excludes node_modules, build output, and .react-router directories.
Required permission: app.read
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
pattern |
string | Yes | — | Search pattern (regex supported, e.g., 'import.*useState', 'TODO|FIXME') |
build_id |
string | No | — | Optional immutable build candidate ID. Mutually exclusive with source_handle. |
source_handle |
string | No | — | Expiring opaque candidate.sourceHandle or candidate.baseSourceHandle returned by app_candidate_diff. It is scoped to this site and MCP session and pins that exact immutable source. Mutually exclusive with build_id. |
glob |
string | No | — | File glob filter (e.g., '.tsx', '.css', 'app/routes/**') |
case_sensitive |
boolean | No | — | Case-sensitive search (default: false) |
max_results |
number | No | — | Maximum number of matching lines to return (default: 100) |
Example call
{
"tool": "app_search",
"arguments": {
"pattern": "string"
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_sync_platform_dependencies
Title: Sync Platform Dependencies
Synchronize required platform production dependencies in package.json and regenerate the checked-in npm lockfile with lifecycle scripts disabled. Use this dedicated write tool when app_dependency_audit reports missing or outdated platform dependencies or a stale lockfile; do not use app_exec or npm audit fix for that remediation. When app_dependency_audit returns remediation.arguments, pass the expected source key, source ETag, and package.json SHA-256 unchanged so the tool refuses cross-snapshot remediation. The operation validates the regenerated lockfile, persists package.json plus the npm lockfile as one guarded source checkpoint, and rolls back on failure. Run app_typecheck afterward to detect host-app API incompatibilities before requesting another audit. If regeneration against the checked-in lockfile fails with npm ERESOLVE, the tool automatically retries once in an isolated manifest-only staging copy — no lockfile, yarn.lock, or node_modules can anchor the resolver — and adopts the result (reported as lockfileResolvedFresh: true); an ERESOLVE that persists in the fresh resolution means the manifest's declared ranges themselves conflict.
Required permission: app.write
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
expected_source_key |
string | No | — | Optional source key returned by app_dependency_audit remediation.arguments. The sync fails without mutation if the authoritative source changed. |
expected_source_etag |
string | No | — | Optional source ETag returned by app_dependency_audit remediation.arguments. The sync fails without mutation if the authoritative source changed. |
expected_package_json_sha256 |
string | No | — | Optional package.json SHA-256 returned by app_dependency_audit remediation.arguments. The sync fails without mutation if package metadata changed. |
Example call
{
"tool": "app_sync_platform_dependencies",
"arguments": {}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_typecheck
Title: Typecheck App
Run React Router type generation when available, then TypeScript type-checking using the project's local binaries in the sandbox workspace. Call this once after a coherent set of source changes, before requesting Security Auditor review and Release Manager deployment. Returns errors if any, or confirms the code is clean. Only a successful app_typecheck result satisfies this verification gate; manual tsc, npx, or app_exec checks are not substitutes. If the result includes remediation, perform it exactly and then rerun app_typecheck.
Required permission: app.read
Parameters
This tool accepts no arguments.
Example call
{
"tool": "app_typecheck",
"arguments": {}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_workspace_diff
Title: Workspace Diff
Show changed files and a unified diff between the current workspace and the current R2 source checkpoint. Use this for uncheckpointed workspace drift and release handoffs. For Code Reviewer scope, use app_candidate_diff instead.
Required permission: app.read
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
max_chars |
number | No | 60000 |
Maximum diff characters to include. Default: 60000, max: 200000. |
Example call
{
"tool": "app_workspace_diff",
"arguments": {
"max_chars": 60000
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
app_write_file
Title: Write App File
Create or replace a complete app source file. Use this for new files or intentional full-file replacement; prefer app_edit_file for targeted changes to existing files. For existing files, pass overwrite=true plus the read_token or metadata.sha256 from app_read_file so stale writes are rejected. The tool rejects notebooks, binary content, symlinks, oversized files, unsupported paths, and unguarded overwrites; it returns a diff after validation.
Required permission: app.write
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path |
string | Yes | — | File path relative to workspace root (e.g., 'app/routes/home.tsx') |
content |
string | Yes | — | Complete final UTF-8 file content. |
overwrite |
boolean | No | false |
Required and must be true when replacing an existing file. Ignored for new files. |
read_token |
string | No | — | read_token returned by app_read_file for this path. Required for existing files unless expected_sha256 is supplied. |
expected_sha256 |
string | No | — | metadata.sha256 returned by app_read_file. May be used instead of read_token for staleness checking. |
dry_run |
boolean | No | false |
When true, validate and return the diff without writing. Default false. |
Example call
{
"tool": "app_write_file",
"arguments": {
"path": "string",
"content": "string",
"overwrite": false,
"dry_run": false
}
}
Output schema
{
"type": "object",
"additionalProperties": true
}
This page is generated from the registered MCP tool providers. Do not edit it by hand.