Skip to content

Repository files navigation

Jarvis β€” Personal AI Agent Starter

A barebones starter template for building a personal 24/7 AI assistant that runs on your machine and communicates via Telegram.

What This Is

Jarvis is a personal AI agent that:

  • Runs 24/7 as a background process
  • Communicates through Telegram
  • Uses Claude as its reasoning engine
  • Orchestrates tasks via MCP servers (filesystem, browser, code sandbox, and more)
  • Maintains conversation history and long-term memory
  • Requires explicit approval for risky operations

Key Differences from the Production Version

This starter is intentionally simplified for clarity:

  • Removed complex retry/event logic (kept the basics)
  • Simplified error handling
  • Removed production features (voice calls, smart home, job tracker, etc.)
  • Streamlined MCP server setup (filesystem, playwright, sandbox, memory only)
  • Minimal but functional scheduler and memory system

This is a working foundation β€” you can run it immediately after adding your API keys. Build additional features on top as needed.

Architecture

main.py (entry point / orchestrator)
  β”œβ”€β”€ PersonalAgent (Claude Agent SDK)
  β”‚   β”œβ”€β”€ MCP Servers (filesystem, playwright, sandbox, memory)
  β”‚   β”œβ”€β”€ Risk classification hook
  β”‚   └── Context loader (personality, skills, memory)
  β”œβ”€β”€ TelegramBot (aiogram)
  β”‚   β”œβ”€β”€ Handlers (/start, /task, /status, /model)
  β”‚   β”œβ”€β”€ Approval flow (inline keyboard)
  β”‚   └── Message splitting
  β”œβ”€β”€ TaskStore (Redis)
  β”œβ”€β”€ Scheduler (basic cron)
  └── Memory system (ChromaDB for vector search)

Quick Start

1. Prerequisites

  • Python 3.12+
  • Redis (local or Docker)
  • Claude API key
  • Telegram bot token

2. Clone & Install

git clone <this-repo> jarvis
cd jarvis

# Install dependencies
uv sync --all-packages

# Or with pip
pip install -r requirements.txt

3. Environment Setup

Copy .env.example to .env and fill in your credentials:

cp .env.example .env

Then edit .env:

ANTHROPIC_API_KEY=sk-ant-...
TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
TELEGRAM_CHAT_ID=your_user_id
TELEGRAM_ALLOWED_USER_IDS=[your_user_id]
REDIS_URL=redis://localhost:6379

Get your Telegram credentials:

  • Bot Token: Create a bot via @BotFather, get the token
  • Chat ID: Send a message to your bot, then visit https://api.telegram.org/bot<TOKEN>/getUpdates to see your user ID

4. Start Redis

Option A: Local (requires redis-server installed)

redis-server

Option B: Docker

docker run -d -p 6379:6379 redis:7-alpine

5. Run the Agent

uv run python main.py

You should see:

INFO: redis_connected url=redis://localhost:6379
INFO: starting_agent model=claude-sonnet-4-6
INFO: telegram_bot_starting

Open Telegram and send a message to your bot. It should respond!

Usage

Send commands to your bot via Telegram:

  • /task <description> β€” Submit a task for the agent to complete

    /task find me a recipe for chocolate chip cookies
    
  • /status β€” View currently running tasks

    /status
    
  • /model <name> β€” Switch AI model (haiku, sonnet, opus)

    /model opus
    
  • Regular message β€” Chat with the agent

    What's the weather like in NYC?
    

Project Structure

jarvis-starter/
β”œβ”€β”€ main.py                              # Entry point
β”œβ”€β”€ pyproject.toml                       # Root workspace config
β”œβ”€β”€ compose.yaml                         # Docker Compose (optional)
β”œβ”€β”€ .env.example                         # Environment template
β”œβ”€β”€ README.md                            # This file
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ core/src/core/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   β”œβ”€β”€ agent.py                     # PersonalAgent (Claude Agent SDK wrapper)
β”‚   β”‚   β”œβ”€β”€ config.py                    # Settings (pydantic)
β”‚   β”‚   β”œβ”€β”€ context.py                   # ContextLoader (personality + skills)
β”‚   β”‚   β”œβ”€β”€ state.py                     # TaskStore + ConversationBuffer (Redis)
β”‚   β”‚   β”œβ”€β”€ risk.py                      # Risk classifier (2-tier)
β”‚   β”‚   β”œβ”€β”€ humanize.py                  # Human-readable tool descriptions
β”‚   β”‚   └── logging.py                   # Structured logging
β”‚   β”œβ”€β”€ interfaces/src/interfaces/telegram/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   β”œβ”€β”€ bot.py                       # TelegramBot class
β”‚   β”‚   β”œβ”€β”€ handlers.py                  # Command handlers
β”‚   β”‚   β”œβ”€β”€ middleware.py                # Auth middleware
β”‚   β”‚   β”œβ”€β”€ approval.py                  # Inline approval flow
β”‚   β”‚   └── attachments.py               # File downloads
β”‚   β”œβ”€β”€ mcp_servers/src/mcp_servers/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   β”œβ”€β”€ memory/server.py             # Memory MCP server (ChromaDB)
β”‚   β”‚   └── memory/__init__.py
β”‚   β”œβ”€β”€ pyproject.toml                   # Package workspace config
β”‚   └── pyproject.toml (each package)
β”œβ”€β”€ tools/memory/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ store.py                         # MemoryStore class
β”‚   └── __main__.py                      # CLI (store/search/list)
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ agent_context/
β”‚   β”‚   β”œβ”€β”€ personality.md               # Agent identity & tone
β”‚   β”‚   β”œβ”€β”€ schedules.md                 # Cron schedule entries
β”‚   β”‚   β”œβ”€β”€ memory/
β”‚   β”‚   β”‚   β”œβ”€β”€ preferences.md           # User preferences (auto-written)
β”‚   β”‚   β”‚   β”œβ”€β”€ projects.md              # Active projects (auto-written)
β”‚   β”‚   β”‚   β”œβ”€β”€ chat_history.md          # Session summaries (auto-written)
β”‚   β”‚   β”‚   └── journal.md               # Task journal (auto-written)
β”‚   β”‚   └── skills/
β”‚   β”‚       β”œβ”€β”€ _index.md                # Skill registry
β”‚   β”‚       β”œβ”€β”€ _manager.md              # Skill routing logic
β”‚   β”‚       └── example-skill.md         # Example skill definition
β”‚   β”œβ”€β”€ memory/chroma/                   # Vector store (auto-created)
β”‚   └── attachments/                     # Downloaded files
β”œβ”€β”€ configs/
β”‚   β”œβ”€β”€ agent.yaml                       # Runtime configuration
β”‚   └── risk_policy.yaml                 # Risk classification overrides
└── tests/
    β”œβ”€β”€ conftest.py                      # pytest fixtures
    └── unit/
        └── test_example.py              # Example test

Configuration

Main Config (configs/agent.yaml)

agent:
  model: "claude-sonnet-4-6"             # Primary model
  max_turns: 50                          # Max conversation turns
  approval_timeout_seconds: 300          # How long to wait for approval
  task_timeout_seconds: 600              # Task execution timeout
  timezone: "America/New_York"           # For scheduled tasks

workspace:
  allowed_paths:                         # Paths the agent can access
    - "/Users/YOUR_NAME/Documents"
    - "/Users/YOUR_NAME/Downloads"
  context_dir: "data/agent_context"      # Where context files live

logging:
  level: "INFO"                          # DEBUG, INFO, WARNING, ERROR
  format: "json"                         # json or console

Risk Policy (configs/risk_policy.yaml)

Define which operations require approval:

risk_overrides:
  mcp__gmail__send_email: "approval"     # Always ask before sending email
  mcp__filesystem__write_file: "autonomous"  # Auto-write files (careful!)

Core Concepts

PersonalAgent

Wraps the Claude Agent SDK with:

  • MCP server configuration
  • Risk classification hook (approve/deny decisions)
  • Context loading (personality + skills + memory)
  • Fallback handling (retries with different models)

Risk Classification

Two-tier system:

  • Autonomous: Safe operations (reading files, web search, code execution) β€” execute immediately
  • Require-Approval: Risky operations (sending emails, deleting files) β€” ask user via Telegram inline keyboard

Override in configs/risk_policy.yaml to customize.

TelegramBot

Handles:

  • Command routing (/task, /status, /model, etc.)
  • Approval flow (inline keyboard with Approve/Deny buttons)
  • Message splitting (Telegram max 4096 chars)
  • Auth middleware (allowlist user IDs)

Memory System

Three levels:

  1. Conversation Buffer (Redis, TTL 1hr) β€” Recent chat history for context
  2. Chat History (file, auto-trimmed) β€” Session summaries (personality.md loads this)
  3. Vector Memory (ChromaDB) β€” Searchable summaries from past tasks

Use the memory CLI:

uv run python -m tools.memory store "summary text" --topics "topic1,topic2"
uv run python -m tools.memory search "what did I do about X?"
uv run python -m tools.memory list --last 10

Skills

Define repeatable workflows in data/agent_context/skills/:

## Daily News Briefing

**Trigger:** Scheduled daily at 9 AM

**Steps:**
1. Search for tech news
2. Compile top stories
3. Send summary via Telegram

**Tools Required:** WebSearch, Telegram

**Tags:** autonomous, scheduled

**Composable With:** email-digest

Register in skills/_index.md for the agent to find and use them.

Extending

Add a New MCP Server

Edit packages/core/src/core/agent.py β†’ _build_mcp_servers():

servers["my-server"] = {
    "type": "stdio",
    "command": "npx",
    "args": ["-y", "@example/my-mcp-server"],
}

Add a New Telegram Command

Edit packages/interfaces/src/interfaces/telegram/handlers.py:

async def cmd_mycommand(message: Message, task_store: TaskStore) -> None:
    # your handler logic
    await message.answer("Result!")

def create_router(...):
    router.message.register(cmd_mycommand, Command("mycommand"))

Customize Agent Personality

Edit data/agent_context/personality.md β€” everything here loads into the system prompt.

Store Long-Term Memory

After completing a task, use:

from tools.memory import MemoryStore

store = MemoryStore()
store.store(
    "Fixed the deployment bug by rolling back schema migration",
    topics=["devops", "database"],
    files_touched=["migrations/001_fix.sql"],
)

Running Tests

# All tests
uv run pytest tests/ -v

# Single test file
uv run pytest tests/unit/test_example.py -v

# With coverage
uv run pytest tests/ --cov=packages/

Environment Variables

Variable Required Default Purpose
ANTHROPIC_API_KEY Yes β€” Claude API key
TELEGRAM_BOT_TOKEN Yes β€” Telegram bot token
TELEGRAM_CHAT_ID Yes β€” Your Telegram user ID
TELEGRAM_ALLOWED_USER_IDS Yes β€” List of allowed user IDs (JSON)
REDIS_URL No redis://localhost:6379 Redis connection string
CONFIG_PATH No configs/agent.yaml Path to config file
RISK_POLICY_PATH No configs/risk_policy.yaml Path to risk policy file
OPENAI_API_KEY No β€” For memory embeddings (optional)

Troubleshooting

"redis_connected" never appears

Redis isn't running. Start it:

redis-server  # or docker run -d -p 6379:6379 redis:7-alpine

Bot doesn't respond to messages

  1. Check TELEGRAM_CHAT_ID is correct (not bot ID)
  2. Check bot token is valid
  3. Check logs: uv run python main.py 2>&1 | grep -i error
  4. Make sure your user ID is in TELEGRAM_ALLOWED_USER_IDS

Task times out

Increase approval_timeout_seconds or task_timeout_seconds in configs/agent.yaml.

"API unavailable" errors

Claude API is rate-limited or down. The agent will retry with a cheaper model (haiku). Check your API quota and billing.

ChromaDB errors on startup

Delete data/memory/chroma/ and restart β€” it will recreate the database.

Next Steps

  1. Personalize personality.md β€” Update identity, tone, and rules to match your preferences
  2. Add your first skill β€” Create a repeatable workflow in data/agent_context/skills/
  3. Enable a new MCP server β€” Integrate Google Calendar, email, or custom tools
  4. Set up scheduled tasks β€” Add entries to data/agent_context/schedules.md
  5. Build context β€” Let the agent run and it will auto-populate preferences.md, projects.md, chat_history.md

Architecture Notes

  • Claude Agent SDK subprocess model β€” Clean, isolated agent execution
  • Local ChromaDB β€” No cloud vector DB dependency
  • Redis for state β€” Task store, conversation buffer, approval flow
  • Async/await throughout β€” Efficient, non-blocking operations
  • Haiku fallback β€” Cheaper model for retries on API issues

License

This starter is provided as-is. Modify and extend freely.

Support

  • CLAUDE.md in the main repo β€” Full documentation of the production version
  • tests/ β€” Example unit tests showing how to test each component
  • Inline code comments β€” Each module explains its purpose and design

Happy building! πŸš€

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages