feat(mcp): Refactor MCP tools for direct function calls & add docs
This commit introduces a major refactoring of the MCP server implementation to prioritize direct function calls over CLI execution, enhancing performance and reliability. It also includes substantial updates to documentation for consistency and interlinking.
**MCP Server & Core Logic Refactoring:**
1. **Introduce Direct Function Wrappers ():**
* Created to house direct wrappers for core Task Master functions (imported from ).
* Implemented as the first wrapper, calling .
* Added utility within to centralize file location logic, removing duplication.
* Established the map for registering these wrappers.
2. **Enhance MCP Utilities ():**
* Added : A primary utility function to streamline MCP tool methods. It handles logging, argument processing (incl. project root normalization), calling the direct action function (e.g., ), processing results via , and formatting the final MCP response.
* Added : Standardizes processing of objects returned by direct function wrappers.
* Added : Filters sensitive/large fields (like , ) from responses sent to the MCP client.
* Added , , to support the new workflow.
* Refactored to use internally, simplifying its usage (though it's now primarily a fallback).
3. **Update MCP Tools (, ):**
* Refactored to use with , significantly simplifying the tool's method.
* Updated (initially) to use the improved (Note: further refactoring to use a direct wrapper for would follow the pattern).
**Documentation Enhancements:**
4. **Comprehensive Interlinking:** Added links across rule files (, , , , , ) to connect related guidelines, improving navigation.
5. **Standardize CLI Syntax ():** Removed legacy ℹ️ Initialized Perplexity client with OpenAI compatibility layer examples, reinforcing ℹ️ Initialized Perplexity client with OpenAI compatibility layer
_____ _ __ __ _
|_ _|_ _ ___| | __ | \/ | __ _ ___| |_ ___ _ __
| |/ _` / __| |/ / | |\/| |/ _` / __| __/ _ \ '__|
| | (_| \__ \ < | | | | (_| \__ \ || __/ |
|_|\__,_|___/_|\_\ |_| |_|\__,_|___/\__\___|_|
by https://x.com/eyaltoledano
╭────────────────────────────────────────────╮
│ │
│ Version: 0.9.30 Project: Task Master │
│ │
╰────────────────────────────────────────────╯
╭─────────────────────╮
│ │
│ Task Master CLI │
│ │
╰─────────────────────╯
╭───────────────────╮
│ Task Generation │
╰───────────────────╯
parse-prd --input=<file.txt> [--tasks=10] Generate tasks from a PRD document
generate Create individual task files from tasks…
╭───────────────────╮
│ Task Management │
╰───────────────────╯
list [--status=<status>] [--with-subtas… List all tasks with their status
set-status --id=<id> --status=<status> Update task status (done, pending, etc.)
update --from=<id> --prompt="<context>" Update tasks based on new requirements
add-task --prompt="<text>" [--dependencies=… Add a new task using AI
add-dependency --id=<id> --depends-on=<id> Add a dependency to a task
remove-dependency --id=<id> --depends-on=<id> Remove a dependency from a task
╭──────────────────────────╮
│ Task Analysis & Detail │
╰──────────────────────────╯
analyze-complexity [--research] [--threshold=5] Analyze tasks and generate expansion re…
complexity-report [--file=<path>] Display the complexity analysis report
expand --id=<id> [--num=5] [--research] [… Break down tasks into detailed subtasks
expand --all [--force] [--research] Expand all pending tasks with subtasks
clear-subtasks --id=<id> Remove subtasks from specified tasks
╭─────────────────────────────╮
│ Task Navigation & Viewing │
╰─────────────────────────────╯
next Show the next task to work on based on …
show <id> Display detailed information about a sp…
╭─────────────────────────╮
│ Dependency Management │
╰─────────────────────────╯
validate-dependenci… Identify invalid dependencies without f…
fix-dependencies Fix invalid dependencies automatically
╭─────────────────────────╮
│ Environment Variables │
╰─────────────────────────╯
ANTHROPIC_API_KEY Your Anthropic API key Required
MODEL Claude model to use Default: claude-3-7-sonn…
MAX_TOKENS Maximum tokens for responses Default: 4000
TEMPERATURE Temperature for model responses Default: 0.7
PERPLEXITY_API_KEY Perplexity API key for research Optional
PERPLEXITY_MODEL Perplexity model to use Default: sonar-pro
DEBUG Enable debug logging Default: false
LOG_LEVEL Console output level (debug,info,warn,error) Default: info
DEFAULT_SUBTASKS Default number of subtasks to generate Default: 3
DEFAULT_PRIORITY Default task priority Default: medium
PROJECT_NAME Project name displayed in UI Default: Task Master
_____ _ __ __ _
|_ _|_ _ ___| | __ | \/ | __ _ ___| |_ ___ _ __
| |/ _` / __| |/ / | |\/| |/ _` / __| __/ _ \ '__|
| | (_| \__ \ < | | | | (_| \__ \ || __/ |
|_|\__,_|___/_|\_\ |_| |_|\__,_|___/\__\___|_|
by https://x.com/eyaltoledano
╭────────────────────────────────────────────╮
│ │
│ Version: 0.9.30 Project: Task Master │
│ │
╰────────────────────────────────────────────╯
╭─────────────────────╮
│ │
│ Task Master CLI │
│ │
╰─────────────────────╯
╭───────────────────╮
│ Task Generation │
╰───────────────────╯
parse-prd --input=<file.txt> [--tasks=10] Generate tasks from a PRD document
generate Create individual task files from tasks…
╭───────────────────╮
│ Task Management │
╰───────────────────╯
list [--status=<status>] [--with-subtas… List all tasks with their status
set-status --id=<id> --status=<status> Update task status (done, pending, etc.)
update --from=<id> --prompt="<context>" Update tasks based on new requirements
add-task --prompt="<text>" [--dependencies=… Add a new task using AI
add-dependency --id=<id> --depends-on=<id> Add a dependency to a task
remove-dependency --id=<id> --depends-on=<id> Remove a dependency from a task
╭──────────────────────────╮
│ Task Analysis & Detail │
╰──────────────────────────╯
analyze-complexity [--research] [--threshold=5] Analyze tasks and generate expansion re…
complexity-report [--file=<path>] Display the complexity analysis report
expand --id=<id> [--num=5] [--research] [… Break down tasks into detailed subtasks
expand --all [--force] [--research] Expand all pending tasks with subtasks
clear-subtasks --id=<id> Remove subtasks from specified tasks
╭─────────────────────────────╮
│ Task Navigation & Viewing │
╰─────────────────────────────╯
next Show the next task to work on based on …
show <id> Display detailed information about a sp…
╭─────────────────────────╮
│ Dependency Management │
╰─────────────────────────╯
validate-dependenci… Identify invalid dependencies without f…
fix-dependencies Fix invalid dependencies automatically
╭─────────────────────────╮
│ Environment Variables │
╰─────────────────────────╯
ANTHROPIC_API_KEY Your Anthropic API key Required
MODEL Claude model to use Default: claude-3-7-sonn…
MAX_TOKENS Maximum tokens for responses Default: 4000
TEMPERATURE Temperature for model responses Default: 0.7
PERPLEXITY_API_KEY Perplexity API key for research Optional
PERPLEXITY_MODEL Perplexity model to use Default: sonar-pro
DEBUG Enable debug logging Default: false
LOG_LEVEL Console output level (debug,info,warn,error) Default: info
DEFAULT_SUBTASKS Default number of subtasks to generate Default: 3
DEFAULT_PRIORITY Default task priority Default: medium
PROJECT_NAME Project name displayed in UI Default: Task Master as the primary CLI.
6. **Add MCP Architecture & Workflow Sections:** Added detailed sections in and explaining MCP server structure and the workflow for adding new MCP tool integrations using the direct function pattern.
7. **Clarify MCP Role:** Updated and to better explain the MCP server's role and its specific utilities.
Overall, this establishes a cleaner, more performant, and maintainable pattern for integrating Task Master functionality with the MCP server, supported by improved documentation.
2025-03-30 00:29:12 -04:00
|
|
|
/**
|
|
|
|
* Integration test for direct function imports in MCP server
|
|
|
|
*/
|
|
|
|
|
|
|
|
import { jest } from '@jest/globals';
|
|
|
|
import path from 'path';
|
|
|
|
import fs from 'fs';
|
|
|
|
import { fileURLToPath } from 'url';
|
|
|
|
import { dirname } from 'path';
|
|
|
|
|
|
|
|
// Get the current module's directory
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
|
|
const __dirname = dirname(__filename);
|
|
|
|
|
|
|
|
// Import the direct functions
|
|
|
|
import { listTasksDirect } from '../../../mcp-server/src/core/task-master-core.js';
|
|
|
|
|
|
|
|
// Mock logger
|
|
|
|
const mockLogger = {
|
|
|
|
info: jest.fn(),
|
|
|
|
error: jest.fn(),
|
|
|
|
debug: jest.fn(),
|
|
|
|
warn: jest.fn()
|
|
|
|
};
|
|
|
|
|
|
|
|
// Test file paths
|
2025-03-30 02:25:24 -04:00
|
|
|
const testProjectRoot = path.join(__dirname, '../../fixture');
|
|
|
|
const testTasksPath = path.join(testProjectRoot, 'test-tasks.json');
|
feat(mcp): Refactor MCP tools for direct function calls & add docs
This commit introduces a major refactoring of the MCP server implementation to prioritize direct function calls over CLI execution, enhancing performance and reliability. It also includes substantial updates to documentation for consistency and interlinking.
**MCP Server & Core Logic Refactoring:**
1. **Introduce Direct Function Wrappers ():**
* Created to house direct wrappers for core Task Master functions (imported from ).
* Implemented as the first wrapper, calling .
* Added utility within to centralize file location logic, removing duplication.
* Established the map for registering these wrappers.
2. **Enhance MCP Utilities ():**
* Added : A primary utility function to streamline MCP tool methods. It handles logging, argument processing (incl. project root normalization), calling the direct action function (e.g., ), processing results via , and formatting the final MCP response.
* Added : Standardizes processing of objects returned by direct function wrappers.
* Added : Filters sensitive/large fields (like , ) from responses sent to the MCP client.
* Added , , to support the new workflow.
* Refactored to use internally, simplifying its usage (though it's now primarily a fallback).
3. **Update MCP Tools (, ):**
* Refactored to use with , significantly simplifying the tool's method.
* Updated (initially) to use the improved (Note: further refactoring to use a direct wrapper for would follow the pattern).
**Documentation Enhancements:**
4. **Comprehensive Interlinking:** Added links across rule files (, , , , , ) to connect related guidelines, improving navigation.
5. **Standardize CLI Syntax ():** Removed legacy ℹ️ Initialized Perplexity client with OpenAI compatibility layer examples, reinforcing ℹ️ Initialized Perplexity client with OpenAI compatibility layer
_____ _ __ __ _
|_ _|_ _ ___| | __ | \/ | __ _ ___| |_ ___ _ __
| |/ _` / __| |/ / | |\/| |/ _` / __| __/ _ \ '__|
| | (_| \__ \ < | | | | (_| \__ \ || __/ |
|_|\__,_|___/_|\_\ |_| |_|\__,_|___/\__\___|_|
by https://x.com/eyaltoledano
╭────────────────────────────────────────────╮
│ │
│ Version: 0.9.30 Project: Task Master │
│ │
╰────────────────────────────────────────────╯
╭─────────────────────╮
│ │
│ Task Master CLI │
│ │
╰─────────────────────╯
╭───────────────────╮
│ Task Generation │
╰───────────────────╯
parse-prd --input=<file.txt> [--tasks=10] Generate tasks from a PRD document
generate Create individual task files from tasks…
╭───────────────────╮
│ Task Management │
╰───────────────────╯
list [--status=<status>] [--with-subtas… List all tasks with their status
set-status --id=<id> --status=<status> Update task status (done, pending, etc.)
update --from=<id> --prompt="<context>" Update tasks based on new requirements
add-task --prompt="<text>" [--dependencies=… Add a new task using AI
add-dependency --id=<id> --depends-on=<id> Add a dependency to a task
remove-dependency --id=<id> --depends-on=<id> Remove a dependency from a task
╭──────────────────────────╮
│ Task Analysis & Detail │
╰──────────────────────────╯
analyze-complexity [--research] [--threshold=5] Analyze tasks and generate expansion re…
complexity-report [--file=<path>] Display the complexity analysis report
expand --id=<id> [--num=5] [--research] [… Break down tasks into detailed subtasks
expand --all [--force] [--research] Expand all pending tasks with subtasks
clear-subtasks --id=<id> Remove subtasks from specified tasks
╭─────────────────────────────╮
│ Task Navigation & Viewing │
╰─────────────────────────────╯
next Show the next task to work on based on …
show <id> Display detailed information about a sp…
╭─────────────────────────╮
│ Dependency Management │
╰─────────────────────────╯
validate-dependenci… Identify invalid dependencies without f…
fix-dependencies Fix invalid dependencies automatically
╭─────────────────────────╮
│ Environment Variables │
╰─────────────────────────╯
ANTHROPIC_API_KEY Your Anthropic API key Required
MODEL Claude model to use Default: claude-3-7-sonn…
MAX_TOKENS Maximum tokens for responses Default: 4000
TEMPERATURE Temperature for model responses Default: 0.7
PERPLEXITY_API_KEY Perplexity API key for research Optional
PERPLEXITY_MODEL Perplexity model to use Default: sonar-pro
DEBUG Enable debug logging Default: false
LOG_LEVEL Console output level (debug,info,warn,error) Default: info
DEFAULT_SUBTASKS Default number of subtasks to generate Default: 3
DEFAULT_PRIORITY Default task priority Default: medium
PROJECT_NAME Project name displayed in UI Default: Task Master
_____ _ __ __ _
|_ _|_ _ ___| | __ | \/ | __ _ ___| |_ ___ _ __
| |/ _` / __| |/ / | |\/| |/ _` / __| __/ _ \ '__|
| | (_| \__ \ < | | | | (_| \__ \ || __/ |
|_|\__,_|___/_|\_\ |_| |_|\__,_|___/\__\___|_|
by https://x.com/eyaltoledano
╭────────────────────────────────────────────╮
│ │
│ Version: 0.9.30 Project: Task Master │
│ │
╰────────────────────────────────────────────╯
╭─────────────────────╮
│ │
│ Task Master CLI │
│ │
╰─────────────────────╯
╭───────────────────╮
│ Task Generation │
╰───────────────────╯
parse-prd --input=<file.txt> [--tasks=10] Generate tasks from a PRD document
generate Create individual task files from tasks…
╭───────────────────╮
│ Task Management │
╰───────────────────╯
list [--status=<status>] [--with-subtas… List all tasks with their status
set-status --id=<id> --status=<status> Update task status (done, pending, etc.)
update --from=<id> --prompt="<context>" Update tasks based on new requirements
add-task --prompt="<text>" [--dependencies=… Add a new task using AI
add-dependency --id=<id> --depends-on=<id> Add a dependency to a task
remove-dependency --id=<id> --depends-on=<id> Remove a dependency from a task
╭──────────────────────────╮
│ Task Analysis & Detail │
╰──────────────────────────╯
analyze-complexity [--research] [--threshold=5] Analyze tasks and generate expansion re…
complexity-report [--file=<path>] Display the complexity analysis report
expand --id=<id> [--num=5] [--research] [… Break down tasks into detailed subtasks
expand --all [--force] [--research] Expand all pending tasks with subtasks
clear-subtasks --id=<id> Remove subtasks from specified tasks
╭─────────────────────────────╮
│ Task Navigation & Viewing │
╰─────────────────────────────╯
next Show the next task to work on based on …
show <id> Display detailed information about a sp…
╭─────────────────────────╮
│ Dependency Management │
╰─────────────────────────╯
validate-dependenci… Identify invalid dependencies without f…
fix-dependencies Fix invalid dependencies automatically
╭─────────────────────────╮
│ Environment Variables │
╰─────────────────────────╯
ANTHROPIC_API_KEY Your Anthropic API key Required
MODEL Claude model to use Default: claude-3-7-sonn…
MAX_TOKENS Maximum tokens for responses Default: 4000
TEMPERATURE Temperature for model responses Default: 0.7
PERPLEXITY_API_KEY Perplexity API key for research Optional
PERPLEXITY_MODEL Perplexity model to use Default: sonar-pro
DEBUG Enable debug logging Default: false
LOG_LEVEL Console output level (debug,info,warn,error) Default: info
DEFAULT_SUBTASKS Default number of subtasks to generate Default: 3
DEFAULT_PRIORITY Default task priority Default: medium
PROJECT_NAME Project name displayed in UI Default: Task Master as the primary CLI.
6. **Add MCP Architecture & Workflow Sections:** Added detailed sections in and explaining MCP server structure and the workflow for adding new MCP tool integrations using the direct function pattern.
7. **Clarify MCP Role:** Updated and to better explain the MCP server's role and its specific utilities.
Overall, this establishes a cleaner, more performant, and maintainable pattern for integrating Task Master functionality with the MCP server, supported by improved documentation.
2025-03-30 00:29:12 -04:00
|
|
|
|
|
|
|
describe('MCP Server Direct Functions', () => {
|
|
|
|
// Create test data before tests
|
|
|
|
beforeAll(() => {
|
|
|
|
// Create test directory if it doesn't exist
|
|
|
|
if (!fs.existsSync(testProjectRoot)) {
|
|
|
|
fs.mkdirSync(testProjectRoot, { recursive: true });
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a sample tasks.json file for testing
|
|
|
|
const sampleTasks = {
|
|
|
|
meta: {
|
|
|
|
projectName: 'Test Project',
|
|
|
|
version: '1.0.0'
|
|
|
|
},
|
|
|
|
tasks: [
|
|
|
|
{
|
|
|
|
id: 1,
|
|
|
|
title: 'Task 1',
|
|
|
|
description: 'First task',
|
|
|
|
status: 'done',
|
|
|
|
dependencies: [],
|
|
|
|
priority: 'high'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 2,
|
|
|
|
title: 'Task 2',
|
|
|
|
description: 'Second task',
|
|
|
|
status: 'in-progress',
|
|
|
|
dependencies: [1],
|
|
|
|
priority: 'medium',
|
|
|
|
subtasks: [
|
|
|
|
{
|
|
|
|
id: 1,
|
|
|
|
title: 'Subtask 2.1',
|
|
|
|
description: 'First subtask',
|
|
|
|
status: 'done'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 2,
|
|
|
|
title: 'Subtask 2.2',
|
|
|
|
description: 'Second subtask',
|
|
|
|
status: 'pending'
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 3,
|
|
|
|
title: 'Task 3',
|
|
|
|
description: 'Third task',
|
|
|
|
status: 'pending',
|
|
|
|
dependencies: [1, 2],
|
|
|
|
priority: 'low'
|
|
|
|
}
|
|
|
|
]
|
|
|
|
};
|
|
|
|
|
|
|
|
fs.writeFileSync(testTasksPath, JSON.stringify(sampleTasks, null, 2));
|
|
|
|
});
|
|
|
|
|
|
|
|
// Clean up after tests
|
|
|
|
afterAll(() => {
|
|
|
|
// Remove test tasks file
|
|
|
|
if (fs.existsSync(testTasksPath)) {
|
|
|
|
fs.unlinkSync(testTasksPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to remove the directory (will only work if empty)
|
|
|
|
try {
|
|
|
|
fs.rmdirSync(testProjectRoot);
|
|
|
|
} catch (error) {
|
|
|
|
// Ignore errors if the directory isn't empty
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Reset mocks before each test
|
|
|
|
beforeEach(() => {
|
|
|
|
jest.clearAllMocks();
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('listTasksDirect', () => {
|
|
|
|
test('should return all tasks when no filter is provided', async () => {
|
|
|
|
// Arrange
|
|
|
|
const args = {
|
|
|
|
projectRoot: testProjectRoot,
|
|
|
|
file: testTasksPath
|
|
|
|
};
|
|
|
|
|
|
|
|
// Act
|
|
|
|
const result = await listTasksDirect(args, mockLogger);
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
expect(result.success).toBe(true);
|
|
|
|
expect(result.data.tasks.length).toBe(3);
|
|
|
|
expect(result.data.stats.total).toBe(3);
|
|
|
|
expect(result.data.stats.completed).toBe(1);
|
|
|
|
expect(result.data.stats.inProgress).toBe(1);
|
|
|
|
expect(result.data.stats.pending).toBe(1);
|
|
|
|
expect(mockLogger.info).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should filter tasks by status', async () => {
|
|
|
|
// Arrange
|
|
|
|
const args = {
|
|
|
|
projectRoot: testProjectRoot,
|
|
|
|
file: testTasksPath,
|
|
|
|
status: 'pending'
|
|
|
|
};
|
|
|
|
|
|
|
|
// Act
|
|
|
|
const result = await listTasksDirect(args, mockLogger);
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
expect(result.success).toBe(true);
|
|
|
|
expect(result.data.tasks.length).toBe(1);
|
|
|
|
expect(result.data.tasks[0].id).toBe(3);
|
|
|
|
expect(result.data.filter).toBe('pending');
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should include subtasks when requested', async () => {
|
|
|
|
// Arrange
|
|
|
|
const args = {
|
|
|
|
projectRoot: testProjectRoot,
|
|
|
|
file: testTasksPath,
|
|
|
|
withSubtasks: true
|
|
|
|
};
|
|
|
|
|
|
|
|
// Act
|
|
|
|
const result = await listTasksDirect(args, mockLogger);
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
expect(result.success).toBe(true);
|
|
|
|
|
|
|
|
// Verify subtasks are included
|
|
|
|
const taskWithSubtasks = result.data.tasks.find(t => t.id === 2);
|
|
|
|
expect(taskWithSubtasks.subtasks).toBeDefined();
|
|
|
|
expect(taskWithSubtasks.subtasks.length).toBe(2);
|
|
|
|
|
|
|
|
// Verify subtask details
|
|
|
|
expect(taskWithSubtasks.subtasks[0].id).toBe(1);
|
|
|
|
expect(taskWithSubtasks.subtasks[0].title).toBe('Subtask 2.1');
|
|
|
|
expect(taskWithSubtasks.subtasks[0].status).toBe('done');
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should handle errors gracefully', async () => {
|
|
|
|
// Arrange
|
|
|
|
const args = {
|
|
|
|
projectRoot: testProjectRoot,
|
|
|
|
file: 'non-existent-file.json'
|
|
|
|
};
|
|
|
|
|
|
|
|
// Act
|
|
|
|
const result = await listTasksDirect(args, mockLogger);
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
expect(result.success).toBe(false);
|
|
|
|
expect(result.error).toBeDefined();
|
|
|
|
expect(result.error.code).toBeDefined();
|
|
|
|
expect(result.error.message).toBeDefined();
|
|
|
|
expect(mockLogger.error).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|