MCP Todo Tools

Four MCP tools any client can call to read and mutate the same todo store as the runtime

The praisonai-mcp host exposes four MCP tools that read and write the same todo store as the agent runtime (todo_add / todo_list / todo_update) — a todo added in Claude Desktop is visible to the runtime on the same machine, and vice versa.

python
from praisonaiagents import Agent

agent = Agent(name="Planner", instructions="Break work into small todos.")
agent.start("Plan a REST API")

Run praisonai-mcp serve --transport stdio, point Claude Desktop at it, and the assistant can list, add, complete, and delete the same todos.

Diagram

📋 MCP Client
Claude Desktop / Cursor

⚙️ praisonai-mcp

🛠️ praisonai.todo.*

💾 Shared store
~/.praisonai/todos.json

🤖 Agent runtime
todo_add / todo_list

Quick Start

  1. Serve the host
    bash
    praisonai-mcp serve --transport stdio
  2. Add a todo from an agent run
    python
    from praisonaiagents import Agent
    
    agent = Agent(name="Planner", instructions="Break work into small todos.")
    agent.start("Plan the release")
  3. Read it back from your client

    In Claude Desktop: > List my todos.

    The assistant calls praisonai.todo.list and sees the todo the runtime wrote.


Tools

Four tools share the runtime’s store and record schema (id int, task, priority, category, status).

ToolArgumentsDescription
praisonai.todo.list—List every todo. Returns "No todos found" when the store is empty.
praisonai.todo.addcontent (str), priority (str, default "medium")Append a todo. Returns "Todo added: <id>" where id is max(existing) + 1 (starts at 1).
praisonai.todo.completetodo_id (str)Mark the matching todo completed. todo_id is compared to the runtime’s integer id as a string, so both "1" and 1 match. Returns "Todo completed: <id>", or "Todo not found: <id>" if no match.
praisonai.todo.deletetodo_id (str)Delete the matching todo. Returns "Todo deleted: <id>", or "Todo not found: <id>" when nothing matched — a real error, not the silent no-op of the old code.

Record Shape

The store is a JSON array — each todo carries an integer id and a task field.

json
[
  {
    "id": 1,
    "task": "Ship the release",
    "priority": "high",
    "category": "general",
    "status": "pending",
    "created_at": "2026-09-08T15:00:00Z"
  }
]

Same shape the agent runtime writes — MCP-created and runtime-created todos read each other’s records field-for-field.


Store Location

The MCP tools resolve the same file path as praisonaiagents.tools.todo_tools.TodoTools._get_todo_file().

WhenPath
A workspace is active<workspace>/todos.json
No workspace~/.praisonai/todos.json

Never ~/.praison/todo.json — that was the old wrong path and is no longer read or written by any surface.


End-to-End Flow

Diagram
todos.jsonpraisonai.todo.*praisonai-mcpClaude DesktopUsertodos.jsonpraisonai.todo.*praisonai-mcpClaude DesktopUser“add a todo: Ship it”praisonai.todo.addTodoTools()._save_todos()append {id:1, task:”Ship it”}“list my todos”praisonai.todo.listTodoTools()._load_todos()read todos.json[{id:1, task:”Ship it”}]“Todo added: 1” then the list“1. Ship it (pending, medium)”

Best Practices

Workspace switches the visible list

A todo added inside ~/code/api-service/ writes to ~/code/api-service/todos.json. Switching directories switches the visible list — useful for keeping unrelated todos apart.

Ids are integers under the hood

The public MCP surface accepts strings, but the underlying id is an integer. str(id) is safe; parse ids back as int.

Delete is safe to retry

praisonai.todo.delete returns "Todo not found: <id>" when nothing matched, so a client can repeat a delete without failing hard.

Migrate off the old path

Any tooling that reads ~/.praison/todo.json is looking at the pre-#4962 layout, which is no longer written. Migrate to ~/.praisonai/todos.json or the workspace todos.json.


Related