hataraku
Version:
An autonomous coding agent for building AI-powered development tools. The name "Hataraku" (働く) means "to work" in Japanese.
134 lines • 5.66 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HatarakuMcpServer = void 0;
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
const task_tool_adapter_1 = require("./task-tool-adapter");
const agent_1 = require("../../agent");
const sample_tasks_1 = require("../../sample-tasks");
const node_fs_1 = require("node:fs");
const node_path_1 = __importDefault(require("node:path"));
const node_os_1 = __importDefault(require("node:os"));
// Should be stored in ~/.hataraku/hataraku-mcp-server-<timestamp>.log
const logDir = node_path_1.default.join(node_os_1.default.homedir(), '.hataraku');
// Create the log directory if it doesn't exist
if (!(0, node_fs_1.existsSync)(logDir)) {
(0, node_fs_1.mkdirSync)(logDir, { recursive: true });
}
const logFile = node_path_1.default.join(logDir, `hataraku-mcp-server-${Date.now()}.log`);
function log(message) {
(0, node_fs_1.appendFileSync)(logFile, message);
}
class HatarakuMcpServer {
server;
tasks;
adapter;
agent;
constructor(model, defaultAgent) {
this.server = new index_js_1.Server({
name: 'hataraku-mcp-server',
version: '1.0.0',
}, {
capabilities: {
tools: {},
},
});
this.server.onerror = (error) => {
console.error(`Server error: ${error.message}`, { code: error.code, stack: error.stack });
};
this.tasks = new Map();
this.adapter = new task_tool_adapter_1.TaskToolAdapter();
this.agent = defaultAgent ?? (0, agent_1.createAgent)({
name: 'hataraku-task-agent',
description: 'Agent for executing Hataraku tasks',
role: 'A software development assistant that helps with code analysis, review, and improvement',
model
});
}
async start(transport = new stdio_js_1.StdioServerTransport()) {
await this.discoverTasks();
await this.registerTools();
await this.server.connect(transport);
return this.server;
}
async discoverTasks() {
// Create instances of all available tasks
const taskFactories = [
sample_tasks_1.createCodeAnalysisTask,
sample_tasks_1.createBugAnalysisTask,
sample_tasks_1.createPRReviewTask,
sample_tasks_1.createRefactoringPlanTask
];
// Initialize tasks with the default agent
for (const factory of taskFactories) {
const task = factory(this.agent);
this.tasks.set(task.name, task);
}
}
async registerTools() {
// Register tasks as MCP tools
this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
const tools = Array.from(this.tasks.values()).map(task => {
const tool = this.adapter.convertToMcpTool(task);
return {
name: tool.name,
description: tool.description,
inputSchema: {
type: 'object',
properties: {
content: {
type: 'string',
description: 'The input content for the task'
}
},
required: ['content']
}
};
});
return {
tools,
_meta: {}
};
});
this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
const task = this.tasks.get(request.params.name);
if (!task) {
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Tool not found: ${request.params.name}`);
}
try {
const logEntry = `Calling task: ${task.name}\nRequest params: ${JSON.stringify(request.params)}\n`;
log(logEntry);
const args = request.params.arguments || {};
if (!args.content || typeof args.content !== 'string') {
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing or invalid content parameter');
}
const tool = this.adapter.convertToMcpTool(task);
const result = await tool.execute({ content: args.content });
log(`Task ${task.name} executed with result: ${JSON.stringify(result)}`);
return {
content: [{
type: 'text',
text: typeof result === 'string' ? result : JSON.stringify(result, null, 2)
}],
_meta: {}
};
}
catch (error) {
console.error('Task execution error:', error);
if (error instanceof types_js_1.McpError) {
throw error;
}
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidRequest, error instanceof Error ? error.message : 'Task execution failed');
}
});
}
async close() {
await this.server.close();
}
}
exports.HatarakuMcpServer = HatarakuMcpServer;
//# sourceMappingURL=hataraku-mcp-server.js.map