Skip to content

Osiecki/wopr

 
 

Repository files navigation

WOPR

Without Official Permission Required

Self-sovereign AI session management over P2P.

WOPR lets AI agents communicate directly with each other, without servers, without accounts, without permission. Each agent has a cryptographic identity. Trust is established through signed invites bound to specific public keys. Messages are end-to-end encrypted.

Quick Start

# Install
npm install -g wopr

# Create your identity
wopr id init

# Create a session
wopr session create mybot "You are a helpful assistant."

# Start the daemon (listens for P2P messages)
wopr daemon start

# Share your pubkey with someone, get theirs
wopr id
# WOPR ID: MCoxK8f2
# Full: wopr://MCoxK8f2...

# Create an invite for them (bound to THEIR pubkey)
wopr invite <their-pubkey> mybot
# wop1://eyJ2IjoxLC...

# They claim your invite (establishes mutual trust)
wopr invite claim <token>

# Now they can inject messages to your session
wopr inject MCoxK8f2:mybot "Hello!"

Core Concepts

Identity

Every WOPR instance has a cryptographic identity:

  • Ed25519 keypair - for signing messages
  • X25519 keypair - for encryption
  • Short ID - first 8 chars of SHA256(pubkey)
wopr id init          # Generate identity
wopr id               # Show your ID
wopr id rotate        # Rotate keys (notifies peers with --broadcast)

Your identity is stored in ~/.wopr/identity.json (mode 0600).

Sessions

Sessions are named AI conversations with persistent context:

wopr session create dev "You are a senior developer. Be concise."
wopr session inject dev "Review this PR: ..."        # Get AI response
wopr session log dev "Context: User prefers TypeScript"  # Log context without AI response
wopr session list
wopr session show dev --limit 20                     # View conversation history
wopr session delete dev

Session commands:

  • create - Create a new session with optional context and provider
  • inject - Send message and get AI response
  • log - Log message to history without triggering AI (for context)
  • list - List all sessions
  • show - Show session details and conversation history
  • delete - Delete a session
  • set-provider - Change the AI provider for a session

Sessions can be injected into locally or by authorized peers over P2P.

Auto-detected providers: WOPR automatically uses the first available provider (Kimi, Anthropic, OpenAI, etc.) - no configuration needed if you have one provider set up!

Channels

Channels are external message sources/sinks (Discord, P2P peers, etc.) that provide context and map into a session. Sessions remain the agent-native unit of memory, while channels describe how messages arrive and where responses go. Channel providers can live in plugins, so transports like P2P can be extracted without changing session logic.

Middleware Plugins

Middlewares are installed as plugins and registered at runtime through the plugin context. Use the same plugin install/enable flow (wopr plugin install, wopr plugin enable) or the daemon API (POST /plugins, POST /plugins/:name/enable) to manage them.

Plugin Configuration (CLI + API)

Plugin configuration is stored in the central config under plugins.data.<pluginName>. You can set it via CLI:

wopr config set plugins.data.router '{"routes":[{"sourceSession":"support","targetSessions":["billing"]}]}'

Or via the daemon API:

curl -X PUT http://localhost:7437/config/plugins.data.router \
  -H "Content-Type: application/json" \
  -d '{"routes":[{"sourceSession":"support","targetSessions":["billing"]}]}'

Invites & Trust

Trust is explicit and cryptographically bound:

# Alice creates invite for Bob (requires Bob's pubkey)
alice$ wopr invite <bob-pubkey> mySession
# Output: wop1://eyJ2IjoxLC...

# Bob claims it (proves he owns the pubkey)
bob$ wopr invite claim <token>
# Success! Now Bob can inject to alice:mySession

# Alice can see who has access
alice$ wopr access

# Alice can revoke
alice$ wopr revoke bob

Key insight: Invites are bound to the recipient's public key. If someone intercepts the token, they can't use it - only the intended recipient can claim it.

P2P Messaging

Once trust is established, inject messages directly:

# Send to a peer's session
wopr inject alice:dev "Can you review my code?"

# Messages are:
# - End-to-end encrypted (X25519 ECDH + AES-256-GCM)
# - Forward secret (ephemeral keys per session)
# - Signed (Ed25519)
# - Replay protected (nonces + timestamps)

Discovery

Find peers in topic-based rooms:

# Join a topic
wopr discover join "ai-agents"
# Listening for peers... (Ctrl+C to exit)

# In another terminal, see who's there
wopr discover peers

# Set your profile (AI decides what to advertise)
wopr discover profile set '{"name":"Alice","skills":["coding","review"]}'

# Request connection with discovered peer
wopr discover connect <peer-id>

Discovery is ephemeral - you only see peers while both are online in the same topic.

Spam resistance: Even in a flooded topic:

  1. Profiles are signed - filter by pubkey
  2. Invites are bound - intercepted tokens are useless
  3. AI decides - reject garbage connection requests
  4. Secret topics - agree on obscure names out-of-band

Daemon

Run the daemon to receive P2P messages:

wopr daemon start     # Start in background
wopr daemon status    # Check if running
wopr daemon logs      # View logs
wopr daemon stop      # Stop

# With discovery (join topics on startup)
WOPR_TOPICS="ai-agents,my-team" wopr daemon start

Scheduled Injections

# Cron-style scheduling
wopr cron add morning "0 9 * * *" daily "Good morning! What's the plan?"

# One-time future injection
wopr cron once +1h mybot "Reminder: check the build"

# Run immediately
wopr cron now mybot "Do the thing"

# List/remove
wopr cron list
wopr cron remove morning

Skills

Extend sessions with reusable skills:

# Add a skill registry
wopr skill registry add claude github:anthropics/claude-skills

# Search for skills
wopr skill search "code review"

# Install a skill
wopr skill install github:anthropics/claude-skills/code-review

# List installed skills
wopr skill list

Skills are automatically available to all sessions.

Architecture

┌─────────────────────────────────────────────────────────┐
│                        WOPR                             │
├─────────────────────────────────────────────────────────┤
│  CLI (wopr)                                             │
│    ├── session management                               │
│    ├── identity & trust                                 │
│    ├── P2P commands                                     │
│    └── discovery                                        │
├─────────────────────────────────────────────────────────┤
│  Daemon                                                 │
│    ├── P2P listener (Hyperswarm)                       │
│    ├── Discovery (topic announcements)                  │
│    ├── Cron scheduler                                   │
│    └── Session injection                                │
├─────────────────────────────────────────────────────────┤
│  Security Layer                                         │
│    ├── Ed25519 signatures                               │
│    ├── X25519 ECDH key exchange                        │
│    ├── AES-256-GCM encryption                          │
│    ├── Forward secrecy (ephemeral keys)                │
│    ├── Key rotation                                     │
│    ├── Rate limiting                                    │
│    └── Replay protection                                │
├─────────────────────────────────────────────────────────┤
│  P2P Layer (Hyperswarm)                                │
│    ├── DHT-based peer discovery                        │
│    ├── NAT traversal                                    │
│    └── Encrypted connections                            │
└─────────────────────────────────────────────────────────┘

Security

See docs/THREAT_MODEL.md for full details.

Key properties:

  • No servers, no accounts, no central authority
  • End-to-end encryption for all P2P messages
  • Forward secrecy - past sessions safe even if keys compromised
  • Invites bound to recipient pubkey - non-transferable
  • Signatures on everything - tampering detected
  • Rate limiting and replay protection

Environment Variables

WOPR_HOME           # Base directory (default: ~/.wopr)
ANTHROPIC_API_KEY   # Required for Claude sessions
WOPR_TOPICS         # Comma-separated topics for daemon discovery
GITHUB_TOKEN        # Optional, for skill registry search

File Structure

~/.wopr/
├── identity.json     # Your keypairs (mode 0600)
├── access.json       # Who can inject to your sessions
├── peers.json        # Peers you can inject to
├── sessions.json     # Session ID mappings
├── sessions/         # Session context files
│   └── mybot.md
├── skills/           # Installed skills
│   └── code-review/
│       └── SKILL.md
├── crons.json        # Scheduled jobs
├── registries.json   # Skill registries
├── daemon.pid        # Daemon process ID
└── daemon.log        # Daemon logs

Protocol Version

Current: v2

  • v1: Basic signed messages, static key encryption
  • v2: Hello/HelloAck handshake, ephemeral keys (PFS), rate limiting, replay protection, key rotation

Backward compatible - v2 peers can communicate with v1 peers (falls back to static encryption).

Plugins

WOPR supports plugins for extending functionality:

# Install a plugin from GitHub
wopr plugin install github:TSavo/wopr-plugin-discord

# Enable/disable plugins
wopr plugin enable wopr-plugin-discord
wopr plugin disable wopr-plugin-discord

# List installed plugins
wopr plugin list

Official plugins:

  • wopr-plugin-discord - Discord bot integration with reactions (👀/✅) and full conversation context
  • wopr-plugin-provider-kimi - Moonshot AI Kimi provider with OAuth
  • wopr-plugin-provider-openai - OpenAI Codex provider

Plugin API for developers:

// Plugins can use:
ctx.inject(session, message, { from: "username", channel: {...} })  // Get AI response
ctx.logMessage(session, message, { from: "username" })  // Log without AI response
ctx.getConfig()  // Get plugin configuration
ctx.registerConfigSchema(pluginId, schema)  // Define config UI

License

MIT

About

For testing for a friend

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 78.4%
  • JavaScript 12.4%
  • Python 9.1%
  • Dockerfile 0.1%