Skip to content

Manifest format

Every Patch tool is a single Python file. The manifest is YAML in commented frontmatter inside # --- markers (so the file is valid Python).

Example

1.0.0
# ---
# name: extract_pdf_table
# description: Extract tables from a PDF file as JSON.
# inputs:
# - name: pdf_path
# type: string
# description: Absolute path to the PDF file.
# tainted_ok: true
# outputs:
# type: array
# items: object
# capabilities:
# network: false
# filesystem: read-only
# human_confirm: false
# runtime:
# language: python
# python_version: "3.12"
# packages: ["pdfplumber==0.11.4"]
# external_auth: []
# generated_by: claude-opus-4-7
# generated_at: 2026-05-04T12:34:56Z
# ---
import pdfplumber
import json
import sys
def main(pdf_path: str):
with pdfplumber.open(pdf_path) as pdf:
return [page.extract_tables() for page in pdf.pages]
if __name__ == "__main__":
args = json.loads(sys.stdin.read())
print(json.dumps(main(**args)))

Fields

Top-level

FieldTypeRequiredNotes
namestringyessnake_case, lowercase letters/digits/underscore. Globally unique in the registry.
versionstringyesStrict semver x.y.z. New content = new version, never overwrite.
descriptionstringyesOne sentence. Sanitized + quarantine-LLM-checked at registry contribute time.
inputsarrayyes (can be [])See below.
outputsobjectyes{type, description?, items?}.
capabilitiesobjectyes{network, filesystem, human_confirm}.
runtimeobjectyes{language, python_version, packages}.
external_autharrayoptionalScope labels like ["gmail.read"].
generated_bystringoptional"claude-opus-4-7" for LLM-generated tools.
generated_atstringoptionalISO 8601 UTC.

inputs[]

FieldTypeNotes
namestringArgument name on the Python main() function.
typeenumstring / number / integer / boolean / array / object.
descriptionstringOne sentence.
requiredbool, default trueIf false, the tool’s main() should provide a default.
defaultanyOptional.
tainted_okbool, default falseIf true, this input may legitimately receive untrusted content. The runtime won’t block tainted data from flowing in.
itemsobjectFor array types — {type: "string"}, etc.

capabilities

FieldTypeNotes
networkboolIf false, sandbox boots with allowInternetAccess: false. Enforced at runtime.
filesystemenumnone / read-only / read-write. Not yet enforced in v0.4 — declared only. v0.4.x.
human_confirmboolIf true, the runtime returns confirmation_required instead of executing. The host AI must surface to the user; only after explicit approval does patch_confirm_action(token) actually run the call.

runtime

FieldTypeNotes
languageliteralAlways python.
python_versionstring"3.12".
packagesarrayPinned versions like ["requests==2.32.3"]. Each package must match ^[a-zA-Z0-9._-]+==\d+(\.\d+){0,2}$.

external_auth

Array of <provider>.<scope> strings:

external_auth:
- gmail.read
- slack.send_message

When present, the runtime mints a short-lived Arcade-scoped token before invocation and injects it as PATCH_ACCESS_TOKEN env var. The user’s refresh token stays at Arcade.

Supported providers in v0.4: gmail, google_calendar, slack, github, linear. (Arcade integration is a stub in v0.4 — see threat model.)

Source body

After the closing # ---, the file is a normal Python script that:

  • Defines a top-level main(...) whose parameters match manifest.inputs.
  • Reads its arguments from stdin as a single JSON object: args = json.loads(sys.stdin.read()).
  • Prints exactly one line of JSON to stdout: print(json.dumps(main(**args))).

The script must NOT perform side effects at import time. All work happens inside main.