Connecting OpenClaw to Your To-Do Lists and Task Managers

Clawpedia · For Humans

Sync OpenClaw with popular task management tools like Todoist, Notion, and Trello.

Connecting OpenClaw to Your To-Do Lists and Task Managers

Turn OpenClaw into your personal productivity assistant by connecting it to popular task management platforms. This guide covers integration with Todoist, Notion, Linear, Jira, and more.

Integration Architecture


┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   "Add task:  │ ──→ │  OpenClaw     │ ──→ │  Task API    │
│   Fix login   │     │  Agent        │     │  (Todoist,   │
│   bug, high   │     │  routes to    │     │   Notion...) │
│   priority"   │ ←── │  right tool   │ ←── │              │
└──────────────┘     └──────────────┘     └──────────────┘

Todoist Integration

Setup


# config.yaml
integrations:
  todoist:
    api_key: "${TODOIST_API_KEY}"
    default_project: "Inbox"

OpenClaw Skill


// skills/todoist/index.js
const fetch = require("node-fetch");

const TODOIST_API = "https://api.todoist.com/rest/v2";

module.exports = {
  name: "todoist",
  description: "Manage tasks in Todoist",
  
  tools: [
    {
      name: "add_task",
      description: "Create a new task in Todoist",
      parameters: {
        type: "object",
        properties: {
          content: { type: "string", description: "Task title" },
          description: { type: "string", description: "Task details" },
          priority: { type: "number", enum: [1, 2, 3, 4], description: "1=normal, 4=urgent" },
          due_string: { type: "string", description: "e.g., 'tomorrow', 'next Monday'" },
          project_id: { type: "string" },
          labels: { type: "array", items: { type: "string" } }
        },
        required: ["content"]
      },
      
      async execute(params) {
        const response = await fetch(`${TODOIST_API}/tasks`, {
          method: "POST",
          headers: {
            "Authorization": `Bearer ${process.env.TODOIST_API_KEY}`,
            "Content-Type": "application/json"
          },
          body: JSON.stringify(params)
        });
        return response.json();
      }
    },
    
    {
      name: "list_tasks",
      description: "Get tasks from Todoist with optional filters",
      parameters: {
        type: "object",
        properties: {
          filter: { type: "string", description: "Todoist filter query, e.g., 'today', 'overdue'" }
        }
      },
      
      async execute({ filter = "today" }) {
        const response = await fetch(
          `${TODOIST_API}/tasks?filter=${encodeURIComponent(filter)}`,
          {
            headers: { "Authorization": `Bearer ${process.env.TODOIST_API_KEY}` }
          }
        );
        return response.json();
      }
    },
    
    {
      name: "complete_task",
      description: "Mark a task as complete",
      parameters: {
        type: "object",
        properties: {
          task_id: { type: "string" }
        },
        required: ["task_id"]
      },
      
      async execute({ task_id }) {
        await fetch(`${TODOIST_API}/tasks/${task_id}/close`, {
          method: "POST",
          headers: { "Authorization": `Bearer ${process.env.TODOIST_API_KEY}` }
        });
        return { completed: true, task_id };
      }
    }
  ]
};

Notion Integration


// skills/notion-tasks/index.js
const { Client } = require("@notionhq/client");

module.exports = {
  name: "notion-tasks",
  
  async onActivate(context) {
    context.state.notion = new Client({ 
      auth: process.env.NOTION_API_KEY 
    });
  },
  
  tools: [
    {
      name: "add_notion_task",
      description: "Add a task to a Notion database",
      parameters: {
        type: "object",
        properties: {
          title: { type: "string" },
          status: { type: "string", enum: ["To Do", "In Progress", "Done"] },
          priority: { type: "string", enum: ["Low", "Medium", "High"] },
          due_date: { type: "string", description: "ISO date string" },
          assignee: { type: "string" }
        },
        required: ["title"]
      },
      
      async execute(params, context) {
        const databaseId = process.env.NOTION_TASKS_DB_ID;
        
        const properties = {
          "Name": { title: [{ text: { content: params.title } }] },
          "Status": { select: { name: params.status || "To Do" } },
          "Priority": { select: { name: params.priority || "Medium" } }
        };
        
        if (params.due_date) {
          properties["Due Date"] = { date: { start: params.due_date } };
        }
        
        const page = await context.state.notion.pages.create({
          parent: { database_id: databaseId },
          properties
        });
        
        return { success: true, page_id: page.id, url: page.url };
      }
    },
    
    {
      name: "query_notion_tasks",
      description: "Query tasks from Notion database",
      parameters: {
        type: "object",
        properties: {
          status: { type: "string" },
          priority: { type: "string" }
        }
      },
      
      async execute(params, context) {
        const databaseId = process.env.NOTION_TASKS_DB_ID;
        const filters = [];
        
        if (params.status) {
          filters.push({
            property: "Status",
            select: { equals: params.status }
          });
        }
        
        const query = {
          database_id: databaseId,
          sorts: [{ property: "Priority", direction: "ascending" }]
        };
        
        if (filters.length > 0) {
          query.filter = filters.length === 1 
            ? filters[0] 
            : { and: filters };
        }
        
        const response = await context.state.notion.databases.query(query);
        return response.results.map(page => ({
          id: page.id,
          title: page.properties.Name?.title?.[0]?.text?.content,
          status: page.properties.Status?.select?.name,
          priority: page.properties.Priority?.select?.name
        }));
      }
    }
  ]
};

Linear Integration


// skills/linear-tasks/index.js
module.exports = {
  name: "linear-tasks",
  
  tools: [
    {
      name: "create_linear_issue",
      description: "Create an issue in Linear",
      parameters: {
        type: "object",
        properties: {
          title: { type: "string" },
          description: { type: "string" },
          team: { type: "string" },
          priority: { type: "number", description: "0=none, 1=urgent, 2=high, 3=medium, 4=low" },
          labels: { type: "array", items: { type: "string" } }
        },
        required: ["title", "team"]
      },
      
      async execute(params) {
        const response = await fetch("https://api.linear.app/graphql", {
          method: "POST",
          headers: {
            "Authorization": process.env.LINEAR_API_KEY,
            "Content-Type": "application/json"
          },
          body: JSON.stringify({
            query: `mutation {
              issueCreate(input: {
                title: "${params.title}"
                description: "${params.description || ""}"
                teamId: "${params.team}"
                priority: ${params.priority || 0}
              }) {
                issue { id identifier url title }
              }
            }`
          })
        });
        
        const data = await response.json();
        return data.data.issueCreate.issue;
      }
    }
  ]
};

Natural Language Task Management

Configure your agent to understand natural task commands:


system_prompt: |
  You are a task management assistant. Parse natural language into actions:
  
  "Add: Fix login bug, high priority, due tomorrow"
  → add_task(content: "Fix login bug", priority: 3, due_string: "tomorrow")
  
  "What's on my plate today?"
  → list_tasks(filter: "today")
  
  "Done with the API refactoring"
  → Search tasks matching "API refactoring" → complete_task(id)
  
  "Move all low-priority bugs to next week"
  → list_tasks(filter: "p1 & @bugs") → update each with due: "next Monday"
  
  Always confirm before bulk operations.
  After any change, show the updated task list.

Multi-Platform Sync

If you use multiple task managers, OpenClaw can sync between them:


// skills/task-sync/index.js
module.exports = {
  name: "task-sync",
  
  tools: [
    {
      name: "sync_tasks",
      description: "Sync tasks between platforms",
      async execute({ source, target }) {
        // Fetch from source
        const sourceTasks = await fetchTasks(source);
        // Map to target format
        const mapped = sourceTasks.map(t => mapTask(t, target));
        // Create in target
        for (const task of mapped) {
          await createTask(target, task);
        }
        return { synced: mapped.length };
      }
    }
  ]
};

Daily Task Reports


system_prompt: |
  At the start of each conversation, offer a task summary:
  
  📋 **Your Day**
  
  🔴 Overdue: [count]
  🟡 Due today: [count]  
  🟢 Completed today: [count]
  
  Top 3 priorities:
  1. [highest priority task]
  2. [next task]
  3. [next task]
  
  Would you like to dive into any of these?

Tips for Effective Task Management

Related Articles