A lean, secure personal AI agent powered by Player2, controlled entirely via Telegram. No web server, no exposed ports, no untrusted code.
Inspired by the OpenClaw project β rebuilt from scratch so every line is understood.
- Player2 App β Download from player2.game and keep it running. It must be available at
http://127.0.0.1:4315. - Node.js β v18 or later.
# 1. Download or clone P2 Claw
git clone <repo-url>
cd P2Claw
# 2. Create your config file
cp .env.example .env
# 3. Edit .env with your Telegram details (see table below)
# 4. Install dependencies
npm install
# 5. Start the bot
npm run devBy default, P2 Claw runs the Telegram frontend. You can run CLI-only by setting:
UI_MODE=cliThen start as usual (interactive REPL).
If you use npm run dev, it runs a watcher; that's great for development, but it may restart the process when files change. For CLI mode, npm run start is usually smoother:
npm run devOr:
npm run startIn CLI mode, type /help for commands. Audio features (STT/TTS) remain Telegram-only for now.
You can also launch CLI directly on Windows:
cli.batOr one-shot (non-interactive) with a message:
cli.bat "hello"Edit your .env file:
| Variable | Where to get it |
|---|---|
TELEGRAM_BOT_TOKEN |
Telegram β @BotFather β /newbot β copy the token |
TELEGRAM_ALLOWED_USER_IDS |
Telegram β @userinfobot β it replies with your numeric ID |
DEFAULT_VOICE_MODE |
Optional. off (default), tg (voice note after replies), or pc (speak via Player2 on this PC). Per-chat override: /voice |
UI_MODE |
Optional. telegram (default) or cli. Controls which frontend starts. |
TOTP_SECRET_BASE32 |
Optional until you use high-risk tools. RFC 6238 secret (Base32) shared with Google Authenticator / Aegis β same value as in the app. |
Important: Never commit your .env. It contains secrets (Telegram bot token, allowed user IDs). This repo ignores .env by default via .gitignore.
That's it. The Player2 API connection is built in β just make sure the Player2 App is running.
- User whitelist β Only responds to Telegram user IDs listed in your
.env. Everyone else is silently ignored. - No web server β Uses Telegram's long-polling. Zero open ports. Nothing to scan or attack.
- Secrets in .env only β Your Telegram token never appears in code or logs.
- Local-first β Everything runs on your machine. Messages are processed locally via Player2.
- Level 4 Phase 1 β TOTP approvals β High-risk tools (demo:
high_risk_demo) ask for your authenticator code. While a challenge is open, send only the 6-digit code in Telegram (orAPPROVE <8-char-id> <code>). Those messages are handled before the AI sees them, so they are not added to model context or chat history. SetTOTP_SECRET_BASE32in.env(see.env.example). See.agent/workflows/security-considerations.mdfor why permission boundaries stay in the bot, not the LLM. - Never paste your Base32 secret into Telegram β only the six-digit rotating code when the bot is waiting for approval.
- No raw model output logging by default β set
P2CLAW_LOG_RAW_MODEL=truein.envto print a short raw response preview for debugging.
| Command | Description |
|---|---|
/start |
Welcome message and bot info |
/status |
Check Player2 health, joule balance, active profile |
/profile |
List AI profiles or switch (/profile <name>) |
/setup |
Guided setup that stores a few βcoreβ memories (your name, purpose, tone). Use /cancel to abort. |
/memories |
List stored memories (and how to forget one) |
/compact |
Summarize older conversation history to free context space |
/voice |
Configure voice output: /voice off | tg | pc (saved per chat; survives restarts) |
/clear |
Reset conversation history |
/cancel |
Cancel an in-progress /setup session |
/totp_status |
Whether TOTP_SECRET_BASE32 is set (boolean only; never prints the secret) |
/totp_enroll_help |
How to enroll an authenticator app and use APPROVE messages |
/shutdown |
Gracefully stop the bot (saves DB, releases bot lock) |
When UI_MODE=cli, you can use:
| Command | Description |
|---|---|
/help |
Show CLI help |
/memories |
List recent memories |
/compact |
Summarize older conversation history |
/clear |
Clear conversation history (memories unaffected) |
/totp_status |
Whether TOTP_SECRET_BASE32 is set |
/shutdown |
Graceful shutdown |
/exit |
Quit CLI |
If your terminal does not support interactive prompts (some IDE/Git Bash setups), you can run a single message and exit:
cli.bat "what is my current status?"Or pipe stdin:
echo "summarize our last chat" | cli.batIf you're a Player2 Patron, you can create AI profiles in the Player2 App that bundle together:
- 1 LLM (chat model)
- 1 TTS (text-to-speech voice)
- 1 Text-to-image model
- 1 Image-to-image model
- 1 3D model generator
- 1 Music model
- 1 Video model
Enable profile switching by setting USE_PROFILES=true in your .env.
Switch at runtime via /profile <name> in Telegram.
This section is for developers building or modifying P2 Claw.
User (Telegram) ββ grammY (long-polling) ββ Agent Loop ββ Player2 App (local)
β
Tool Registry
- No HTTP server β grammY polls Telegram's API directly
- Agentic loop β LLM can call tools, inspect results, and iterate (capped at configurable max)
- Player2 as gateway β All AI models accessed through the local Player2 App at
127.0.0.1:4315 - 60s health ping β Periodically pings Player2
/v1/healthfor time-spent tracking
src/
βββ index.ts # Boot sequence
βββ config.ts # Environment loading & validation
βββ security.ts # API credential resolution & protection
βββ player2.ts # Player2/OpenAI SDK client + health ping
βββ bot.ts # Telegram bot setup & message routing
βββ agent.ts # Agentic tool loop
βββ ui/ # Frontends (Telegram, CLI; future local HTML GUI)
β βββ core.ts # Shared agent core wrapper for frontends
β βββ frontend.ts # Frontend interface + hooks types
β βββ telegram.ts # Telegram frontend wrapper
β βββ cli.ts # CLI REPL frontend
βββ security/
β βββ totp.ts # RFC 6238 verification (Node crypto)
β βββ approval.ts # Pending challenges + TOTP gate
βββ tools/
βββ registry.ts # Tool registration, dispatch, high-risk TOTP gate
βββ tool-types.ts # Shared ToolDefinition (avoids import cycles)
βββ get-current-time.ts
βββ remember.ts
βββ recall.ts
βββ forget.ts
βββ high-risk-demo.ts # Stub high-risk tool (Level 4 Phase 1)
scripts/
βββ encode-key.ts # Utility to encode your game key for embedding
End users should never need to deal with the game key. Before distributing, you must embed your real key:
-
Get your Game Client ID from the Player2 Developer Dashboard
-
Encode it:
npx tsx scripts/encode-key.ts YOUR_REAL_GAME_CLIENT_ID
-
Copy the output array and paste it into
src/security.ts, replacing the_encarray. -
Test the build:
# Remove PLAYER2_GAME_KEY from your .env (or comment it out) npm run dev # Should boot normally using the embedded key
The .env value PLAYER2_GAME_KEY always overrides the embedded key β useful for testing with a different key during development.
If you're actively developing and want to use a key different from the embedded one, uncomment the last line in .env:
PLAYER2_GAME_KEY=your_dev_key_hereThis is not needed for end users.
Source-available β see LICENSE.