Estender
Plugins
Um plugin é uma pasta que ensina uma nova ferramenta ao Lampson. Consultar seu banco de dados, chamar a API da sua empresa, fazer um deploy, publicar uma mensagem — qualquer coisa que um script consiga fazer, em qualquer linguagem. Os plugins vêm desligados por padrão: você liga cada um, e só então o agente pode usar as ferramentas dele.
Até o Lampson 0.2.6 os plugins se chamavam lâmpadas (lamps). Esse nome agora é do lamps.sh — veja Plugins e lâmpadas. As pastas antigas continuam funcionando: o que continua valendo.
Ligar um§
❯ /plugins on postgres
☼ postgres is on — 1 tool available: plugin_postgres_query
Na interface web, clique na pílula plugins no cabeçalho: uma lista de todos os plugins com um interruptor, suas ferramentas e um formulário para você mesmo testar cada uma. /plugins off <name> desliga. Sem interface (uma VPS por SSH, um script), na pasta do projeto: lampson plugin on postgres (plugin list mostra todos, plugin off desliga). O agente pode pedir que você ligue um plugin, mas nunca consegue fazer isso sozinho.
Anatomia§
~/lampson/plugins/postgres/ ← global: disponível em todos os projetos
plugin.json ← o manifesto
query.py ← o código, em qualquer linguagem
my-project/.lampson/plugins/… ← ou dentro de um projeto (versione, e sua equipe também terá)
plugin.json:
{
"name": "postgres",
"description": "read-only queries on the dev database",
"kind": "exec",
"command": "python query.py",
"timeout": 30,
"tools": [
{
"name": "query",
"description": "Run a SELECT and return the rows as JSON.",
"parameters": {"type": "object", "properties": {"sql": {"type": "string"}}, "required": ["sql"]},
"readonly": true
}
]
}
Como funciona uma chamada§
Toda vez que o agente usa uma ferramenta de plugin, o Lampson inicia um processo curto e passa a chamada em variáveis de ambiente:
| variável | conteúdo |
|---|---|
PLUGIN_TOOL | qual ferramenta foi chamada (query) |
PLUGIN_ARGS | os argumentos, em JSON ({"sql": "select …"}) |
PLUGIN_DIR | a pasta do plugin |
PLUGIN_WORKSPACE | a pasta do projeto |
O que o script imprimir em stdout é o resultado que o modelo vê. Uma saída com código diferente de zero ou um timeout vira um erro que o modelo pode ler.
# query.py
import os, json, psycopg
tool = os.environ["PLUGIN_TOOL"]
args = json.loads(os.environ.get("PLUGIN_ARGS", "{}"))
if tool == "query":
with psycopg.connect(os.environ["DEV_DATABASE_URL"]) as db:
rows = db.execute(args["sql"]).fetchall()
print(json.dumps(rows, default=str))
Dois tipos§
"kind": "exec"—commandroda como está, a partir da pasta do projeto. Qualquer linguagem. Uma palavra do comando que corresponde a um arquivo na pasta do plugin é resolvida automaticamente (python query.pyencontra oquery.pydo plugin). Sem sandbox: o script pode fazer tudo o que o seu usuário pode."kind": "syn"— um programa Synsema ("entry": "plugin.syn"). Ele roda sob um teto de capacidades tirado de"caps"no manifesto: o plugin pode fazer exatamente o que você aprovou ao ligá-lo, e código que pede mais falha. Exemplo:
"caps": "file.read=workspace/**,net"
O asterisco duplo é a pasta inteira e um só, o primeiro nível; um manifesto antigo com um só continua valendo pela pasta inteira.
Como um plugin exec não tem esse teto, ligar qualquer plugin é sempre uma decisão humana. Seu código, suas regras, seu risco.
Segredos e ajustes: config§
Um plugin declara os ajustes de que precisa, e o Lampson os passa a ele a partir de ~/lampson/.env:
"config": ["DEPLOY_TOKEN", "DEPLOY_URL"]
LAMPSON_DEPLOY_TOKEN do .env chega ao plugin como PLUGIN_DEPLOY_TOKEN — também a um plugin em Synsema com teto, que só vê PLUGIN_*. Assim os segredos não ficam no código nem no plugin.json.
Instruções: o plugin traz o seu processo§
Uma ferramenta sozinha não diz como usá-la. Um plugin pode trazer suas instruções, e o Lampson as soma ao prompt de cada agente que tenha alguma das suas ferramentas. Assim cada plugin é usado como o autor quis, sem repetir isso no prompt de cada agente.
Coloque-as num INSTRUCTIONS.md dentro da pasta do plugin (é lido sozinho), ou no manifesto:
"instructions": "INSTRUCTIONS.md"
"instructions": "Antes do deploy, rode os testes e confirme a branch com o usuário."
Servem para qualquer coisa que o modelo precise saber para usar bem essas ferramentas:
- Um processo de backend: «para cadastrar um cliente:
findpelo CNPJ primeiro; se não existir,createcom os dados da Receita; nunca dois cadastros com o mesmo CNPJ». - Apontar para outra coisa: «antes do
deploy, leia o skillreleasedo projeto», «para consultas de faturamento usemcp_erp_query, não este plugin». - Um prompt longo e preciso: o formato exato de um relatório, os passos de uma conciliação, o que fazer com cada código de erro da sua API.
- Uma conversa: como receber um pedido pelo chat — é o que faz o plugin
orders.
As instruções só chegam aos agentes que têm as ferramentas do plugin, e só com o plugin ligado. Um agente com "tools": ["read"] não as vê. São lidas no começo de cada sessão (até 12.000 caracteres).
Canais§
Um plugin com "channel" no seu plugin.json é um canal: conecta um agente a uma plataforma de mensagens (Telegram, Chatwoot, a que você escrever). O Lampson vem com telegram e chatwoot. → Canais
Permissões§
As ferramentas dos plugins seguem o modo de permissões: perguntam em ask, rodam em yolo, são negadas em strict. Ferramentas marcadas com "readonly": true também ficam disponíveis para os perfis de só leitura (plan, review, explore).
Deixe o agente escrever um§
"Crie para mim um plugin que liste os pull requests abertos com o gh." O agente cria a pasta e o manifesto dentro do seu projeto, valida (synsema check para um plugin Synsema) e avisa que está pronto — ligá-lo continua sendo decisão sua. No chat da web aparece uma linha ☼ plugin created e a pílula de plugins pisca.
Agendar um plugin§
Uma ferramenta de plugin pode ser o trabalho de uma tarefa agendada: "toda manhã, rode postgres.query com este SQL e me envie o resultado". Ligar o plugin é a autorização.
O exemplo§
~/lampson/plugins/example-hello/ vem junto com o Lampson — um plugin Synsema com uma ferramenta, greet. Copie a pasta, renomeie, e você tem um ponto de partida.
~/lampson/plugins/orders/ é um completo: sete ferramentas, dados no projeto, um teto de capacidades que só abre .lampson/orders/ e o seu INSTRUCTIONS.md. → Receita: receber pedidos pelo chat
Plugins e lâmpadas§
São duas coisas diferentes, de propósito:
- Um plugin é local, seu e do seu repositório: qualquer linguagem, sem distribuição, sem teto a menos que você o escreva em Synsema. Rápido de fazer; quem confia é você.
- Uma lâmpada (lamps.sh) é uma unidade portátil de capacidade: um manifesto que declara exatamente o que o código pode tocar, um runtime que faz cumprir e audita cada verificação, versionada por tag do git, baixada de um hub e usável por qualquer agente MCP — Claude Code, Cursor, Lampson…
Para usar lâmpadas no Lampson: instale o CLI, lamp add <ref>, habilite e adicione lamp mcp como servidor MCP. As ferramentas chegam com o teto escrito na descrição.
Antes se chamavam lâmpadas§
Se você usava lâmpadas no Lampson antes da 0.2.7, nada quebra hoje:
- As pastas
.lampson/lamps/<name>/continuam sendo descobertas (marcadas como pasta antiga na interface e em/plugins); se faltarplugin.json, olamp.jsoné lido. - O estado ligado/desligado em
.lampson/lamps.jsoné lido até existir.lampson/plugins.json. - Os scripts continuam recebendo
LAMP_TOOL,LAMP_ARGS,LAMP_DIReLAMP_WORKSPACEao lado dos nomes novos; um plugin Synsema pode manterrequire env("LAMP_*"). - Tarefas agendadas salvas com
"type": "lamp"continuam rodando;/lampsé um atalho para/plugins. - As pastas globais que você colocou em
~/lampson/lamps/são movidas para~/lampson/plugins/na primeira vez que o Lampson roda.
É uma ponte, não um segundo formato: renomeie a pasta para .lampson/plugins/, o manifesto para plugin.json e leia as variáveis PLUGIN_*.