A minimal Python framework for building stateful REPL applications with ASCII display
Project description
ReplKit2
Flask-style framework for building stateful REPL applications with rich display, MCP integration, and multi-mode deployment.
✨ Features
- 🚀 Multi-mode: REPL, CLI, MCP server from one codebase
- 🎨 Rich display: Tables, trees, boxes, charts, markdown
- 🔌 MCP ready: Tools, resources, prompts for Claude/LLMs
- ⚡ CLI support: Traditional command-line interface via Typer
- 🎯 Type safe: Full type hints, MCP-compatible validation
📦 Installation
# With uv (recommended)
uv add replkit2 # Core library only
uv add "replkit2[all]" # MCP + CLI support
uv add "replkit2[mcp,cli]" # Same as above
uv add "replkit2[examples]" # For running examples
# Or with pip
pip install replkit2
pip install replkit2[all] # MCP + CLI support
pip install replkit2[mcp,cli] # Same as above
pip install replkit2[examples] # For running examples
🚀 Quick Start
from dataclasses import dataclass, field
from replkit2 import App
@dataclass
class State:
tasks: list = field(default_factory=list)
next_id: int = 1
app = App("todo", State)
@app.command(display="table", headers=["ID", "Task", "Done"])
def list_tasks(state):
"""List all tasks."""
return [{"ID": t["id"], "Task": t["text"], "Done": "✓" if t["done"] else ""}
for t in state.tasks]
@app.command()
def add(state, text: str):
"""Add a task."""
task = {"id": state.next_id, "text": text, "done": False}
state.tasks.append(task)
state.next_id += 1
return f"Added: {text}"
@app.command()
def done(state, id: int):
"""Mark task as done."""
for task in state.tasks:
if task["id"] == id:
task["done"] = True
return f"Completed task {id}"
return f"Task {id} not found"
if __name__ == "__main__":
import sys
if "--mcp" in sys.argv:
app.mcp.run() # MCP server for Claude/LLMs
elif "--cli" in sys.argv:
app.cli() # Traditional CLI
else:
app.run(title="Todo Manager") # Interactive REPL
Run it:
python todo.py # Interactive REPL
python todo.py --cli add "Buy milk" # CLI mode
python todo.py --cli list_tasks # CLI mode
python todo.py --mcp # MCP server
🎨 Display Types
@app.command(display="table", headers=["Name", "Status"])
def show_table(state):
return [{"Name": "Item 1", "Status": "Active"}]
@app.command(display="box", title="Info")
def show_box(state):
return "This is in a box!"
@app.command(display="tree")
def show_tree(state):
return {"root": {"child1": "leaf", "child2": ["item1", "item2"]}}
@app.command(display="progress", show_percentage=True)
def show_progress(state):
return {"value": 7, "total": 10}
🔌 MCP Integration
# Tool (callable action)
@app.command(fastmcp={"type": "tool"})
def process(state, text: str, count: int = 1):
return f"Processed '{text}' {count} times"
# Resource (readable data at app://get_task/123)
@app.command(fastmcp={"type": "resource"})
def get_task(state, id: int):
return {"id": id, "data": state.tasks.get(id)}
# Prompt template
@app.command(fastmcp={"type": "prompt"})
def brainstorm(state, topic: str = ""):
context = "\n".join(t["text"] for t in state.tasks[:5])
return f"Based on these tasks:\n{context}\n\nBrainstorm about: {topic}"
Configure Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"todo": {
"command": "python",
"args": ["/path/to/todo.py", "--mcp"]
}
}
}
⚡ CLI Support
@app.command(
typer={"name": "ls", "help": "List tasks with filters"}
)
def list_tasks(state, done: bool = False, limit: int = 10):
tasks = [t for t in state.tasks if not done or t.get("done")]
return tasks[:limit]
# Usage:
# python todo.py --cli ls --done --limit 5
# python todo.py --cli add "New task"
# python todo.py --cli done 1
🎯 Type Safety
# ✅ Good - MCP compatible
def cmd(state,
required: str, # Required param
optional: str = None, # Optional with None
items: List[str] = None, # Typed list
config: Dict[str, int] = None, # Typed dict
):
pass
# ❌ Bad - causes "unknown" in MCP
def cmd(state,
untyped, # Missing annotation
opt: Optional[str] = None, # Don't use Optional
either: Union[str, int] = "", # Don't use Union
):
pass
📁 Examples
todo.py- Full task manager with persistencenotes_mcp.py- MCP server with all typesmonitor.py- System monitoring dashboardtyper_demo.py- CLI with JSON statemarkdown_demo.py- Markdown rendering
Run examples:
cd examples
python todo.py # REPL mode
python notes_mcp.py --mcp # MCP server
python typer_demo.py --cli --help # CLI help
📚 Documentation
- CHANGELOG.md - Version history
- ROADMAP.md - Future plans
- CLAUDE.md - Development guide
- src/replkit2/llms.txt - LLM quick reference
🛠️ Development
# Clone and install
git clone https://github.com/angelsen/replkit2
cd replkit2
uv sync --group dev
# Type check
uv run basedpyright src/replkit2
# Format & lint
uv run ruff format src/
uv run ruff check src/
📄 License
MIT - see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file replkit2-0.7.6.tar.gz.
File metadata
- Download URL: replkit2-0.7.6.tar.gz
- Upload date:
- Size: 101.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc99975074aa7841a83c2fb9549d0b08982254816baac809de531171771a28e1
|
|
| MD5 |
cc0a9f180e98a5c8da43e61cff0b2e54
|
|
| BLAKE2b-256 |
90ca9e25560793aadfe0729de320f3bea37754e3d7da184b52f0b8c74cfe54e1
|
File details
Details for the file replkit2-0.7.6-py3-none-any.whl.
File metadata
- Download URL: replkit2-0.7.6-py3-none-any.whl
- Upload date:
- Size: 35.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1d5ba92ad0284aa65523a39abc1d72d2c93cb3d42772b82caff252737d17326
|
|
| MD5 |
a434de778066c9db49021d8b0f5dda8b
|
|
| BLAKE2b-256 |
e1a7c1780d263bb5bef4326bcce7c5bc54f7058861915d254be22c559d0e16fb
|