Back to garden
Seedling··2 min read

On Building your own Lobster Trap

K
Kevin De Asis
ai
Share

Still thinking through this one... The ideas here might look different tomorrow.

Building an agent inside a container

Let's build an isolated container that sandboxes an AI assistant inside it.

We will have our agent run inside Linux containers. They can only see files we explicitly mount. If the AI tries something unexpected, it's trapped in a sandbox.

The Core Idea

Messaging Channel  -->  SQLite Database  -->  Polling Loop  -->  Container (Claude)  -->  Response

Our Lobster Trap will be Node.js process that:

  1. Connects to Gmail
  2. Stores incoming messages in a SQLite database
  3. Polls for new messages every 2 seconds
  4. When it sees a trigger word (default: @LobsterCage), it spawns a container
  5. The container runs Claude Agent SDK, processes the message, and returns a response
  6. Lobster Trap sends the response back through the messaging channel

Key Concepts

Groups

A "group" is any chat where LobsterCage is active. Each group gets:

  • Its own folder on disk (groups/{name}/)
  • Its own CLAUDE.md memory file (the AI reads this for context)
  • Its own container sandbox (completely isolated from other groups)
  • Its own Claude session (conversation history doesn't leak between groups)

The Main Group

One special group is the "main" group -- your private self-chat. This is the admin channel. From here you can:

  • Register new groups
  • Manage scheduled tasks across all groups
  • See the full project structure

Non-main groups are treated as untrusted. They can only see their own files and manage their own tasks.

Channels

A "channel" is a messaging platform connector. Let's start with supporting Gmail

Containers

Every time the AI needs to respond, it runs inside a Linux container:

  • Filesystem isolation: the AI can only see folders you mount
  • Process isolation: it can't affect your host machine
  • Non-root execution: runs as an unprivileged user
  • Ephemeral: the container is destroyed after use

How Everything Connects

Here's a simplified view of the data flow:

 ┌──────────────────────────────────────────────────────────────────┐
 │   Gmail                                                          │
 └──────────────────────┬───────────────────────────────────────────┘
                        │ Messages arrive
                        ▼
 ┌──────────────────────────────────────────────────────────────────┐
 │                    HOST PROCESS (src/)                             │
 │                                                                   │
 │  1. Channel stores message in SQLite                             │
 │  2. Message loop polls every 2 seconds                           │
 │  3. Checks for @LobsterCage trigger                                     │
 │  4. Formats messages as XML                                      │
 │  5. Spawns container via GroupQueue                               │
 │                                                                   │
 │  Also running:                                                    │
 │  - Task scheduler (every 60s)                                    │
 │  - IPC watcher (every 1s)                                        │
 │  - Credential proxy (port 3001)                                  │
 └──────────────────────┬───────────────────────────────────────────┘
                        │ Container spawned with mounts
                        ▼
 ┌──────────────────────────────────────────────────────────────────┐
 │                 CONTAINER (Isolated Linux VM)                      │
 │                                                                   │
 │  - Receives prompt via stdin JSON                                │
 │  - Runs Claude Agent SDK (Claude Code)                           │
 │  - Has bash, web search, file access (within mounts)             │
 │  - Outputs results via stdout markers                            │
 │  - Communicates with host via IPC files                          │
 └──────────────────────┬───────────────────────────────────────────┘
                        │ Response sent back
                        ▼
 ┌──────────────────────────────────────────────────────────────────┐
 │                     MESSAGING CHANNELS                            │
 │  Response delivered to the user                                  │
 └──────────────────────────────────────────────────────────────────┘

You might also like