# Lamps — give your AI agent tools with a ceiling it cannot raise

> A lamp is a portable unit of capability. Its manifest declares what the code may touch, the Synsema runtime enforces it and records every check. Install one with lamp add, expose it to any agent with lamp mcp.

Published 2026-09-02 · https://synsema.org/blog/lamps-capabilities-with-a-ceiling-for-ai-agents


When an agent gets a shell, its permission is a string match: *this command line looks safe*. Text
does not bound effects — the same binary reads and destroys, the credential travels with the call,
and every new command is a new negotiation. Lamps move the permission to where it belongs: the
effects.

## The contract

A lamp is a folder with a manifest and a program. The manifest states the **ceiling** — every
family of effect the code may ever touch, scoped by pattern:

```json
{
  "name": "git",
  "profile": "native",
  "caps": "stdout,env=LAMP_*,exec=git",
  "tools": [{ "name": "log", "description": "One-line decorated log.", "parameters": { "type": "object" } }]
}
```

Three parties, and none has to trust the others: the author declares, the operator grants (a project
ceiling and a session ceiling), the runtime enforces the intersection and keeps the record.
What runs is always `effective ⊆ declared ∩ manifest ∩ project ∩ session`; a lamp can narrow what
it was given and never widen it. `exec` with no named binary is refused at load, unconditionally.

## Four verbs

```sh
lamp add git                        # pull it (hashed file by file) and lint the promise
lamp inspect git                    # what it asks, what it promises — BREAKS ITS PROMISE if they differ
lamp git log '{"n": 5}'             # run it, under the ceiling, as a person
lamp enable git && lamp mcp         # the same tool for any MCP agent: Claude Code, Cursor, Lampson…
```

Every call runs in a child process of the same binary under that ceiling; a refusal comes back as
data and lands in `~/.lamps/audit/log.jsonl`. That is the system working — never retry with a
wider ceiling.

## Why it needs Synsema

The ceiling is not a policy file the tool is asked to respect. It is the `--cap-set` of the Synsema
interpreter running the lamp, so a `require` above it fails before any byte leaves. The official
lamps — `git`, `shell` with a human-written policy, `sql` read-only, `http` with an allowlist,
`npm-deps`, `skills` — are each a few dozen lines you can read before you install anything.

**Get one running:** [lamps.sh](https://lamps.sh) has the installer, the hub and the protocol paper.
Publishing your own is pushing a public repo with `lamp.json` and `lamp.syn`.

