By James Aspinwall, co-written by Alfred (your trusted AI agent) – February 25, 2026, 14:00
This demo walks through the WorkingAgents task management system and shows how tasks integrate with contacts, companies, and other NIS entities. Every command below runs through the MCP tool interface — the same tools available to AI agents and the web UI.
The Setup: A Consulting Pipeline
You’re managing an AI consulting engagement. You have a prospect (David Chen at Coastal Logistics), a proposal to write, and a team to coordinate. Let’s build this out with tasks and entity links.
1. Create a Contact and Company
nis_create_contact({
name: "David Chen",
title: "VP Operations",
email: "[email protected]",
phone: "+1-555-0142"
})
→ {id: 1740001}
nis_create_company({
name: "Coastal Logistics",
industry: "Supply Chain & Warehousing",
website: "https://coastallogistics.com"
})
→ {id: 1740002}
Now you have a contact and a company in NIS. On their own, they’re just records. Tasks are what turn them into actionable work.
2. Create Tasks
task_create({
title: "Prepare ROI analysis for Coastal Logistics",
priority: 7,
due_at: 1740700800,
tags: ["#sales", "#coastal"],
note: "David needs warehouse efficiency data. Include 30% improvement case study."
})
→ {id: 1740100}
task_create({
title: "Schedule discovery call with David Chen",
priority: 8,
due_at: 1740500000,
tags: ["#sales", "#coastal"]
})
→ {id: 1740101}
task_create({
title: "Draft proposal document",
priority: 5,
tags: ["#sales", "#coastal"],
note: "Template in asset/docs/proposal-template.md"
})
→ {id: 1740102}
Three tasks, all tagged #coastal. But tags are just labels — they don’t know about David or Coastal Logistics as entities. That’s where linking comes in.
3. Link Tasks to Entities
This is the key integration. Link each task to the contact and company it relates to:
task_link({id: 1740100, entity_type: "company", entity_id: 1740002})
→ {status: "linked"}
task_link({id: 1740100, entity_type: "contact", entity_id: 1740001})
→ {status: "linked"}
task_link({id: 1740101, entity_type: "contact", entity_id: 1740001})
→ {status: "linked"}
task_link({id: 1740102, entity_type: "company", entity_id: 1740002})
→ {status: "linked"}
Now the data has structure. The ROI analysis is connected to both David (the person requesting it) and Coastal Logistics (the company it’s for). The discovery call is connected to David. The proposal is connected to the company.
Duplicate links are handled gracefully — linking the same pair again returns {status: "already_linked"} instead of an error.
4. Query: What’s Linked to What?
All links for a task:
task_links({id: 1740100})
→ [
{entity_type: "company", entity_id: 1740002},
{entity_type: "contact", entity_id: 1740001}
]
All tasks for a contact:
task_entity_tasks({entity_type: "contact", entity_id: 1740001})
→ [
{id: 1740101, title: "Schedule discovery call with David Chen", priority: 8, ...},
{id: 1740100, title: "Prepare ROI analysis for Coastal Logistics", priority: 7, ...}
]
Results come back sorted by priority (highest first). When you open David Chen’s contact, you immediately see what needs doing — discovery call first, then the ROI analysis.
All tasks for a company:
task_entity_tasks({entity_type: "company", entity_id: 1740002})
→ [
{id: 1740100, title: "Prepare ROI analysis for Coastal Logistics", priority: 7, ...},
{id: 1740102, title: "Draft proposal document", priority: 5, ...}
]
5. Subtasks: Break Down the Work
The ROI analysis is complex. Break it into subtasks:
task_create({
title: "Pull warehouse throughput benchmarks",
priority: 6,
parent_id: 1740100,
tags: ["#research"]
})
→ {id: 1740200}
task_create({
title: "Calculate 3-year cost savings projection",
priority: 6,
parent_id: 1740100,
tags: ["#analysis"]
})
→ {id: 1740201}
task_create({
title: "Write executive summary",
priority: 4,
parent_id: 1740100,
tags: ["#writing"]
})
→ {id: 1740202}
Get the task with subtasks included:
task_get({id: 1740100})
→ {
id: 1740100,
title: "Prepare ROI analysis for Coastal Logistics",
priority: 7,
status: "todo",
links: [
{entity_type: "company", entity_id: 1740002},
{entity_type: "contact", entity_id: 1740001}
],
subtasks: [
{id: 1740200, title: "Pull warehouse throughput benchmarks", status: "todo"},
{id: 1740201, title: "Calculate 3-year cost savings projection", status: "todo"},
{id: 1740202, title: "Write executive summary", status: "todo"}
]
}
The parent task carries its entity links. Subtasks inherit the context — you know why you’re pulling benchmarks without having to tag each subtask.
6. Natural Language Capture
In a hurry? Use task_capture with plain text:
task_capture({text: "Call David about warehouse tour next Friday #coastal !!"})
→ {
title: "Call David about warehouse tour",
due_at: 1741046400,
tags: ["#coastal"],
priority: 7
}
The parser extracts dates, tags, and priority (!! = high priority). You can then link the created task to David’s contact.
7. Task Lifecycle
Start working:
task_update({id: 1740200, status: "in_progress"})
Block on something:
task_update({id: 1740201, status: "blocked", waiting_for: "Coastal Logistics to share current throughput data"})
Snooze until later:
task_snooze({id: 1740102, until: "next monday"})
→ {status: "snoozed", after_at: 1741046400}
Complete a task:
task_complete({id: 1740200})
→ {status: "completed", completed_at: 1740600000}
Complete with a note:
task_done({id: 1740101, note: "David confirmed Thursday 2pm. Zoom link sent."})
8. Recurring Tasks
For work that repeats:
task_create({
title: "Weekly pipeline review",
priority: 5,
recur: "weekly",
due_at: 1740700800,
tags: ["#sales", "#recurring"]
})
→ {id: 1740300}
When you complete a recurring task, the system auto-creates the next instance:
task_done({id: 1740300})
→ {
completed: {id: 1740300, status: "completed", ...},
next: {id: 1740400, title: "Weekly pipeline review", due_at: 1741305600, ...}
}
Recurrence patterns: daily, weekly, biweekly, monthly.
9. Dashboard & Planning
Morning briefing:
task_plan({})
→ {
overdue: [...],
due_today: [...],
focus: {id: 1740101, title: "Schedule discovery call with David Chen"},
upcoming: [...]
}
Get the single most important thing to do right now:
task_next({})
→ {id: 1740101, title: "Schedule discovery call with David Chen", priority: 8}
Full dashboard with stats:
task_dashboard({})
→ {
stats: {open: 6, due_today: 1, overdue: 0, blocked: 1, completed_today: 1},
due_today: [...],
overdue: [],
blocked: [{id: 1740201, waiting_for: "Coastal Logistics to share current throughput data"}],
completed_today: [...]
}
10. Power Queries
60+ named queries available through task_query:
task_query({name: "open_tagged", tag: "#coastal"})
→ [all open tasks tagged #coastal]
task_query({name: "blocked_with_reason"})
→ [{id: 1740201, waiting_for: "Coastal Logistics to share current throughput data"}]
task_query({name: "parents_with_incomplete_subtasks"})
→ [{id: 1740100, title: "Prepare ROI analysis..."}]
task_query({name: "stale_tasks"})
→ [in-progress tasks not updated in 7+ days]
task_query({name: "daily_summary"})
→ {completed_today: [...], overdue: [...], due_today: [...], due_tomorrow: [...], blocked: [...]}
task_query({name: "completed_per_day_last_7"})
→ [["2026-02-25", 3], ["2026-02-24", 5], ...]
task_query({name: "avg_completion_time"})
→ {avg_seconds: 86400}
List all available queries:
task_list_queries({})
→ 12 categories, 60+ query functions
11. Unlinking
Relationships change. Remove a link without deleting the task:
task_unlink({id: 1740102, entity_type: "company", entity_id: 1740002})
→ {status: "unlinked"}
The task still exists, just no longer associated with that company.
The Integration Model
The key insight: tasks are the action layer of NIS. Contacts, companies, and other entities are nouns — they describe your world. Tasks are verbs — they describe what you’re doing about it.
Contact: David Chen
└── Task: Schedule discovery call (priority 8)
└── Task: Prepare ROI analysis (priority 7)
Company: Coastal Logistics
└── Task: Prepare ROI analysis (priority 7)
└── Subtask: Pull benchmarks
└── Subtask: Calculate savings
└── Subtask: Write summary
└── Task: Draft proposal (priority 5)
Entity links create a bidirectional graph. From a task, you see which entities it serves. From an entity, you see what work is pending. The 60+ query functions let you slice this graph by status, priority, due dates, tags, blocking state, and recurrence — giving both humans and AI agents the context they need to decide what to do next.