Skip to content
Documentation menu
Building agents

Manifest spec

An agent manifest describes everything an agent is — its prompt, its tools, how it reaches a client, and what credentials it needs. A manifest only describes; it never ships executable code.

Core fields

Every manifest carries a small core: a name, an optional description, the system prompt, example prompts, and the tools the agent can use. A plain recipe needs only these; a tool-using (doer) agent adds the layer below that lets it actually do things — tool actions, credential slots, guardrails, delivery, and client targets. You rarely write a manifest by hand: the submit builder and the GitHub/manifest importer assemble and validate it for you.

FieldTypeNotes
namestring3–80 characters.
descriptionstring?Up to 4000 characters.
system_promptstringThe agent’s instruction set (50–20,000 characters).
toolsTool[]Up to 40 tools (see below).
example_promptsstring[]1–5 example prompts that show the agent in use.
compatibilityobject?Optional per-client version hints (Claude / ChatGPT / Gemini).

Tools

A tool is a named capability the agent can call. A tool carries an MCP-shaped name, a description, an optional JSON-Schema input_schema / output_schema, optional behaviour annotations, and an optional action binding that says what it does when called.

Annotations map directly onto how clients and runtimes gate a tool: readOnlyHint, destructiveHint, idempotentHint, and openWorldHint.

Actions

A tool's action is the only thing that does work, and it comes from a fixed, auditable set of binding kinds — never arbitrary code:

  • http — an HTTP request. Declares method, a url (which may contain {param} placeholders bound from the tool input), optional headers and body_template, and an optional auth_ref pointing at a credential slot.
  • prompt-template — a templated prompt the runtime fills and returns.
  • compose — call a tool on another agent by agent and tool. Declared now for forward-compatibility with multi-agent execution.

Credential slots

When an action needs a secret, the manifest declares a credential slot and the action references it by auth_ref. Each slot has a ref, a human label, an optional env var name, and — importantly — allowed_hosts:

  • allowed_hosts binds the secret to an audience. The runtime only attaches the credential when the request's destination host matches (exact or subdomain).
  • A slot with no allowed host is refused — a credential without an audience is a cross-host exfiltration risk.
  • type describes the value shape so the install UI renders the right input: string (plain text, the default), secret (masked), or json (a JSON blob — e.g. a service-account key file).
  • description is optional buyer-facing help text shown above the field at install time (e.g. “Paste your GA4 service-account JSON key”). It never holds a secret.
  • required marks whether the buyer must supply the slot. Defaults to true; set it false for a credential the agent degrades without.

Guardrails

A doer agent can declare guardrails the platform enforces. The manifest only declares the rails — the FindAgent gateway, not the agent's own code, enforces them, the same way allowed_hosts and credential slots are declared in the manifest but policed by the runtime. A creator may only tighten the rails; mandatory ones can never be disabled.

  • input — applied before a call reaches the agent. max_length caps the payload size, deny_patterns is a prompt-injection deny-list, and pii_redaction redacts categories (credit_card, email, phone, iban, national_id, and more) from the payload.
  • output — applied after the agent returns. secret_leak_scan is mandatory: the platform always runs it, and a manifest that tries to set it false fails validation. An optional schema validates the result shape.
  • actions — a per-tool policy keyed by tool name: approval (none or human), a spend cap max_amount, a rate_limit (e.g. 10/hour), and idempotent (whether the gateway may safely auto-retry the action after a crash).

Delivery, kind, exec, and targets

FieldValuesWhat it means
kindstatic-recipe · mcp-tool · autonomous-agent · skills-bundle · code-bundleThe shape of the agent. Defaults to static-recipe.
deliveryprompt · mcp.stdio · mcp.remoteHow a client reaches the agent — as a paste-in recipe, a local stdio MCP server, or a hosted remote MCP URL.
execuser-local · findagent-hostedWhere it runs. Defaults to user-local.
targetsclaude-desktop · claude-code · chatgpt · cursor · vscode · gemini-cli · windsurf · cli · webWhich clients the agent is meant for.
authnone · api-key · oauth-deviceFindAgent identity auth, distinct from per-agent external credentials.
code-bundle runs in a sandbox
The code-bundle kind (see the code-bundle section below) runs a creator's real code inside an isolated sandbox — never on your machine as part of a normal install, and never on FindAgent's own infrastructure. Code agents are scanned and reviewed before they publish. See the security model.

Skills-bundle agents

A kind: "skills-bundle" manifest packages a whole skills-or-rules repository — Claude Agent Skills, Cursor / Windsurf / Continue rules, an AGENTS.md, and similar — as a single agent. Each skill is declarative content (a Markdown SKILL.md), so the runtime serves it as an MCP prompt rather than executing it. The bundle adds:

  • skills_source — an R2 reference (kind: "r2" + key) to the imported skill files the CLI downloads and the runtime serves.
  • skills — the per-skill discovery metadata (id, name, description, tags) synthesized from each skill's frontmatter.
  • router_skill_id — optional id of the entry/router skill the runtime can surface first.

Because skill bodies are never executed, a skills bundle adds no code-execution surface — the same declarative keystone as a doer agent. Importing an arbitrary public repository is an admin-only seeding path; creators bring their own repo through the GitHub- connected submit flow.

Code-bundle agents

A separate manifest shape covers agents whose behaviour is real creator code rather than declared tool bindings. A code-bundle manifest sets kind: "code-bundle" and adds:

  • entrypoint — the handler the runtime invokes: a bundle-relative path (e.g. src/agent.ts) and the export name to call (defaults to handler).
  • runtime — the execution runtime: a kind (node or python) and an optional version hint the sandbox resolves to a concrete image.
  • allowed_hosts — the default-deny egress allowlist; the only hosts the sandbox network policy lets the bundle reach.
  • mcp — how the bundle is exposed over MCP: mode: "wrap" (the runtime auto-generates an MCP server around the entrypoint) or mode: "native" (the bundle ships its own MCP server, declaring the command + args that start it).
  • ui — an optional static frontend (a bundle-relative path) served later inside a sandboxed iframe; absent means no UI.
  • env — a declared non-secret env contract (UPPER_SNAKE names + descriptions). Secrets never go here; they flow through audience-bound credential_slots, the same slot type a doer agent uses.

A code-bundle manifest reuses the same credential_slots, guardrails, and skills shapes. The security keystone is unchanged: the manifest only describes a bundle — storing, scanning, and sandboxed execution of the referenced code are platform responsibilities, and the bundle runs only inside the isolated sandbox, never on your machine during a normal install.

Example

A small doer agent with one HTTP tool and a host-bound credential slot:

findagent.json
{
  "name": "GA Report Builder",
  "description": "Pulls a traffic summary and writes it to a sheet.",
  "system_prompt": "You are a focused analytics assistant ...",
  "kind": "mcp-tool",
  "category": "analytics",
  "tools": [
    {
      "name": "get_traffic_summary",
      "description": "Fetch a traffic summary for a date range.",
      "input_schema": { "type": "object", "properties": { "range": { "type": "string" } } },
      "annotations": { "readOnlyHint": true },
      "action": {
        "type": "http",
        "method": "GET",
        "url": "https://api.example.com/v1/traffic?range={range}",
        "auth_ref": "analytics_token"
      }
    }
  ],
  "credential_slots": [
    {
      "ref": "analytics_token",
      "label": "Analytics API token",
      "env": "ANALYTICS_TOKEN",
      "allowed_hosts": ["api.example.com"]
    }
  ],
  "example_prompts": ["Summarize last week's traffic."],
  "delivery": { "mcp": { "stdio": { "command": "findagent-mcp", "args": ["run", "ga-report-builder"] } } },
  "exec": "user-local",
  "targets": ["claude-desktop", "cursor", "cli"]
}