Lampson

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ávelconteúdo
PLUGIN_TOOLqual ferramenta foi chamada (query)
PLUGIN_ARGSos argumentos, em JSON ({"sql": "select …"})
PLUGIN_DIRa pasta do plugin
PLUGIN_WORKSPACEa 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" — command roda 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.py encontra o query.py do 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: find pelo CNPJ primeiro; se não existir, create com os dados da Receita; nunca dois cadastros com o mesmo CNPJ».
  • Apontar para outra coisa: «antes do deploy, leia o skill release do projeto», «para consultas de faturamento use mcp_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 faltar plugin.json, o lamp.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_DIR e LAMP_WORKSPACE ao lado dos nomes novos; um plugin Synsema pode manter require 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_*.

Ver como Markdown