Running locally

Your machine, your API keys, your MCP connections.

Two entry points, and they produce the same directory. Start with Pi to write the files yourself, or with the introspection CLI to have an agent build them with you.

Start with Pi

Install the extension once, then point Pi at any recipe directory. Clone one that already runs, read it, then change the parts where your work is different.

pi install npm:@introspection-ai/recipes   # once per machine

git clone https://github.com/introspection-recipes/template-claude
pi --recipe ./template-claude

That one has no dependencies, so there is nothing to install inside it. To start from nothing instead, the two files in the smallest recipe are the entire requirement: no build step, no install store, no publish command. Requires Node.js 24 or later and Pi ^0.82.

Start with Introspection

The plugin acts as a forward-deployed engineer: it scaffolds the package and works through your domain with you until the method is written down as skills and the standard as judges. What it produces is the same directory, so you can start here and keep working in Pi, or the reverse.

npm install -g @introspection-ai/cli
introspection init     # scaffold a recipe, with the agent that builds it
introspection local    # launch Pi against it

Model API keys

Locally, credentials come from your environment. A recipe never names an environment variable, which is why the same package also runs on a host that supplies credentials another way. The variable is derived from the provider in model.name.

Provider prefixReads
anthropic/ANTHROPIC_API_KEY or ANTHROPIC_OAUTH_TOKEN
openai/OPENAI_API_KEY
google/ or gemini/GEMINI_API_KEY
openrouter/OPENROUTER_API_KEY
anything else<PROVIDER>_API_KEY
export ANTHROPIC_API_KEY='sk-ant-…'
pi --recipe .
// From your own process, omit credentials to read the same variables.
const handle = await createAgentSession({ recipe, agentName: "agent" });

A missing key is a launch failure, not a failure three tool calls in. Credential resolution happens before the session starts and raises RecipeCredentialError naming the provider it wanted.

MCP endpoints

The package declares which servers a recipe may use. Where those servers actually live is local configuration, because it differs per machine and per environment.

.pi/mcp.local.json
{
  "servers": [
    {
      "id": "contacts",
      "transport": "streamable_http",
      "url": "https://contacts.example.com/mcp",
      "headers": {
        "Authorization": "Bearer ${CONTACTS_MCP_TOKEN}"
      }
    }
  ]
}

Header values stay environment references and resolve at launch, so no token is ever written into the workspace. Export it first:

export CONTACTS_MCP_TOKEN='…'
pi --recipe .
// The same file, read explicitly instead of by convention.
await createAgentSession({
  recipe,
  agentName,
  mcpBindingsPath: ".pi/mcp.local.json",
});

OAuth servers

Declare auth: "oauth" on a local server definition to enable it.

.pi/mcp.local.json
{
  "servers": [
    {
      "id": "linear",
      "transport": "streamable_http",
      "url": "https://mcp.linear.app/mcp",
      "auth": "oauth",
      "oauthClientSecretEnv": "LINEAR_OAUTH_CLIENT_SECRET",
      "oauthRedirectUrl": "http://127.0.0.1:8787/callback"
    }
  ]
}

A recipe session uses cached credentials only and never opens a browser. That is deliberate: an agent cannot authenticate itself into a system you had not already connected. Complete or refresh the flow yourself and retry. A launch projects your local definitions into .pi/mcporter.json, so authenticate against that:

npx mcporter auth linear --config .pi/mcporter.json

Until then the agent gets a deployment-neutral message telling it to ask you to authenticate outside the session and retry, reported by mcp run --json-errors as authentication_required.

What to commit

FileCommit it?
.pi/mcp.local.jsonNo. It carries your endpoints and tokens
.pi/mcp.local.example.jsonYes, when a binding template helps the next person
.pi/mcporter.jsonNo. A launch regenerates it
Everything else in the recipeYes. That is the deliverable

Environment variables inside a run

recipe-owned tools receive the selected path and agent as PI_RECIPE_DIR and PI_AGENT_NAME. PI_ASK_USER_AUTO_APPROVE makes interactions resolve without a human, which is what you want in CI.