Advanced search, analytics, and multi-item operations for efficient project management.
Advanced search with multiple filter criteria and name resolution.
Parameters:
projectId(number, optional): Project IDtitleContains(string, optional): Filter by title substring (case-insensitive)descriptionContains(string, optional): Filter by description substringcategories(array, optional): Category names or IDs (['programming', 'bug'])importanceLevels(array, optional): Priority names or IDs (['urgent', 'high'])tags(array, optional): Tag names or IDshasAssignedUsers(boolean, optional): Filter by assignment statusisCompleted(boolean, optional): Filter by completion statusminEstimate(number, optional): Minimum estimated costmaxEstimate(number, optional): Maximum estimated costboardId(number, optional): Filter by board/sprintstageId(number, optional): Filter by workflow stagemilestoneId(number, optional): Filter by milestoneassignedUserId(number, optional): Filter by assigned user
Returns: { items: WorkItem[], total: number }
High-priority backend tasks:
const tasks = await callTool('search_work_items', {
projectId: 230954,
categories: ['programming'], // Name resolution
tags: ['backend'],
importanceLevels: ['high', 'urgent'],
minEstimate: 5,
isCompleted: false
});
console.log(`Found ${tasks.total} high-priority backend tasks`);Tasks nearing deadline:
const nearDeadline = await callTool('search_work_items', {
projectId: 230954,
boardId: 650299, // Current sprint
isCompleted: false,
stageId: 2 // "In Progress"
});Unassigned bugs:
const unassignedBugs = await callTool('search_work_items', {
categories: ['bug'],
hasAssignedUsers: false,
isCompleted: false
});Complex query:
// Find incomplete programming tasks:
// - Tagged as "backend" OR "api"
// - High or urgent priority
// - Estimated between 3-8 hours
// - NOT in closed sprints
const complexQuery = await callTool('search_work_items', {
projectId: 230954,
categories: ['programming'],
tags: ['backend', 'api'],
importanceLevels: ['high', 'urgent'],
minEstimate: 3,
maxEstimate: 8,
isCompleted: false,
boardId: 650299 // Active sprint only
});Get current user's assigned tasks with aggregated statistics.
Parameters:
projectId(number, optional): Project IDboardId(number, optional): Filter by specific sprintincludeCompleted(boolean, optional): Include completed tasks (default: false)limit(number, optional): Manual pagination limitoffset(number, optional): Manual pagination offset
Returns:
{
items: WorkItem[];
total: number;
statistics: {
byStage: { [stageName: string]: number };
byPriority: { [priorityName: string]: number };
totalEstimate: number;
};
}Daily standup view:
const result = await callTool('get_my_current_tasks', {
projectId: 230954,
includeCompleted: false
});
console.log(`You have ${result.total} active tasks:`);
console.log(` In Progress: ${result.statistics.byStage['In Progress'] || 0}`);
console.log(` In Review: ${result.statistics.byStage['Review'] || 0}`);
console.log(` Total estimate: ${result.statistics.totalEstimate} hours`);
// Show top 3 tasks
result.items.slice(0, 3).forEach(task => {
console.log(` #${task.workItemId}: ${task.title} (${task.estimatedCost}h)`);
});Sprint-specific tasks:
const sprintTasks = await callTool('get_my_current_tasks', {
projectId: 230954,
boardId: 650299, // Current sprint
includeCompleted: false
});Weekly summary:
const weeklyWork = await callTool('get_my_current_tasks', {
includeCompleted: true // Include finished work
});
const completed = weeklyWork.items.filter(t => t.isCompleted);
const completedHours = completed.reduce((sum, t) => sum + (t.estimatedCost || 0), 0);
console.log(`Completed ${completed.length} tasks (${completedHours} hours)`);Get all incomplete work items for a project or board.
Parameters:
projectId(number, optional): Project IDboardId(number, optional): Filter by board/sprint
Returns: { items, total }
Example:
const incomplete = await callTool('get_incomplete_tasks', {
projectId: 230954,
boardId: 650299
});
console.log(`Sprint has ${incomplete.total} incomplete tasks`);Get TRUE backlog items - work items with NO board/sprint assignment.
Parameters:
projectId(number, optional): Project ID
Returns: { items, total, note }
Example:
const backlog = await callTool('get_backlog', {
projectId: 230954
});
console.log(`True backlog: ${backlog.total} items`);
console.log(`Note: ${backlog.note}`);
// Review unassigned items
backlog.items.forEach(item => {
console.log(`#${item.workItemId}: ${item.title}`);
console.log(` Category: ${item.categoryName}`);
console.log(` Estimate: ${item.estimatedCost}h`);
});Safety Note: Use this tool for backlog cleanup. Never delete items from closed sprints or completed work. See Deletion Safety Guide.
Get overview of currently active (open) sprints with task counts.
Parameters:
projectId(number, optional): Project ID
Returns:
{
boards: Array<{
boardId: number;
name: string;
startDate: string;
endDate: string;
totalTasks: number;
completedTasks: number;
progress: number; // Percentage
}>;
totalActiveSprints: number;
}Example:
const overview = await callTool('get_active_sprint_overview', {
projectId: 230954
});
console.log(`${overview.totalActiveSprints} active sprints:\n`);
overview.boards.forEach(board => {
const daysLeft = Math.ceil(
(new Date(board.endDate) - new Date()) / (1000 * 60 * 60 * 24)
);
console.log(`${board.name}:`);
console.log(` Progress: ${board.progress}%`);
console.log(` Tasks: ${board.completedTasks}/${board.totalTasks}`);
console.log(` Days left: ${daysLeft}`);
console.log('');
});Get comprehensive sprint progress metrics including burndown chart and hour tracking.
Parameters:
projectId(number, optional): Project IDboardId(number, required): Board/sprint ID
Returns: Rich progress data with:
- Burndown chart data: Daily progress snapshots
- Dependency graph: Task relationships and blockers
- Hour tracking: Logged vs estimated hours
- Completion trends: Velocity and projections
Example:
const progress = await callTool('get_sprint_progress', {
projectId: 230954,
boardId: 650299
});
console.log('Sprint Progress Report:');
console.log(` Total tasks: ${progress.totalWorkItems}`);
console.log(` Completed: ${progress.completedWorkItems}`);
console.log(` Completion: ${progress.completionPercentage}%`);
console.log(` Hours logged: ${progress.loggedHours}/${progress.estimatedHours}`);
// Burndown data
if (progress.burndownData) {
console.log('\nBurndown Chart:');
progress.burndownData.forEach(day => {
console.log(` ${day.date}: ${day.remainingTasks} tasks remaining`);
});
}
// Velocity calculation
const daysElapsed = progress.burndownData.length;
const velocity = progress.completedWorkItems / daysElapsed;
console.log(`\nVelocity: ${velocity.toFixed(1)} tasks/day`);Get compressed sprint status with task counts by stage (optimized for token usage).
Parameters:
projectId(number, optional): Project IDboardId(number, required): Board/sprint ID
Returns: Compressed summary with minimal tokens:
{
boardId: number;
boardName: string;
totalTasks: number;
completedTasks: number;
byStage: { [stageName: string]: number };
}Example:
const summary = await callTool('get_sprint_summary', {
boardId: 650299
});
console.log(`${summary.boardName} (${summary.completedTasks}/${summary.totalTasks})`);
Object.entries(summary.byStage).forEach(([stage, count]) => {
console.log(` ${stage}: ${count}`);
});Use case: Quick sprint status checks without full analytics overhead.
Analyze dependency graphs to identify blocking work items. Supports premium API + free-tier fallback.
Parameters:
projectId(number, optional): Project IDworkItemId(number|string, optional): Analyze specific work item (ID or title)includeIndirect(boolean, optional): Include transitive dependencies (blockers of blockers). Default: falseuseFallbackParser(boolean, optional): Use description parser if premium API unavailable (default: true)
Returns: Blocked items with dependency analysis
Premium Plan:
- Uses HacknPlan's native dependency API
- Full graph analysis with transitive dependencies
Free Tier (Fallback):
- Parses work item descriptions for dependency markers:
Blocked by #123Depends on #456Waiting for #789
- Regex-based extraction
Find all blockers in project:
const blockers = await callTool('get_blockers', {
projectId: 230954
});
console.log(`Found ${blockers.total} blocked items:`);
blockers.items.forEach(item => {
console.log(`#${item.workItemId}: ${item.title}`);
console.log(` Blocked by: ${item.blockedBy.join(', ')}`);
});Critical path for specific task:
const criticalPath = await callTool('get_blockers', {
workItemId: 'Deploy to production',
includeIndirect: true // Include transitive blockers
});
console.log('Critical path:');
criticalPath.chain.forEach((step, i) => {
console.log(` ${i + 1}. #${step.workItemId}: ${step.title}`);
});Identify bottlenecks:
const allBlockers = await callTool('get_blockers', {
projectId: 230954,
includeIndirect: false
});
// Find items blocking the most tasks
const blockingCounts = {};
allBlockers.items.forEach(item => {
item.blockedBy.forEach(blockerId => {
blockingCounts[blockerId] = (blockingCounts[blockerId] || 0) + 1;
});
});
const bottlenecks = Object.entries(blockingCounts)
.sort((a, b) => b[1] - a[1])
.slice(0, 5);
console.log('Top bottlenecks (blocking most tasks):');
bottlenecks.forEach(([id, count]) => {
console.log(` Task #${id}: blocking ${count} other tasks`);
});// 1. Get current sprint status
const current = await callTool('get_sprint_summary', {
boardId: 650299
});
// 2. Check backlog for next sprint
const backlog = await callTool('get_backlog', {
projectId: 230954
});
// 3. Identify blockers before planning
const blockers = await callTool('get_blockers', {
projectId: 230954
});
console.log(`Current sprint: ${current.completedTasks}/${current.totalTasks}`);
console.log(`Backlog: ${backlog.total} unassigned items`);
console.log(`Blockers: ${blockers.total} blocked items`);// Get my tasks
const myTasks = await callTool('get_my_current_tasks', {
includeCompleted: false
});
console.log(`📊 Daily Standup - ${new Date().toLocaleDateString()}\n`);
// Yesterday (completed)
const yesterday = myTasks.items.filter(t =>
t.isCompleted &&
new Date(t.updatedAt).toDateString() === new Date(Date.now() - 86400000).toDateString()
);
console.log(`✅ Completed yesterday (${yesterday.length}):`);
yesterday.forEach(t => console.log(` - ${t.title}`));
// Today (in progress)
const today = myTasks.items.filter(t =>
t.stageName === 'In Progress' && !t.isCompleted
);
console.log(`\n🔄 Working on today (${today.length}):`);
today.forEach(t => console.log(` - ${t.title}`));
// Blockers
const myBlockers = await callTool('get_blockers', {
projectId: 230954
});
const myBlockedTasks = myBlockers.items.filter(item =>
myTasks.items.some(t => t.workItemId === item.workItemId)
);
if (myBlockedTasks.length > 0) {
console.log(`\n🚫 Blockers (${myBlockedTasks.length}):`);
myBlockedTasks.forEach(t => {
console.log(` - ${t.title} (blocked by: ${t.blockedBy.join(', ')})`);
});
}// Get sprint data
const progress = await callTool('get_sprint_progress', {
boardId: 650299
});
console.log('📈 Sprint Retrospective\n');
console.log(`Total tasks: ${progress.totalWorkItems}`);
console.log(`Completed: ${progress.completedWorkItems} (${progress.completionPercentage}%)`);
console.log(`Velocity: ${(progress.completedWorkItems / progress.sprintDays).toFixed(1)} tasks/day`);
console.log(`Hours: ${progress.loggedHours}/${progress.estimatedHours} (${((progress.loggedHours / progress.estimatedHours) * 100).toFixed(0)}%)`);
// Identify patterns
const incomplete = progress.totalWorkItems - progress.completedWorkItems;
if (incomplete > progress.totalWorkItems * 0.3) {
console.log(`\n⚠️ Warning: ${incomplete} incomplete tasks (>${30}% of sprint)`);
}
if (progress.loggedHours > progress.estimatedHours * 1.2) {
console.log('\n⚠️ Sprint over-estimated by 20%+');
}See Also:
- Work Items - Core work item operations
- Boards & Sprints - Sprint management
- Deletion Safety - Safe backlog cleanup
- Best Practices - Query optimization tips