Lampson as an engine
Agents as files
Besides the agents that ship with Lampson (build, plan, review, explore), you can define your own in a file. An agent is data, not code: its prompt, the tools it may use, its permissions and its model.
{
"id": "tienda",
"description": "Serves the bakery's customers over chat",
"base": "none",
"system": "You are the assistant of Sol Bakery. Read the catalog before answering about prices or stock. Never make up products or discounts.",
"tools": [{"name": "read", "paths": [".lampson/tienda/*"]}],
"permission": "strict",
"steps": 6,
"budget_tokens": 40000,
"model": {"provider": "", "model": ""}
}
Save it as .lampson/agents/tienda.agent.json in your project: the file name must be <id>.agent.json. From then on you see it in /agent, in the web picker, in lampson run --agent tienda, in the API, in channels and in the SDK.
Where they live§
- Project:
<project>/.lampson/agents/<id>.agent.json. Commit it and your team has it. - Global:
~/lampson/agents/<id>.agent.json— in the Lampson folder, available in all your projects. Areviewerwith your rules, atranslator: you write them once. - If a project has an agent with the same
idas a global one (or a built-in one), the project's wins.
A broken file doesn't take down the others: it is ignored and the reason is shown.
The fields§
| field | default | |
|---|---|---|
id | lowercase letters, digits and - (max. 40) | required |
description | what it's for; shown in /agent, the API and to AIs that use it over MCP | "" |
base | "none": the prompt is just system. "lampson": prepends the coding agent's prompt (tools, project rules, AGENTS.md) | "none" |
system | the agent's prompt (required with base: "none"). The instructions of the plugins whose tools it has are added to it | |
tools | the tools it may use — see below | [] |
permission | ask, strict or yolo — see Permissions | the way in's |
steps | max steps per turn | Lampson's |
budget_tokens | max tokens per turn | Lampson's |
model | {"provider", "model"} so this agent uses its own model (a cheap one for customer service, a strong one for code) | the configured one |
buffer | the mailbox's quiet wait: {"quiet_s": 3, "max_s": 15} or false | the way in's |
Its own model is honored everywhere: the API, channels, the SDK and the terminal too — lampson --agent tienda starts with tienda's model, and /agent switches model along with the agent (/model still changes it for the session).
Tools and permissions§
tools is an exact list: the model sees nothing outside it.
"tools": [
"read",
"plugin_pedidos_*",
{"name": "read", "paths": [".lampson/tienda/*", "README.md"]},
{"name": "mcp_proveedor_ask", "approve": "auto"},
{"name": "bash", "approve": "ask"}
]
- By name: built-in tools (
read,write,edit,ls,find,grep,bash,fetch…), plugin tools (plugin_<plugin>_<tool>) and MCP tools (mcp_<server>_<tool>). A trailingmatches a prefix:plugin_pedidos_. paths— limited paths (optional). Only forread,write,edit,ls,findandgrep. With plain"read"the agent sees the whole project (as usual, ideal for code or personal use); withpaths, only those paths:"folder/"is the folder and everything inside it,"file.json"an exact file,""everything. Lampson checks the real path the tool would use, not the model's text:../, backslashes and absolute paths don't slip through.
An agent with limited paths cannot also have bash, process, delegate, lsp or computer_use, which would read any file another way: Lampson rejects the file and tells you why.
approve— per-tool permission (optional)."auto": that tool, and only that one, runs without asking for approval even if the agent isstrict(what is forbidden in every mode, likerm -rf /, stays forbidden)."ask": always asks for approval, even if the agent isyolo. So you don't have to give a whole agentyolojust so it can use one tool.
With nobody present (the API, a channel, lampson run), an agent that doesn't set permission runs in strict: whatever would ask for approval is denied, and the model sees it and explains it. Over the API, an agent in ask can wait for an approval: it shows up in the web UI's Approvals panel and, if you set up the public URL and the webhook, on your phone. → Scheduled tasks
A public-facing agent§
For a bot that talks to strangers, the safe choice is to give it just enough:
base: "none"and asystemthat says what it does and what it doesn't.- Only the tools it needs — better a plugin with one concrete action (
catalogo_buscar) thanread; and if it usesread, withpaths. permission: "strict".
A complete example, with a real conversation: Recipe: taking orders by chat.
Even if someone talks it into "reading the .env", the agent can't: Lampson rejects the call before running it. What Lampson guarantees and what it doesn't, with a real prompt injection example, is in Security; and a support agent with its own tools is in Recipe: a support agent.