Skip to content
Perstack

perstack.toml Reference

# Runtime configuration
model = "claude-sonnet-4-5"
reasoningBudget = "medium"
runtime = "docker"
maxSteps = 50
maxRetries = 3
timeout = 60000
envPath = [".env", ".env.local"]
[provider]
providerName = "anthropic"
[provider.setting]
headers = { "X-Custom-Header" = "value" }
# Expert definition
[experts."my-expert"]
version = "1.0.0"
description = "TypeScript and React code reviewer with security analysis"
instruction = """
You are a code reviewer specializing in TypeScript and React.
Review code for type safety, performance, accessibility, and security.
Provide constructive feedback with specific examples.
"""
delegates = ["@org/security-expert", "performance-analyzer"]
# Base skill (optional)
[experts."my-expert".skills."@perstack/base"]
type = "mcpStdioSkill"
description = "Base filesystem and shell tools"
command = "npx"
packageName = "@perstack/base"
# MCP Stdio skill
[experts."my-expert".skills."web-search"]
type = "mcpStdioSkill"
description = "Search the web for documentation and best practices"
rule = "Use for finding up-to-date documentation and security advisories"
command = "npx"
packageName = "exa-mcp-server"
pick = ["web_search_exa"]
requiredEnv = ["EXA_API_KEY"]
# MCP SSE skill
[experts."my-expert".skills."static-analyzer"]
type = "mcpSseSkill"
description = "Remote static analysis service"
endpoint = "https://api.example.com/static-analysis"
pick = ["analyze_typescript"]
omit = ["analyze_python"]
# Interactive skill
[experts."my-expert".skills."user-interaction"]
type = "interactiveSkill"
description = "Interactive tools for user feedback"
rule = "Use when clarification is needed from the user"
[experts."my-expert".skills."user-interaction".tools."askUser"]
description = "Ask user for input or clarification"
inputJsonSchema = """
{
"type": "object",
"properties": {
"question": {
"type": "string",
"description": "Question to ask the user"
}
},
"required": ["question"]
}
"""

Top-level settings that apply to all Experts in the file.

model = "claude-sonnet-4-5"
reasoningBudget = "medium"
runtime = "docker"
maxSteps = 100
maxRetries = 10
timeout = 60000
[provider]
providerName = "anthropic"
[provider.setting]
baseUrl = "https://custom-endpoint.example.com"
headers = { "X-Custom-Header" = "value" }
FieldTypeDescription
modelstringModel name
reasoningBudgetstring or numberNative LLM reasoning budget (minimal, low, medium, high, or token count)
runtimestringExecution runtime (docker, local, cursor, claude-code, gemini)
maxStepsnumberMaximum steps per run
maxRetriesnumberMaximum retry attempts
timeoutnumberTimeout per generation (ms)

Configure LLM provider under [provider] table.

[provider]
providerName = "anthropic" # Required: anthropic, google, openai, ollama, azure-openai, amazon-bedrock, google-vertex
[provider.setting]
# Provider-specific options (all optional)
FieldTypeDescription
providerNamestringLLM provider name (required)
settingobjectProvider-specific settings (optional)

Anthropic (providerName = "anthropic")

SettingTypeDescription
baseUrlstringCustom API endpoint
headersobjectCustom HTTP headers

Google (providerName = "google")

SettingTypeDescription
baseUrlstringCustom API endpoint
headersobjectCustom HTTP headers

OpenAI (providerName = "openai")

SettingTypeDescription
baseUrlstringCustom API endpoint
organizationstringOpenAI organization ID
projectstringOpenAI project ID
namestringCustom provider name
headersobjectCustom HTTP headers

Ollama (providerName = "ollama")

SettingTypeDescription
baseUrlstringOllama server URL
headersobjectCustom HTTP headers

Azure OpenAI (providerName = "azure-openai")

SettingTypeDescription
resourceNamestringAzure resource name
apiVersionstringAzure API version
baseUrlstringCustom API endpoint
headersobjectCustom HTTP headers
useDeploymentBasedUrlsbooleanUse deployment-based URLs

Amazon Bedrock (providerName = "amazon-bedrock")

SettingTypeDescription
regionstringAWS region

Google Vertex AI (providerName = "google-vertex")

SettingTypeDescription
projectstringGCP project ID
locationstringGCP location (e.g., us-central1)
baseUrlstringCustom API endpoint
headersobjectCustom HTTP headers

DeepSeek (providerName = "deepseek")

SettingTypeDescription
baseUrlstringCustom API endpoint
headersobjectCustom HTTP headers

See Providers and Models for available models and environment variables.

Define Experts under [experts."expert-key"].

[experts."my-expert"]
version = "1.0.0"
description = "Brief description of the expert"
instruction = """
Detailed instructions for the expert's behavior.
Can be multi-line.
"""
delegates = ["other-expert", "@org/another-expert"]
FieldTypeRequiredDescription
versionstringNoSemantic version (default: 1.0.0)
minRuntimeVersionstringNoMinimum runtime version
descriptionstringNoBrief description (max 2048 chars)
instructionstringYesBehavior instructions (max 20KB)
delegatesstring[]NoExperts this Expert can delegate to
tagsstring[]NoTags for categorization

Define skills under [experts."expert-name".skills."skill-name"].

[experts."my-expert".skills."my-skill"]
type = "mcpStdioSkill"
description = "Skill description"
rule = "Additional usage guidelines"
command = "npx"
packageName = "mcp-server-package"
args = ["-y", "additional-args"]
pick = ["tool1", "tool2"]
omit = ["tool3"]
requiredEnv = ["API_KEY"]
allowedDomains = ["api.example.com", "*.example.com"]
FieldTypeRequiredDescription
typeliteralYes"mcpStdioSkill"
descriptionstringNoSkill description
rulestringNoAdditional usage guidelines
commandstringYesCommand to execute (npx, python, uvx)
packageNamestringNoPackage name (for npx)
argsstring[]NoCommand-line arguments
pickstring[]NoTools to include (whitelist)
omitstring[]NoTools to exclude (blacklist)
requiredEnvstring[]NoRequired environment variables
allowedDomainsstring[]NoAllowed domains for network access (docker runtime)

Punycode domains (containing xn-- labels) are rejected to prevent homograph attacks. Only ASCII domains are allowed.

[experts."my-expert".skills."remote-skill"]
type = "mcpSseSkill"
description = "Remote MCP server"
endpoint = "https://api.example.com/mcp"
pick = ["tool1"]
omit = ["tool2"]
allowedDomains = ["api.example.com"]
FieldTypeRequiredDescription
typeliteralYes"mcpSseSkill"
descriptionstringNoSkill description
rulestringNoAdditional usage guidelines
endpointstringYesMCP server URL
pickstring[]NoTools to include
omitstring[]NoTools to exclude
allowedDomainsstring[]NoAllowed domains for network access (docker runtime)

Punycode domains (containing xn-- labels) are rejected to prevent homograph attacks. Only ASCII domains are allowed.

[experts."my-expert".skills."user-interaction"]
type = "interactiveSkill"
description = "User interaction skill"
[experts."my-expert".skills."user-interaction".tools."askUser"]
description = "Ask user for input"
inputJsonSchema = """
{
"type": "object",
"properties": {
"question": { "type": "string" }
},
"required": ["question"]
}
"""
FieldTypeRequiredDescription
typeliteralYes"interactiveSkill"
descriptionstringNoSkill description
rulestringNoAdditional usage guidelines
toolsobjectYesTool definitions

Tool definition:

FieldTypeRequiredDescription
descriptionstringNoTool description
inputJsonSchemastringYesJSON Schema for input