Skip to content

About

A self-hosted personal agent engine. Discord conversations, persistent coding sessions and private Markdown memory.

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Latest commit

 

History

49 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

plompy-engine: Codex, Claude Code and OpenCode in persistent private threads

plompy-engine

Run coding agents from private Discord threads.

One CLI session per thread. A durable queue for accepted work. Private Markdown context that survives the conversation.

Offline checks Release Node.js 26 MIT license

Quick start · Supervised goals · See it work · Runners · Documentation

plompy-engine connects a private Discord forum to coding agents on your own Linux machine. Send a task, follow up in the same thread, and return to a saved result. The engine keeps the runner session, accepted work and recovery state together, so a disconnected client does not mean starting the conversation again.

Your phone can go back in your pocket.

Local tools for your own agent

The new Plompy Local mode gives an independently running Codex CLI, Claude Code, OpenCode or compatible MCP client selected research tools through an authenticated Streamable HTTP endpoint. Start it in Docker, connect your client, and keep the conversation and model choice in that client. No Discord bot or second model account is required inside the container. The existing Discord mode remains available.

  • Read public sources with bounded HTTP fetching or optional sandboxed Chromium.
  • Select supported search/documentation integrations using your own credentials.
  • Save sourced research, email drafts, CSV, JSON and Markdown in a persistent volume.
  • Use a compatible local model through Ollama in your agent, or choose its supported hosted provider. Ollama is the model provider, not the MCP client. Local-model quality and tool calling depend on the chosen model; hosted integrations still receive their requests.

Plompy Local 0.13.0 includes ready-made Linux amd64 and arm64 images: ghcr.io/dalkedev/plompy-engine:0.13.0-local and the optional ghcr.io/dalkedev/plompy-engine:0.13.0-local-browser. Download the small starter kit; no source checkout or host Node installation is needed. It does not expose email sending or general shell execution tools. Paid provider calls and actual Ollama inference have not been tested.

Docker quickstart · Codex CLI · Claude Code · OpenCode · Ollama · Integration matrix · Verification and limits · Release history

mkdir -m 700 plompy-local
cd plompy-local
curl -fL https://github.com/dalkedev/plompy-engine/releases/download/v0.13.0/plompy-local-0.13.0.tar.gz \
  -o plompy-local-0.13.0.tar.gz
tar -xzf plompy-local-0.13.0.tar.gz
docker compose pull local
docker compose run --rm -T local node scripts/integrations.mjs init --mode local
docker compose up -d local
docker compose exec -T local node scripts/integrations.mjs test --mode local

Use the quickstart to export the access token into your client's environment, select integrations, and print the appropriate client configuration without embedding secrets.

Upgrading an existing installation? Read the 0.12 migration guide before changing service paths or Docker volumes.

What the engine handles

  • Continuity: one provider-bound CLI session per Discord thread; private Markdown instructions and notes.
  • Durable intake: SQLite WAL, deduplicated message IDs, bounded queues and atomic claims.
  • Bounded work: active execution budgets, typed checkpoints and fair turns between threads.
  • Supervised goals: a fresh Codex reviewer checks each candidate; an explicit repository binding adds saved code and test diffs.
  • Honest recovery: interrupted work remains visible; uncertain actions are never replayed automatically.
  • Delivery and maintenance: result receipts, transcript exports and scoped local Git commits have separate durable state.
  • Deployment checks: owner/forum authorization, local diagnostics, versioned migrations and verified state snapshots.

The public edition has one global worker. Work sessions yield between verified steps; they do not interrupt a running step. Still-image input and supervised goals use Codex. There is no built-in scheduler, publication broker or message-history catch-up after an outage.

Quick start

You need Linux, Node.js 26.13.0+ (26.x LTS), Git, flock, your own Discord bot and an authenticated runner. The default path below uses Codex CLI 0.166.0. For containers, start with the Docker guide.

1. Install and try the offline demo

git clone --branch v0.13.0 --depth 1 https://github.com/dalkedev/plompy-engine.git
cd plompy-engine
npm --prefix apps/discord-agent ci --ignore-scripts
npm run build
npm run demo -- session

The demo uses synthetic data and needs no Discord token or model account. Run npm test for the offline regression suite.

2. Prepare your private installation

Create your Discord bot, enable Message Content Intent, and choose a private forum in a server you own. Keep the bot token private. The configuration guide explains the four Discord IDs and permission requirements.

npm run setup

The guided setup asks for the runner, paths and Discord identities. Token input is hidden. It creates a separate private Git workspace, state/artifact/browser and runner directories, and a mode-0600 environment file outside this checkout. Existing installations are preserved. It installs no runner or service and does not authenticate accounts or contact Discord. Setup options and automation.

The default root is $HOME/.local/share/plompy. Edit its workspace/agent/USER.md and workspace/agent/POLICY.md before asking the agent to act. For containers, continue with the Docker volume workflow instead.

3. Sign in, inspect and start

After installing the supported Codex CLI, load only the trusted environment file you just created. If you chose custom paths or another runner, use the setup's printed commands and runner guide.

set -a
. "$HOME/.local/share/plompy/agent.env"
set +a
codex login
npm run doctor -- --check-login --check-discord
flock -n -E 75 "$PLOMPY_STATE_DIR/engine.lock" npm --prefix apps/discord-agent start

doctor is local by default. --check-discord explicitly performs bounded read-only REST checks of bot identity, owner, forum privacy and reply permissions; it sends no message and calls no model. Message Content Intent, Gateway delivery and actual model access still need a harmless live task. Hold the instance lock before startup recovery. See deployment for service operation and the supplied first code goal for an independently checked task.

4. Choose integrations

With the engine stopped and the same private configuration loaded:

npm run integrations
# Or configure explicitly:
npm run integrations -- add github --yes
npm run integrations -- login github
npm run integrations -- add openai-docs --yes
npm run integrations -- status

Choose GitHub, Playwright, Camoufox, Perplexity, Firecrawl, TinyFish, PostHog, OpenAI Docs, Context7 or a custom MCP server. Each entry belongs to the selected runner: Codex, Claude Code or OpenCode. The tools are not tied to a Codex-only browser session.

Playwright uses pinned optional dependencies and a fresh headless browser context; Camoufox keeps a separately provisioned Linux browser and private display. Remote services use your own OAuth account or a private API-key file. PostHog starts in read-only mode; adding it does not add analytics tracking to the engine.

Setup also writes maintained tool-use playbooks to private agent/INTEGRATIONS.md. It does not import personal credentials, purchase API access or call the services to test configuration. See integration setup for prerequisites, authentication, Docker support and a real browser acceptance test. Your agent can click buttons. It still needs a reason to click that button.

Working in a thread

Task Example message
Investigate a failure Reproduce the failing parser test, explain the cause, and prepare a focused fix.
Build in bounded steps !work 30m Add quantity limits to the fixture app. Include tests and document the rules.
Research before implementing Compare these two API designs. Save the trade-offs before changing code.

Choose repository, browser and documentation tools with npm run integrations. Choose Codex, Claude Code, or OpenCode first, then the integration. Use --runner claude or --runner opencode to target a runner directly. OpenCode can use Go, Zen or another configured model provider. The menu prepares your own CLI and explicit MCP configuration; the engine does not provide model access or accounts. See integration setup.

From a task to a reviewed change

A normal message runs one task in the thread's saved session. Use !work for a larger task with checkpoints, or !goal for steps checked by a separate supervisor. !loop is an alias for !goal; both currently require a Codex thread.

For a code change, bind the repository when you start. For example, in a private thread:

!goal 30m --repo "/srv/plompy/artifacts/quantity-parser" Reject negative quantities, preserve zero as valid, and add regression tests. Run the parser tests and report the result.

This is an illustrative request for an existing project. Replace the path with the exact Git repository root inside your configured workspace or artifacts directory. The binding selects evidence to capture; it does not grant additional filesystem access.

  1. The worker advances the fixed goal and returns a candidate with a checkpoint.
  2. The engine saves the observed before/after changes in the bound repository.
  3. A fresh supervisor receives the candidate, code and test diff, and two recent review receipts.
  4. Its review determines whether to continue, mark the goal complete, or block for owner input or reconciliation.

The capture compares file contents across the worker step, so staging or committing the change does not erase the review evidence. SQLite retains the sealed evidence for review retries. A reviewer can inspect whether the parser changed or an assertion merely became easier to satisfy. A green test is useful; moving the goalposts is less useful.

Worker and supervisor share the execution budget. Use these commands in the same thread to inspect or control the goal:

!goal status
!goal pause
!goal resume
!goal stop

Code evidence is bounded and reports omissions. It records observed changes, not authorship; use separate working copies for independent goals. Without --repo, new and migrated goals have no automatic code diff, and the supervisor is explicitly told that it is unavailable. Existing bindings are retained during recovery unless explicitly changed.

Start with your first supervised goal, then read the goal lifecycle and code evidence contract.

See it work

These captures show the real Engine and Store running locally with synthetic messages, transport and runner responses. They are documentation views of actual offline output, not screenshots of a connected Discord account or live model results. Text transcripts and reproduction instructions are included.

Follow up without starting over

A second message resumes the saved session. A separate thread gets a separate session.

Offline demonstration of a follow-up preserving its session and another thread receiving a separate session

Inspect an interruption before continuing

A failed turn remains visible. Queued follow-ups wait; the owner chooses recovery explicitly. A delivery retry does not rerun the model.

Offline demonstration of saved failure state, a blocked follow-up and explicit recovery

“Queued” is a state, not an optimistic progress report.

Use !queue to see which tasks are waiting and why: an earlier task in this thread, unverified runner readiness, a blocked conversation, or the shared worker. The view contains task IDs and states from this thread; it does not call a model or expose messages from other conversations. No invented countdown. Computers have enough timers.

Keep the runner attached to the conversation

Choose a default for new threads. Existing conversations keep their provider and session, while unavailable providers do not block eligible work for others.

Offline demonstration of provider-bound conversations and independent readiness

Choose a runner

Runner CLI requirement Where it runs
Codex (default) 0.166.0 Linux host or the published Docker image
Claude Code (experimental) >=2.1.285, <3 Linux host with restricted mode and mandatory native Bash sandboxing
OpenCode (experimental) 1.19.5 Operator-isolated Linux host; explicit host execution opt-in
PLOMPY_RUNNER=codex     # or claude / opencode

This selects the default for new conversations. Existing threads and recovered jobs retain their original runner. The engine never switches tools after an authentication or model failure. Upstream CLI model aliases and provider fallback policies can still apply.

The Docker image packages Codex only. Claude Code and OpenCode have different execution boundaries and private login paths; see runner setup. Their protocol tests are offline; live account and host-boundary acceptance remain deployment checks.

How it fits together

flowchart LR
    Discord["Private Discord thread"] --> Guard["Owner + forum checks"]
    Guard --> Queue[(SQLite queue)]
    Queue --> Worker["One worker"]
    Worker --> Runner["Provider adapter"]
    Runner --> Codex["Codex"]
    Runner --> Claude["Claude Code"]
    Runner --> OpenCode["OpenCode"]
    Runner <--> Memory["Private Markdown + Git"]
    Runner -. "optional MCP" .-> Browser["Camoufox"]
    Worker --> Result["Saved result + delivery state"]
    Result --> Discord
Loading

Execution, notification delivery and external effects are separate facts. A successful local turn does not prove a deployment, post or website action succeeded. Architecture covers the state transitions and recovery contract.

Discord commands

Input Effect
A normal message Queue a task in this thread's saved session
!goal 30m <goal> Advance a fixed goal under a separate supervisor; !loop is an alias
!goal 30m --repo "/absolute/path" <goal> Capture code changes in an explicit repository inside workspace/artifacts
!goal status / pause / resume / stop [MESSAGE_ID] Inspect or control this thread's supervised goal
!work 30m <goal> Continue a fixed goal with checkpoints; 1–120 active minutes, at most 32 completed steps
!status Inspect this thread's queue, readiness, work session and delivery state
!queue Show accepted task IDs and explain why each waiting task is blocked
!cancel MESSAGE_ID Cancel queued work or stop this thread's active process
!recover [MESSAGE_ID] [instruction] Reconcile the blocking or selected task, then continue its saved session
!new-session Cancel queued work and clear the session; retain the provider binding and history
!result [MESSAGE_ID] Read a saved response without rerunning work; latest task by default
!help Show commands without starting a model

Messages received during a full outage may never have entered the queue. Use !status to check what was accepted. Invalid commands show usage rather than becoming model tasks.

A verified work-session pause retains its session and checkpoint. A fresh explicit !work budget can continue it. Crashes, timeouts and malformed outcomes require inspection and manual recovery. In a blocked thread, a fresh explicit !work budget reconciles prior actions and continues the saved session. See work sessions.

Codex threads also accept up to four still PNG, JPEG or WebP attachments, with a caption, without text, or alongside an explicit !work goal. Images are passed as native inputs on initial and resumed turns and retained privately with the durable job. Claude Code and OpenCode image requests are explicitly rejected by these adapters. See image input, limits and privacy.

Public code. Private memory.

plompy-engine/                 # Public source and synthetic templates
~/.config/plompy/agent.env     # Private credentials and deployment IDs
~/.local/share/plompy/
  workspace/                  # Instructions, notes, transcripts and Git history
  state/                      # SQLite queue, private images and provider/session mappings
  codex/                      # Private Codex login and configuration
  browser/                    # Optional browser profile
  artifacts/                  # Task output

The engine commits selected Markdown locally; it does not push memory. Keep the workspace remote separate from this public repository. Treat transcripts, credentials, browser profiles and artifacts as private data. Alternative runners have their own private directories.

Version 0.13.0 uses SQLite schema 6, retaining owner-bound repositories and durable code-diff evidence. Take a verified pre-upgrade snapshot; rollback requires compatible state and reconciliation of later actions. Do not point older code at a migrated database.

Development

npm test
# Optional browser package, with Python 3.12 and the locked dependencies:
(cd packages/browser && uv run --locked --offline pytest -q)

The tests use synthetic data and fake CLIs. They exercise queueing, migrations, exact session resume, recovery, provider readiness, process limits and checkpoint validation without calling a model or posting messages. Container checks additionally exercise the actual Codex filesystem sandbox. See demo and capture tooling to reproduce the gallery.

Explore the code

Source map
Path Responsibility
config.ts Configuration, authorization and child environments
engine.ts Execution, maintenance and notification lifecycle
store.ts Queue, provider bindings, checkpoints and recovery
runner.ts Explicit dispatch to the recorded provider
codex.ts, claude.ts, opencode.ts CLI protocols, process bounds and cancellation
workspace.ts Prompt context, transcript export and scoped Git commits
scripts/integrations.mjs Local integration setup, managed configuration and playbooks
packages/browser/ Optional Camoufox MCP tools and offline checks
examples/workspace/ Synthetic workspace templates

Trust and limits

There is no exactly-once guarantee for external services. Inspect the actual destination before recovering an uncertain action. Environment filtering does not isolate processes sharing a Unix user; browser URL guards do not replace network isolation. Explicit MCP servers remain trusted processes. Read security before granting real account access.

The project is MIT-licensed; model access and third-party services are separate. The road to 1.0 records the remaining stability gates.

Support the project

If Plompy is useful to you, you can buy me a coffee to support its development.

Documentation · Contributing · Releases · Brand assets · MIT license

About

A self-hosted personal agent engine. Discord conversations, persistent coding sessions and private Markdown memory.

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages