Skip to main content
Glama

convert_task_markdown

Convert markdown task files to Claude Code MCP-compatible JSON format for execution by AI agents in the MeshSeeks distributed network.

Instructions

Converts markdown task files into Claude Code MCP-compatible JSON format. Returns an array of tasks that can be executed using the claude_code tool.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
markdownPathYesPath to the markdown task file to convert.
outputPathNoOptional path where to save the JSON output. If not provided, returns the JSON directly.

Implementation Reference

  • MCP tool handler for 'convert_task_markdown'. Extracts parameters, executes task_converter.py Python script via spawnAsync, processes output/errors, returns JSON tasks or error.
    if (toolName === 'convert_task_markdown') { const toolArguments = args.params.arguments; // Extract markdownPath (required) let markdownPath: string; if ( toolArguments && typeof toolArguments === 'object' && 'markdownPath' in toolArguments && typeof toolArguments.markdownPath === 'string' ) { markdownPath = toolArguments.markdownPath; } else { throw new McpError(ErrorCode.InvalidParams, 'Missing or invalid required parameter: markdownPath for convert_task_markdown tool'); } // Extract outputPath (optional) let outputPath: string | undefined; if (toolArguments.outputPath && typeof toolArguments.outputPath === 'string') { outputPath = toolArguments.outputPath; } debugLog(`[Debug] Converting markdown task file: ${markdownPath}`); let stderr = ''; try { // Prepare command to run task_converter.py const pythonPath = 'python3'; const converterPath = pathResolve(__dirname, '../docs/task_converter.py'); // Use --json-output flag to get JSON to stdout const args = ['--json-output', markdownPath]; const result = await spawnAsync(pythonPath, [converterPath, ...args], { cwd: homedir(), timeout: 30000 // 30 seconds timeout }); const stdout = result.stdout; stderr = result.stderr; // Extract progress messages and actual errors const stderrLines = stderr.split('\n'); const progressMessages = stderrLines.filter(line => line.includes('[Progress]')); const errorMessages = stderrLines.filter(line => !line.includes('[Progress]') && line.trim()); // Log progress messages progressMessages.forEach(msg => { console.error(msg); // Send to client debugLog(msg); }); if (errorMessages.length > 0) { stderr = errorMessages.join('\n'); debugLog(`[Debug] Task converter stderr: ${stderr}`); } // Check if there was an error from the converter if (stderr && stderr.includes('Markdown format validation failed')) { // Return validation error as a structured response const validationError = { status: 'error', error: 'Markdown format validation failed', details: stderr, helpUrl: 'https://github.com/grahama1970/claude-code-mcp/blob/main/README.md#markdown-task-file-format' }; this.activeRequests.delete(requestId); return { content: [{ type: 'text', text: JSON.stringify(validationError, null, 2) }] }; } // Parse the JSON output const tasks = JSON.parse(stdout); // If outputPath is provided, also save to file if (outputPath) { await fs.writeFile(outputPath, JSON.stringify(tasks, null, 2)); debugLog(`[Debug] Saved converted tasks to: ${outputPath}`); } // Return the converted tasks const response = { status: 'success', tasksCount: tasks.length, outputPath: outputPath || 'none', tasks: tasks }; this.activeRequests.delete(requestId); return { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] }; } catch (error) { this.activeRequests.delete(requestId); const errorMessage = error instanceof Error ? error.message : String(error); // Check if this is a JSON parsing error (indicating validation failure) if (errorMessage.includes('JSON') && stderr) { const validationError = { status: 'error', error: 'Task conversion failed', details: stderr || errorMessage, helpUrl: 'https://github.com/grahama1970/claude-code-mcp/blob/main/README.md#markdown-task-file-format' }; return { content: [{ type: 'text', text: JSON.stringify(validationError, null, 2) }] }; } throw new McpError(ErrorCode.InternalError, `Failed to convert markdown tasks: ${errorMessage}`); } }
  • src/server.ts:299-316 (registration)
    Registers the 'convert_task_markdown' tool in the ListTools response, including description and input schema.
    { name: 'convert_task_markdown', description: 'Converts markdown task files into Claude Code MCP-compatible JSON format. Returns an array of tasks that can be executed using the claude_code tool.', inputSchema: { type: 'object', properties: { markdownPath: { type: 'string', description: 'Path to the markdown task file to convert.', }, outputPath: { type: 'string', description: 'Optional path where to save the JSON output. If not provided, returns the JSON directly.', }, }, required: ['markdownPath'], }, },
  • Input schema definition for the convert_task_markdown tool, specifying markdownPath as required and outputPath as optional.
    inputSchema: { type: 'object', properties: { markdownPath: { type: 'string', description: 'Path to the markdown task file to convert.', }, outputPath: { type: 'string', description: 'Optional path where to save the JSON output. If not provided, returns the JSON directly.', }, }, required: ['markdownPath'], },
  • Core helper function that parses markdown task file, validates structure, extracts sections (title, objective, requirements, validation tasks), builds prompts using build_validation_prompt, and formats into MCP-compatible task list.
    def process_markdown(input_file: str, progress_callback: Optional[callable] = None) -> List[Dict[str, Any]]: """ Process a markdown file and extract validation tasks. Args: input_file: Path to the markdown file progress_callback: Optional callback for progress updates Returns: List of tasks in Claude Code MCP format Raises: ValueError: If markdown format is invalid or missing required sections """ if progress_callback: progress_callback("Loading task file...") md = load_file(input_file) if progress_callback: progress_callback("Validating markdown structure...") # Validate markdown structure validation_errors = [] # Extract and validate title title = extract_title(md) if title == "Untitled Task": validation_errors.append("Missing required title. Format: '# Task NNN: Title'") # Extract and validate objective objective = extract_objective(md) if not objective: validation_errors.append("Missing required 'Objective' section. Format: '## Objective\\nDescription'") # Extract and validate requirements requirements = extract_requirements(md) if not requirements: validation_errors.append("Missing or empty 'Requirements' section. Format: '## Requirements\\n1. [ ] Requirement'") # Extract and validate tasks validation_tasks = extract_validation_tasks(md) if not validation_tasks: validation_errors.append("No validation tasks found. Format: '- [ ] Validate `module.py`' with indented steps") # Check for task steps empty_tasks = [] for module, block in validation_tasks: steps = extract_steps(block) if not steps: empty_tasks.append(module) if empty_tasks: validation_errors.append(f"Tasks without steps: {', '.join(empty_tasks)}. Each task needs indented steps") # If there are validation errors, raise exception with helpful message if validation_errors: error_msg = "Markdown format validation failed:\n" error_msg += "\n".join(f" - {error}" for error in validation_errors) error_msg += "\n\nRequired markdown format:\n" error_msg += "# Task NNN: Title\n" error_msg += "## Objective\n" error_msg += "Clear description\n" error_msg += "## Requirements\n" error_msg += "1. [ ] First requirement\n" error_msg += "## Task Section\n" error_msg += "- [ ] Validate `file.py`\n" error_msg += " - [ ] Step 1\n" error_msg += " - [ ] Step 2\n" raise ValueError(error_msg) if progress_callback: progress_callback(f"Converting {len(validation_tasks)} validation tasks...") prompts = [] for i, (module, block) in enumerate(validation_tasks, 1): if progress_callback: progress_callback(f"Task {i}/{len(validation_tasks)}: Converting {module}") steps = extract_steps(block) if not steps: continue # skip if no steps found (already reported in validation) prompt = build_validation_prompt(title, objective, module, steps, requirements) prompts.append(prompt) if progress_callback: progress_callback("Conversion complete!") return format_tasks_for_mcp(prompts)
  • Entry point for the task_converter.py script. Handles --json-output mode for MCP integration by calling process_markdown and printing JSON to stdout, with progress to stderr.
    def main(): """Main function to execute the script from command line.""" # Check for --json-output flag for MCP integration json_output_mode = '--json-output' in sys.argv if json_output_mode: # Remove the flag from argv for processing sys.argv.remove('--json-output') # Expect only input file if len(sys.argv) != 2: print("Usage: python task_converter.py --json-output <input_markdown>", file=sys.stderr) sys.exit(1) input_file = sys.argv[1] # Validate input file if not os.path.isfile(input_file): print(f"Error: Input file '{input_file}' does not exist.", file=sys.stderr) sys.exit(1) try: # Process markdown and output JSON to stdout def progress_to_stderr(msg): print(f"[Progress] {msg}", file=sys.stderr) tasks = process_markdown(input_file, progress_callback=progress_to_stderr) # Output JSON to stdout for MCP consumption print(json.dumps(tasks, indent=2)) sys.exit(0) except Exception as e: print(f"Error during conversion: {str(e)}", file=sys.stderr) sys.exit(1) else: # Original file-based mode if len(sys.argv) < 3: print("Usage: python task_converter.py <input_markdown> <output_json>") print(" or: python task_converter.py --json-output <input_markdown>") sys.exit(1) input_file = sys.argv[1] output_file = sys.argv[2] success = convert_tasks(input_file, output_file) if success: print("\nJSON structure is compatible with Claude Code MCP format.") # Show example of how to use the output print("\nTo use this file with Claude Code MCP:") print("1. Configure your MCP server to use this JSON file") print("2. Start your MCP server with the command:") print(f" claude mcp add arangodb-validation -- node /path/to/server.js '{output_file}'") print("3. The tasks will be available to Claude through the MCP server") else: print("\nTask conversion failed.") sys.exit(1)
Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/twalichiewicz/meshseeks'

If you have feedback or need assistance with the MCP directory API, please join our Discord server