From 21fcf92e0f4e362ff5ef39eb9bee0147c69a6532 Mon Sep 17 00:00:00 2001 From: Joe Danziger Date: Fri, 9 May 2025 11:31:46 -0400 Subject: [PATCH] register tool with mcp server --- mcp-server/src/core/direct-functions/rules.js | 55 +++++++++++++++++++ mcp-server/src/tools/index.js | 2 + mcp-server/src/tools/rules.js | 39 +++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 mcp-server/src/core/direct-functions/rules.js create mode 100644 mcp-server/src/tools/rules.js diff --git a/mcp-server/src/core/direct-functions/rules.js b/mcp-server/src/core/direct-functions/rules.js new file mode 100644 index 00000000..f2cbb9de --- /dev/null +++ b/mcp-server/src/core/direct-functions/rules.js @@ -0,0 +1,55 @@ +/** + * rules.js + * Direct function implementation for adding or removing brand rules + */ + +import { execSync } from 'child_process'; +import { + enableSilentMode, + disableSilentMode +} from '../../../../scripts/modules/utils.js'; + +/** + * Direct function wrapper for adding or removing brand rules. + * @param {Object} args - Command arguments + * @param {"add"|"remove"} args.action - Action to perform: add or remove rules + * @param {string[]} args.rules - List of brand rules to add or remove + * @param {string} args.projectRoot - Absolute path to the project root + * @param {boolean} [args.yes=true] - Run non-interactively + * @param {Object} log - Logger object + * @param {Object} context - Additional context (session) + * @returns {Promise} - Result object { success: boolean, data?: any, error?: { code: string, message: string } } + */ +export async function rulesDirect(args, log, context = {}) { + enableSilentMode(); + try { + const { action, rules, projectRoot, yes } = args; + if (!action || !Array.isArray(rules) || rules.length === 0 || !projectRoot) { + return { + success: false, + error: { + code: 'MISSING_ARGUMENT', + message: 'action, rules, and projectRoot are required.' + } + }; + } + const rulesList = rules.join(','); + const yesFlag = yes !== false ? '--yes' : ''; + const cmd = `npx task-master rules ${action} ${rulesList} ${yesFlag}`.trim(); + log.info(`[rulesDirect] Running: ${cmd} in ${projectRoot}`); + const output = execSync(cmd, { cwd: projectRoot, encoding: 'utf8' }); + log.info(`[rulesDirect] Output: ${output}`); + disableSilentMode(); + return { success: true, data: { output } }; + } catch (error) { + disableSilentMode(); + log.error(`[rulesDirect] Error: ${error.message}`); + return { + success: false, + error: { + code: error.code || 'RULES_ERROR', + message: error.message + } + }; + } +} diff --git a/mcp-server/src/tools/index.js b/mcp-server/src/tools/index.js index 863f28cf..e0aaa46d 100644 --- a/mcp-server/src/tools/index.js +++ b/mcp-server/src/tools/index.js @@ -28,6 +28,7 @@ import { registerAddDependencyTool } from './add-dependency.js'; import { registerRemoveTaskTool } from './remove-task.js'; import { registerInitializeProjectTool } from './initialize-project.js'; import { registerModelsTool } from './models.js'; +import { registerRulesTool } from './rules.js'; /** * Register all Task Master tools with the MCP server @@ -40,6 +41,7 @@ export function registerTaskMasterTools(server) { // Group 1: Initialization & Setup registerInitializeProjectTool(server); registerModelsTool(server); + registerRulesTool(server); registerParsePRDTool(server); // Group 2: Task Listing & Viewing diff --git a/mcp-server/src/tools/rules.js b/mcp-server/src/tools/rules.js new file mode 100644 index 00000000..bccbcf29 --- /dev/null +++ b/mcp-server/src/tools/rules.js @@ -0,0 +1,39 @@ +/** + * tools/rules.js + * Tool to add or remove brand rules from a project (MCP server) + */ + +import { z } from 'zod'; +import { + createErrorResponse, + handleApiResult, + withNormalizedProjectRoot +} from './utils.js'; +import { rulesDirect } from '../core/direct-functions/rules.js'; + +/** + * Register the rules tool with the MCP server + * @param {Object} server - FastMCP server instance + */ +export function registerRulesTool(server) { + server.addTool({ + name: 'rules', + description: 'Add or remove brand rules and MCP config from the project (mirrors CLI rules add/remove).', + parameters: z.object({ + action: z.enum(['add', 'remove']).describe('Whether to add or remove brand rules.'), + rules: z.array(z.string()).min(1).describe('List of brand rules to add or remove (e.g., ["roo", "windsurf"]).'), + projectRoot: z.string().describe('The root directory of the project. Must be an absolute path.'), + yes: z.boolean().optional().default(true).describe('Run non-interactively (default: true).') + }), + execute: withNormalizedProjectRoot(async (args, { log, session }) => { + try { + log.info(`[rules tool] Executing action: ${args.action} for rules: ${args.rules.join(', ')} in ${args.projectRoot}`); + const result = await rulesDirect(args, log, { session }); + return handleApiResult(result, log); + } catch (error) { + log.error(`[rules tool] Error: ${error.message}`); + return createErrorResponse(error.message, { details: error.stack }); + } + }) + }); +}