pyclaudir
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 9 GitHub stars
Code Gecti
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
This tool is a self-evolving AI assistant that runs directly within Telegram. It acts as a personal or team agent capable of managing tasks, retaining conversation memory, sending alerts, and autonomously executing background research while integrating with external platforms like Jira or GitHub.
Security Assessment
Overall risk: Medium. The tool requires network access to communicate with the Telegram API and Claude AI services. It does not explicitly request dangerous permissions, but the README highlights its ability to execute shell commands, edit code, and connect to external MCP servers. This creates a significant attack surface: if the Telegram bot is compromised, an attacker could potentially trigger arbitrary code execution or shell access on the host machine. A light code scan of 12 files found no hardcoded secrets or dangerous patterns, but administrators must be extremely careful to protect their Telegram Bot Token and Owner ID in the `.env` file.
Quality Assessment
The project is under active development, with its most recent push occurring today. It uses the standard, permissive MIT license and the repository includes a thorough description and setup instructions. However, it has very low community visibility with only 9 GitHub stars. Because of this limited public traction, the codebase has not been broadly reviewed or battle-tested by the open-source community.
Verdict
Use with caution — while the baseline code appears safe and is actively maintained, the integration of autonomous AI with shell access via a messaging app introduces significant inherent risks that require strong environment isolation and strict secret management.
Your personal self-evolving AI agent. In telegram. With your rules.
Run personal self-evolving AI assistant in Telegram. With your rules. Lightweight.
Most AI tools wait. Pyclaudir doesn't. It lives in your Telegram, remembers every conversation, and pings you the moment something matters — a trend turning, a Jira ticket due, a build that broke at 3am.
Brief it before bed: "research global tech trends, find problems worth solving in Uzbekistan, write the analysis and ship a prototype." Wake up to a report, a pitch, and a working demo. That's the difference between a chatbot and an assistant.
It learns you. Every day it reflects on what worked and writes new rules into its own playbook — with your approval. Drop it in a group chat and it tracks who's blocked, what shipped, what slipped. DM it and it's your personal chief of staff. Plain markdown files you actually own. Your rules. One process you control end to end.
Out of the box: messaging, memory, reminders, web, vision. Want shell access? Code editing? Plug in any other MCP server — GitHub, Jira, Notion, Slack, your own — same one-entry pattern, stdio or remote HTTP/SSE with auth headers. Runs on your laptop or any small VPS. Works with your existing Claude Code subscription.
Quickstart (3 minutes)
git clone https://github.com/Rustam-Z/pyclaudir && cd pyclaudir
cp .env.example .env && nano .env
# set TELEGRAM_BOT_TOKEN (from @BotFather)
# set PYCLAUDIR_OWNER_ID (your numeric Telegram user id, from @userinfobot)
# update if necessary: PYCLAUDIR_MODEL and PYCLAUDIR_EFFORT
cp prompts/project.md.example prompts/project.md && nano prompts/project.md
# set bot name, language, personality
cp plugins.json.example plugins.json && nano plugins.json
# single source of truth for the bot's capability surface — see below
docker compose up -d --build
docker compose logs -f # run harness, wait for "pyclaudir is live"
docker compose exec pyclaudir python -m pyclaudir.scripts.trace --follow # tail Claude Code I/O
DM your bot. It replies.
No Docker? You need Python 3.11+ and the Claude Code CLI (claude --version).
uv sync --extra dev && uv run python -m pyclaudir # run harness, wait for "pyclaudir is live"
uv run python -m pyclaudir.scripts.trace --follow # tail Claude Code I/O
On Windows? Easiest path: install Docker Desktop and run the Quickstart from Git Bash or WSL — all commands above work as written. From PowerShell, swap nano for notepad (the rest of the commands are fine; cp is an alias for Copy-Item). From cmd.exe, additionally swap cp → copy and && chaining still works. Docker Desktop's docker compose runs identically on Windows.
What you can do with it
Overnight engineer. Brief it before bed — "build a Stripe checkout
against a mock Customer table". Wake up to a pushed branch and a
working prototype.
Market watch. Point it at a topic, get pinged the second a trend
turns. Reads RSS, scrapes pages, summarises competitor release notes —
all from one Telegram thread. Uses the always-on WebFetch andWebSearch.
Team co-pilot for startups. Your team already lives in Telegram —
now their AI does too. Drop the bot in the group chat and it tracks
who's blocked, what shipped, what slipped. Catch a bug
mid-conversation? Tell it — the Jira ticket files itself, with the
right repro steps and the right reporter. Need a stand-up summary?
It reads the last 24 hours of chat and writes one. Hand it the
backlog at 6am, get a clean board by 9. No context switch out of
Telegram, no extra dashboards to babysit.
Personal assistant. Reminders, notes, daily check-ins. Persistent
across sessions because everything writes to plain markdown files you
actually own. Always on.
Try saying
Concrete one-liners you can DM the bot today (assumes you named itLuna in prompts/project.md):
- "@Luna every weekday at 9am, read the last 24h of our team chat and DM me a 5-bullet status." — uses
set_reminder+query_db+send_message. Ships on by default. - "@Luna every Monday at 8am, pull top AI stories from Hacker News and TechCrunch and message me a briefing." —
set_reminder+WebFetch+WebSearch. Default tools. - "@Luna each evening at 9pm, ask me what I shipped today and append it to my journal." — appends to
data/memories/journal.mdviaappend_memory. Default tools. - "@Luna remind me to take meds at 9pm daily, and nag me if I don't react with 👍 within 10 min." —
set_reminder+add_reaction+query_dbto check the reaction. - "@Luna watch https://example.com/changelog hourly and ping me the moment a new entry mentions 'pricing'." — cron
set_reminder+WebFetch. Diff state lives in a memory file. - "@Luna every Friday at 5pm, review this week's git log on
~/code/myappand open a PR if the README has drifted." — needstool_groups.bash: trueandtool_groups.code: trueinplugins.json, plusGITHUB_PERSONAL_ACCESS_TOKENin.envfor the PR. - "@Luna every morning at 7am, DM me my Jira tickets due this week, grouped by project." — needs
JIRA_*env vars. - "@Luna poll the group on lunch spots — Ramen, Burrito, Salad — and message me the result at 11:45." —
create_poll+set_reminder+stop_poll. Default tools.
The pattern: you describe the outcome in chat, the bot picks the
tools and schedules itself. No YAML, no cron syntax to memorise.
Configuration
This README is the high-level intro. Deeper material lives in
docs/ — full technical manual, deployment walkthrough, tools
reference, and the systems pyclaudir descends from. Start at
docs/README.md.
The four setup files
| File | Tracked in git? | What it controls |
|---|---|---|
.env |
no | secrets — Telegram bot token, owner id, plus any credentials your plugins.json entries reference via ${VAR} (the example file's Jira / GitLab / GitHub entries demonstrate the pattern) |
prompts/project.md |
no | persona — bot name, language, house rules, owner-specific instructions; appended to the shipped prompts/system.md |
plugins.json |
no | capability surface — what tools, skills, and MCPs are on |
access.json |
no | who can DM the bot or use it in groups (hot-reloaded, no restart) |
.env.example, prompts/project.md.example, plugins.json.example, and access.json.example are tracked so you have a starting point; the real files are gitignored so different deployments carry different config without fighting over the file. access.json is auto-created on first run with the safest default (owner_only, no allowlist) if you don't seed it from the example.
What plugins.json controls
One file, four blocks. Edit and restart to apply.
{
"tool_groups": { // dangerous Claude Code built-ins, all off by default
"bash": false, // Bash, PowerShell, Monitor — shell execution
"code": false, // Edit, Write, Read, NotebookEdit, Glob, Grep, LSP
"subagents": false // Agent — token-heavy, isolated context
},
"mcps": [ // external MCP servers — stdio, http, or sse
{ // stdio (local subprocess; auth via env)
"name": "github",
"type": "stdio", // optional; "stdio" is the default
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}" },
"allowed_tools": ["mcp__github"],
"enabled": true
},
{ // http (remote server; auth via static headers)
"name": "linear",
"type": "http",
"url": "https://mcp.linear.app/mcp",
"headers": { "Authorization": "Bearer ${LINEAR_API_KEY}" },
"allowed_tools": ["mcp__linear"],
"enabled": true
}
// …Notion, Slack, Postgres, Playwright, your own — same shape; sse also supported
],
"builtin_tools_disabled": [ // pyclaudir built-ins to hide from the agent
// e.g. "create_poll", "stop_poll", "render_html", "render_latex", "send_photo"
],
"skills_disabled": [ // skill directories under skills/ to hide
// e.g. "render-style"
]
}
- Tool groups. Claude Code's dangerous built-ins (shell / code edit / subagents). All off by default. Flip to
trueand restart to unlock. - External MCPs. Three transports supported, exactly as the MCP spec defines them:
stdio(local subprocess, auth viaenv),http(remote streamable HTTP, auth via staticheaders), andsse(Server-Sent Events, same field shape as http).${VAR}references pull credentials from.env; if any required var is empty the MCP is silently skipped at boot. To stop advertising one without removing credentials, flip"enabled": false. Adding a new MCP (Linear, Notion, Slack, your own) is just a new array entry — no Python. Pyclaudir doesn't manage OAuth flows; supply an already-issued token via${VAR}. - Built-in tool toggles. Names of pyclaudir built-ins (e.g.
create_poll,render_latex) you want hidden. Filtered at MCP registration — the agent literally can't see them. A typo crashes boot with the available list. - Skill toggles. Directory names under
skills/to hide. The skill stays on disk but isn't listed or readable, so it can't be invoked.
A missing plugins.json boots locked-down (no integrations, no tool groups). A malformed file crashes boot loudly. Full schema reference: docs/tools.md.
.env
All settings come from environment variables (or .env). Full list in
pyclaudir/config.py. The ones you'll touch:
| Variable | Required | Notes |
|---|---|---|
TELEGRAM_BOT_TOKEN |
yes | from @BotFather |
PYCLAUDIR_OWNER_ID |
yes | your numeric Telegram user id |
PYCLAUDIR_MODEL |
yes | e.g. claude-opus-4-7 |
PYCLAUDIR_EFFORT |
yes | low / medium / high / max |
Credentials for any external MCP you wire in live in .env and are
pulled into plugins.json via ${VAR} references.
Access
Access lives in access.json at the repo root (hot-reloaded). One policy
gates DMs and groups: owner_only (default, owner DM only) · allowlist
(allowed_users for DMs, allowed_chats for groups) · open (everyone).
Owner-only commands: /access, /allow, /deny, /policy, /kill, /health, /audit.
Details: docs/documentation.md.
What pyclaudir can do
communication: send / reply / edit / delete text, emoji reactions, polls (regular + quiz, multi-answer, auto-close).
media: render HTML to PNG (tables, charts, diffs — Chart.js / D3 inline) and LaTeX to PNG (math via KaTeX), send back as inline photos. Read inbound photos (vision), text-like docs (md / txt / log / csv / json / yaml / code …), and PDFs (extracted text with --- page N --- markers).
memory: persistent markdown files under data/memories/ (list / read / write / append / send-as-document), 64 KiB per file, read-before-write rail, survives restarts. Per-user / per-group / journal layout.
search & history: web search and web fetch (no internal / RFC1918 URLs). Read-only SQL SELECTs on the chat database (messages, users, reminders, ≤100 rows). Multi-hop reply-chain expansion.
scheduling: one-shot + cron-recurring reminders. Auto-seeded daily self-reflection skill that promotes corrections into durable rules with owner approval.
self-edit: append rules to prompts/project.md (owner-only); shipped system.md is git-tracked and not exposed.
skills: read operator-curated playbooks under skills/ — render-style (house style for renders), self-reflection (learning loop). Reference skills are read on initiative; invoked skills require a real <reminder> envelope.
opt-in: shell (Bash / PowerShell / Monitor), code editing (Edit / Write / Read / NotebookEdit / Glob / Grep / LSP), and subagents (Agent) — all toggled in plugins.json. Off by default. Plug in any external MCP server the same way (the example file ships sample Jira / GitLab / GitHub entries to copy from).
what can't do: generate images. Send voice messages, GIFs, animations, stickers. Read voice / video / video notes / stickers (they arrive empty — ask for a screenshot or description). Moderate (mute / ban / kick / unban / member lists). Make phone calls or watch videos.
How to make AI assistant more proactive?
- Event subscribers: GitHub webhooks, file watchers, or a CI poller feed into the same engine as Telegram messages. The bot pings you when a PR review lands or a build fails, instead of you asking.
- Scheduled check-ins
- More reminders
- Idle-time sweeps: if no Telegram message for N hours, run a low-stakes routine (lint, dep audit, memory cleanup) and only ping if it finds something.
- Self-followups
Per-tool descriptions, the plugins.json schema, and how to add a new MCP / disable a built-in tool / hide a skill: docs/tools.md.
Architecture
Telegram → Engine (buffer + debounce) → Claude worker → claude process
│ │
▼ ▼
SQLite Local MCP server
- Telegram listener reads messages, saves them to SQLite, hands
them off. - Engine bundles messages that arrive close together. If a new
one arrives while Claude is mid-reply, it's injected into the
running turn. - Claude worker runs the
claudesubprocess and restarts it on
crash. - MCP server auto-loads every tool in
pyclaudir/tools/.
The engine handles one turn at a time. A long task in chat A
delays chat B until it finishes. Fine for one user; for busy setups,
run a separate bot per chat group.
The system prompt is two files: prompts/system.md
(generic pyclaudir behaviour, shipped) and prompts/project.md
(your overlay — gitignored, copy from
prompts/project.md.example).
Extending
Almost every axis of the bot is pluggable without touching the core:
- Add a built-in tool. Drop a
BaseToolsubclass into
pyclaudir/tools/ — one file, Pydantic args
model, asyncrun. The local MCP server auto-discovers it on
restart. No registry edits, no wiring. - Plug in an external MCP server. Append an entry to
plugins.json. Three transports
supported, exactly as the MCP spec
defines them:stdio(local subprocess; auth viaenv),http
(remote streamable HTTP; auth via staticheaders), andsse
(same shape as http).${VAR}references pull credentials from.env. The example file ships sample Jira, GitLab, and GitHub
entries you can keep, edit, or delete; nothing in the code path
treats them as special. Any other MCP server (Notion, Linear,
Slack, Postgres, Playwright, GitHub-remote, your own) drops in the
same way — no Python edit.
To hide a wired-in MCP without removing credentials, flipenabled: falseon its entry. - Disable a built-in tool you don't use. List it in
builtin_tools_disabledinplugins.json(e.g.create_poll,stop_poll,render_html,render_latex,send_photo). The
tool is filtered at MCP registration time — the model can't see or
invoke it. Trims the surface area without code changes. - Add a skill. Drop a playbook at
skills/<name>/SKILL.md(see
Agent Skills spec) and the
bot reads it on demand. Two ship today:self-reflection(daily
learning loop) andrender-style(house style forrender_html).
To hide one without deleting it, list its directory name inskills_disabledinplugins.json. - Reshape the persona. Name, voice, language, house rules,
default behaviours — all live inprompts/project.md. Edit and
restart; no code change. - Run a fleet. One process is one bot. Want a per-team bot,
per-project bot, work/personal split? Run multiple instances with
different.envfiles andPYCLAUDIR_DATA_DIRpaths — they share
nothing.
Observability — live tagged log ([RX] / [TX] / [CC.tool→]),
human-readable session replay (uv run python -m pyclaudir.scripts.trace --follow;
add --session <id> to pin one), raw wire log indata/cc_logs/<session>.stream.jsonl, plus sqlite3 data/pyclaudir.db
for cross-session queries. Talk to the bot's own session interactively
with claude --resume $(cat data/session_id) --fork-session.
Security
The bot is public-facing — anyone in an allowed chat can talk to it.
Enforced in code:
- Tight default surface. By default no shell, no file edits, no reads
outsidedata/memories/, no subagents — by default. The CC
subprocess is spawned with--allowedTools mcp__pyclaudir,WebFetch,WebSearch(plus opt-in
groups when their env flag is set) and a deny list covering every
gated tool. See docs/tools.md. - Web access is read-only, with private/internal URLs refused at
the prompt layer. A determined prompt injection could still get
one through — don't host pyclaudir next to sensitive internal
endpoints. - Memory writes are guarded — path-hardened, 64 KiB cap,
read-before-write, no delete tool. query_dbis read-only (single SELECT, sqlglot-validated,
100-row cap).- Rate limit of 20 DM/min per user (owner exempt; groups not
limited). - Inbound text is scrubbed for tokens/keys before hitting SQLite.
- Owner-only commands check
effective_user.id == PYCLAUDIR_OWNER_ID. - Wedged subprocesses are killed and respawned. Crash-loops give
up after 10 crashes in 10 min and notify the owner.
Contributing
Issues and PRs welcome. Three rules before you start:
- Run the suite —
uv run python -m pytest -q. 346 tests today;
keep them green. - Persona-agnostic code. Don't hardcode bot names, owner-specific
strings, or chat ids inpyclaudir/. Persona lives inprompts/project.mdand stays there. - Default surface stays tight. The bot ships off-by-default for
shell, code editing, and subagents. External MCPs spawn only when
their${VAR}credentials are set in.env(the example file's
Jira / GitLab / GitHub entries follow this pattern, but they're
examples — not first-class). New capabilities follow the same
rule — gated behind atool_groupsflag inplugins.jsonor
behind a credentialledmcps[]entry, unless they're strictly
safer than the current base.
Architecture deep-dive before bigger changes:
docs/documentation.md and
docs/reference-architectures.md.
License
MIT. See LICENSE.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi