fenkit-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -0
- package/dist/index.js +1312 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/index.ts","../src/tools/auth.ts","../src/api.ts","../src/tools/projects.ts","../src/tools/task-read.ts","../src/utils.ts","../src/tools/task-write.ts","../src/schemas.ts","../src/tools/setup.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\n\nconst CONFIG_DIR = path.join(os.homedir(), '.fnk');\nconst CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');\n\nexport interface FnkConfig {\n token: string;\n currentProjectId?: string;\n currentProjectName?: string;\n apiUrl: string;\n}\n\nconst DEFAULT_CONFIG: FnkConfig = {\n token: '',\n apiUrl: 'https://ickit-be.vercel.app/api/v1',\n};\n\nfunction ensureConfigDir(): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\nexport function loadConfig(): FnkConfig {\n ensureConfigDir();\n\n if (!fs.existsSync(CONFIG_FILE)) {\n return { ...DEFAULT_CONFIG };\n }\n\n const raw = fs.readFileSync(CONFIG_FILE, 'utf-8');\n return { ...DEFAULT_CONFIG, ...JSON.parse(raw) } as FnkConfig;\n}\n\nexport function saveConfig(config: Partial<FnkConfig>): void {\n ensureConfigDir();\n\n const current = loadConfig();\n const merged = { ...current, ...config };\n\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2), 'utf-8');\n}\n\nexport function requireAuth(): FnkConfig {\n const config = loadConfig();\n if (!config.token) {\n throw new Error('NOT_AUTHENTICATED: No token found. Run the `login` tool or configure ~/.fnk/config.json with your API key.');\n }\n return config;\n}\n\nexport function requireProject(): FnkConfig {\n const config = requireAuth();\n if (!config.currentProjectId) {\n throw new Error('NO_ACTIVE_PROJECT: No project selected. Use `select_project` or `list_projects` first.');\n }\n return config;\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { registerAuthTools } from './tools/auth.js';\nimport { registerProjectTools } from './tools/projects.js';\nimport { registerTaskReadTools } from './tools/task-read.js';\nimport { registerTaskWriteTools } from './tools/task-write.js';\nimport { registerSetupTools, setupHandlers, CLIENTS, ClientType } from './tools/setup.js';\n\nconst server = new McpServer({\n\tname: 'fenkit-mcp',\n\tversion: '0.1.0',\n\tdescription:\n\t\t'Fenkit MCP Server — LLM-native task coordination layer for AI agents. Discover, plan, execute, and track tasks in the Fenkit platform.'\n});\n\n// Phase 1: Auth & Config\nregisterAuthTools(server);\n\n// Phase 1: Project Management\nregisterProjectTools(server);\n\n// Phase 1: Task Discovery & Retrieval\nregisterTaskReadTools(server);\n\n// Phase 2: Task Writes (Plan, Walkthrough, Metadata)\nregisterTaskWriteTools(server);\n\n// Setup: Client Configuration (Claude, Cursor, Windsurf, Codex, Antigravity)\nregisterSetupTools(server);\n\n// Start the server with stdio transport\nasync function main(): Promise<void> {\n\tconst args = process.argv.slice(2);\n\n\t// Manual Setup Command: node dist/index.js setup <client>\n\tif (args[0] === 'setup') {\n\t\tconst client = args[1] as ClientType;\n\t\tif (!client || !CLIENTS.includes(client)) {\n\t\t\tconsole.error(`Usage: fenkit-mcp setup <${CLIENTS.join('|')}>`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\ttry {\n\t\t\t// In CLI mode, we assume argv[1] is the absolute path to the current script\n\t\t\tconst serverPath = process.argv[1];\n\t\t\tconst result = setupHandlers[client](serverPath);\n\t\t\tconsole.log(`✅ Fenkit MCP configured for ${client}`);\n\t\t\tconsole.log(`Action: ${result.action}`);\n\t\t\tconsole.log(`Config path: ${result.path}`);\n\t\t\tconsole.log(`\\nNext steps:`);\n\t\t\tconsole.log(`1. Restart ${client} to load the new config.`);\n\t\t\tconsole.log(`2. Call 'get_status' to verify the connection.`);\n\t\t\tprocess.exit(0);\n\t\t} catch (error) {\n\t\t\tconsole.error(`❌ Error setting up ${client}:`, error instanceof Error ? error.message : error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\t// Default: Start MCP Server\n\tconst transport = new StdioServerTransport();\n\tawait server.connect(transport);\n}\n\nmain().catch((error) => {\n\tconsole.error('Fatal error starting MCP server:', error);\n\tprocess.exit(1);\n});\n","import http from 'node:http';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport open from 'open';\nimport { loadConfig, saveConfig } from '../config.js';\nimport { getApiClient } from '../api.js';\n\ninterface ProjectResponse {\n\tid: string;\n\tname: string;\n\tdescription?: string;\n}\n\n/**\n * Finds an available port by letting the OS pick one.\n */\nfunction getAvailablePort(): Promise<number> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst server = http.createServer();\n\t\tserver.listen(0, '127.0.0.1', () => {\n\t\t\tconst address = server.address();\n\t\t\tif (address && typeof address !== 'string') {\n\t\t\t\tconst port = address.port;\n\t\t\t\tserver.close(() => resolve(port));\n\t\t\t} else {\n\t\t\t\tserver.close(() => reject(new Error('Could not determine port')));\n\t\t\t}\n\t\t});\n\t\tserver.on('error', reject);\n\t});\n}\n\n/**\n * Starts a temporary local HTTP server that waits for a token callback\n * from the frontend auth page.\n */\nfunction waitForToken(port: number): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst server = http.createServer((req, res) => {\n\t\t\t// Enable CORS for the frontend origin\n\t\t\tres.setHeader('Access-Control-Allow-Origin', '*');\n\t\t\tres.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');\n\t\t\tres.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n\t\t\tif (req.method === 'OPTIONS') {\n\t\t\t\tres.writeHead(204);\n\t\t\t\tres.end();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (req.method === 'POST' && req.url === '/callback') {\n\t\t\t\tlet body = '';\n\t\t\t\treq.on('data', (chunk: Buffer) => {\n\t\t\t\t\tbody += chunk.toString();\n\t\t\t\t});\n\t\t\t\treq.on('end', () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst { token } = JSON.parse(body) as { token: string };\n\t\t\t\t\t\tres.writeHead(200, { 'Content-Type': 'application/json' });\n\t\t\t\t\t\tres.end(JSON.stringify({ ok: true }));\n\t\t\t\t\t\tserver.close();\n\t\t\t\t\t\tresolve(token);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tres.writeHead(400, { 'Content-Type': 'application/json' });\n\t\t\t\t\t\tres.end(JSON.stringify({ error: 'Invalid payload' }));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tres.writeHead(404);\n\t\t\tres.end();\n\t\t});\n\n\t\tserver.listen(port, '127.0.0.1');\n\n\t\tserver.on('error', (err) => {\n\t\t\treject(err);\n\t\t});\n\n\t\t// Timeout after 2 minutes\n\t\tsetTimeout(() => {\n\t\t\tserver.close();\n\t\t\treject(new Error('Authentication timed out after 2 minutes.'));\n\t\t}, 120_000);\n\t});\n}\n\n/**\n * Phase 1: Authentication tools\n * PRD Section 6.5 + 9\n */\nexport function registerAuthTools(server: McpServer): void {\n\t// login — Shared handler for browser-based auth\n\tconst loginHandler = async ({ appUrl, apiUrl }: { appUrl?: string; apiUrl?: string }) => {\n\t\tconst resolvedAppUrl = appUrl ?? 'https://ickit-fe.vercel.app';\n\t\tconst resolvedApiUrl = apiUrl ?? 'https://ickit-be.vercel.app/api/v1';\n\n\t\t// Save API URL first so subsequent calls use it\n\t\tsaveConfig({ apiUrl: resolvedApiUrl });\n\n\t\tlet port: number;\n\t\ttry {\n\t\t\tport = await getAvailablePort();\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'text' as const,\n\t\t\t\t\t\ttext: '❌ Could not find an available port for the auth callback server.'\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t};\n\t\t}\n\n\t\tconst authUrl = `${resolvedAppUrl}/tool-auth?port=${port}&tool=mcp`;\n\n\t\t// Start the token receiver before opening the browser\n\t\tconst tokenPromise = waitForToken(port);\n\n\t\ttry {\n\t\t\tawait open(authUrl);\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'text' as const,\n\t\t\t\t\t\ttext: `❌ Could not open browser. Please visit manually:\\n\\n${authUrl}`\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t};\n\t\t}\n\n\t\tlet token: string;\n\t\ttry {\n\t\t\ttoken = await tokenPromise;\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : 'Unknown error';\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'text' as const,\n\t\t\t\t\t\ttext: `❌ Authentication failed: ${message}`\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t};\n\t\t}\n\n\t\tsaveConfig({ token });\n\n\t\tlet autoSelectedProjectName: string | undefined;\n\t\ttry {\n\t\t\tconst api = getApiClient(true);\n\t\t\tconst { data } = await api.get<ProjectResponse[]>('/projects');\n\n\t\t\tif (data.length === 1) {\n\t\t\t\tconst project = data[0];\n\t\t\t\tsaveConfig({\n\t\t\t\t\tcurrentProjectId: project.id,\n\t\t\t\t\tcurrentProjectName: project.name\n\t\t\t\t});\n\t\t\t\tautoSelectedProjectName = project.name;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// We don't want to fail the whole login if project fetching fails\n\t\t\tconsole.error('Failed to fetch projects for auto-selection:', error);\n\t\t}\n\n\t\tlet successMessage = '✅ Authenticated successfully! Token saved to ~/.fnk/config.json.';\n\t\tif (autoSelectedProjectName) {\n\t\t\tsuccessMessage += `\\n\\n✔ **Auto-selected project**: ${autoSelectedProjectName}. You're ready to go!`;\n\t\t} else {\n\t\t\tsuccessMessage += '\\n\\nUse `list_projects` to see your projects and `select_project` to set an active one.';\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'text' as const,\n\t\t\t\t\ttext: successMessage\n\t\t\t\t}\n\t\t\t]\n\t\t};\n\t};\n\n\t// Primary login tool\n\tserver.tool(\n\t\t'login',\n\t\t'Authenticate via browser. Opens a browser window pointing to the Fenkit app, waits for authentication, then saves the token automatically.',\n\t\t{\n\t\t\tappUrl: z.string().optional().describe('Frontend app URL (default: https://ickit-fe.vercel.app)'),\n\t\t\tapiUrl: z.string().optional().describe('API base URL (default: https://ickit-be.vercel.app/api/v1)')\n\t\t},\n\t\tloginHandler\n\t);\n\n\t// get_status — Returns current auth and project status\n\tserver.tool(\n\t\t'get_status',\n\t\t'Check current authentication status and active project. Call this to verify your setup before starting work.',\n\t\t{},\n\t\tasync () => {\n\t\t\tconst config = loadConfig();\n\t\t\tconst authenticated = !!config.token;\n\t\t\tconst hasProject = !!config.currentProjectId;\n\n\t\t\tconst lines = [\n\t\t\t\t`**Authenticated**: ${authenticated ? '✅ Yes' : \"❌ No — run 'login_browser' first\"}`,\n\t\t\t\t`**API URL**: ${config.apiUrl}`\n\t\t\t];\n\n\t\t\tif (hasProject) {\n\t\t\t\tlines.push(`**Active Project**: ${config.currentProjectName || config.currentProjectId}`);\n\t\t\t\tlines.push(`**Project ID**: ${config.currentProjectId}`);\n\t\t\t} else {\n\t\t\t\tlines.push('**Active Project**: None — use `list_projects` and `select_project` first');\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: 'text' as const, text: lines.join('\\n') }]\n\t\t\t};\n\t\t}\n\t);\n}\n","import axios, { AxiosInstance, AxiosError } from 'axios';\nimport { loadConfig } from './config.js';\n\nlet client: AxiosInstance | null = null;\n\nexport function getApiClient(force = false): AxiosInstance {\n if (client && !force) return client;\n\n const config = loadConfig();\n\n let { apiUrl } = config;\n if (\n (apiUrl.includes('localhost') || apiUrl.includes('127.0.0.1')) &&\n !apiUrl.includes('/api/v1')\n ) {\n apiUrl = apiUrl.replace(/\\/$/, '') + '/api/v1';\n }\n\n client = axios.create({\n baseURL: apiUrl,\n headers: {\n Authorization: `ApiKey ${config.token}`,\n 'Content-Type': 'application/json',\n },\n timeout: 15000,\n });\n\n return client;\n}\n\nexport interface ApiErrorResult {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport function formatApiError(error: unknown): ApiErrorResult {\n if (error instanceof AxiosError) {\n if (error.response) {\n const status = error.response.status;\n const message =\n (error.response.data as Record<string, string>)?.message ||\n error.message;\n\n if (status === 401) {\n return {\n code: 'NOT_AUTHENTICATED',\n message: 'Authentication failed. Check your token or run `login`.',\n };\n }\n if (status === 404) {\n return {\n code: 'TASK_NOT_FOUND',\n message: `Not found: ${message}`,\n };\n }\n return {\n code: 'API_ERROR',\n message: `API Error (${status}): ${message}`,\n };\n }\n if (error.code === 'ECONNREFUSED') {\n return {\n code: 'API_ERROR',\n message: 'Cannot connect to the API server. Is it running?',\n };\n }\n return {\n code: 'API_ERROR',\n message: `Network error: ${error.message}`,\n };\n }\n\n if (error instanceof Error) {\n // Handle our custom auth/project errors\n if (error.message.startsWith('NOT_AUTHENTICATED:')) {\n return { code: 'NOT_AUTHENTICATED', message: error.message };\n }\n if (error.message.startsWith('NO_ACTIVE_PROJECT:')) {\n return { code: 'NO_ACTIVE_PROJECT', message: error.message };\n }\n return { code: 'INTERNAL_ERROR', message: error.message };\n }\n\n return { code: 'INTERNAL_ERROR', message: 'An unexpected error occurred.' };\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { requireAuth, saveConfig } from '../config.js';\nimport { getApiClient, formatApiError } from '../api.js';\n\ninterface ProjectResponse {\n id: string;\n name: string;\n description?: string;\n}\n\n/**\n * Phase 1: Project management tools\n * PRD Section 6.1\n */\nexport function registerProjectTools(server: McpServer): void {\n // list_projects — GET /projects\n server.tool(\n 'list_projects',\n 'List all accessible projects in your Fenkit workspace. Returns project IDs, names, and descriptions. Use this to discover projects before selecting one.',\n {},\n async () => {\n try {\n requireAuth();\n const api = getApiClient();\n const { data } = await api.get<ProjectResponse[]>('/projects');\n\n if (data.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No projects found. Create one in the Fenkit web UI first.' }],\n };\n }\n\n const { loadConfig } = await import('../config.js');\n const config = loadConfig();\n\n const lines = data.map((p) => {\n const active = p.id === config.currentProjectId ? ' ← **active**' : '';\n return `- **${p.name}** (\\`${p.id.slice(0, 8)}\\`)${p.description ? ` — ${p.description}` : ''}${active}`;\n });\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `## Projects\\n\\n${lines.join('\\n')}`,\n },\n ],\n };\n } catch (error) {\n const err = formatApiError(error);\n return { content: [{ type: 'text' as const, text: `Error: ${err.message}` }], isError: true };\n }\n },\n );\n\n // get_active_project — reads config\n server.tool(\n 'get_active_project',\n 'Get the currently active project. Returns the project name and ID from local config.',\n {},\n async () => {\n try {\n const config = requireAuth();\n if (!config.currentProjectId) {\n return {\n content: [{ type: 'text' as const, text: 'No active project. Use `list_projects` and `select_project` to choose one.' }],\n };\n }\n return {\n content: [\n {\n type: 'text' as const,\n text: `**Active Project**: ${config.currentProjectName || 'Unknown'}\\n**ID**: \\`${config.currentProjectId}\\``,\n },\n ],\n };\n } catch (error) {\n const err = formatApiError(error);\n return { content: [{ type: 'text' as const, text: `Error: ${err.message}` }], isError: true };\n }\n },\n );\n\n // select_project — updates currentProjectId in config\n server.tool(\n 'select_project',\n 'Set the active project by ID. All subsequent task operations will use this project. Call `list_projects` first to discover available project IDs.',\n {\n projectId: z.string().describe('Project ID to select as active'),\n },\n async ({ projectId }) => {\n try {\n requireAuth();\n const api = getApiClient();\n const { data } = await api.get<ProjectResponse[]>('/projects');\n\n const selected = data.find((p) => p.id === projectId || p.id.startsWith(projectId));\n if (!selected) {\n return {\n content: [{ type: 'text' as const, text: `Project \"${projectId}\" not found. Use \\`list_projects\\` to see available projects.` }],\n isError: true,\n };\n }\n\n saveConfig({\n currentProjectId: selected.id,\n currentProjectName: selected.name,\n });\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `✔ Active project set to **${selected.name}** (\\`${selected.id.slice(0, 8)}\\`)`,\n },\n ],\n };\n } catch (error) {\n const err = formatApiError(error);\n return { content: [{ type: 'text' as const, text: `Error: ${err.message}` }], isError: true };\n }\n },\n );\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { requireProject } from '../config.js';\nimport { getApiClient, formatApiError } from '../api.js';\nimport { stripPrivate } from '../utils.js';\n\ninterface TaskResponse {\n\tid: string;\n\tprojectId: string;\n\ttitle: string;\n\tdescription?: string | null;\n\tstatus: string;\n\tpriority: string;\n\tassigneeId?: string | null;\n\tplan?: string | null;\n\twalkthrough?: string | null;\n\timplementationMetadata?: Record<string, unknown> | null;\n\tcreatedBy: string;\n\tupdatedBy?: string | null;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\ttags?: { id: string; name: string; color: string | null }[];\n}\n\nconst STATUS_ICONS: Record<string, string> = {\n\ttodo: '📋',\n\tin_progress: '🏗️',\n\tdone: '✅',\n\tbacklog: '📥',\n\tfrozen: '❄️'\n};\n\n/**\n * Phase 1: Task read tools (discovery + retrieval)\n * PRD Sections 6.2, 6.3\n */\nexport function registerTaskReadTools(server: McpServer): void {\n\t// list_tasks — GET /projects/:projectId/tasks\n\tserver.tool(\n\t\t'list_tasks',\n\t\t'List tasks in the active project. Returns task titles, IDs, status, and priority. Use status filter to narrow results. Default shows todo + in_progress tasks.',\n\t\t{\n\t\t\tstatus: z\n\t\t\t\t.string()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t'Comma-separated status filter (e.g. \"todo,in_progress\"). Default: \"todo,in_progress\". Options: todo, in_progress, done, backlog, frozen'\n\t\t\t\t)\n\t\t},\n\t\tasync ({ status }) => {\n\t\t\ttry {\n\t\t\t\tconst config = requireProject();\n\t\t\t\tconst api = getApiClient();\n\t\t\t\tconst params = new URLSearchParams();\n\t\t\t\tconst statusFilter = status || 'todo,in_progress';\n\t\t\t\tparams.set('status', statusFilter);\n\n\t\t\t\tconst { data } = await api.get<TaskResponse[]>(\n\t\t\t\t\t`/projects/${config.currentProjectId}/tasks?${params.toString()}`\n\t\t\t\t);\n\n\t\t\t\tif (data.length === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text' as const, text: `No tasks found with status: ${statusFilter}` }]\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst statusOrder = ['in_progress', 'todo', 'frozen', 'backlog', 'done'];\n\t\t\t\tconst tasksByStatus: Record<string, TaskResponse[]> = {};\n\n\t\t\t\tfor (const t of data) {\n\t\t\t\t\tif (!tasksByStatus[t.status]) tasksByStatus[t.status] = [];\n\t\t\t\t\ttasksByStatus[t.status].push(t);\n\t\t\t\t}\n\n\t\t\t\tconst lines: string[] = [`## Tasks in ${config.currentProjectName || 'project'}`, ''];\n\n\t\t\t\tfor (const s of statusOrder) {\n\t\t\t\t\tconst tasks = tasksByStatus[s];\n\t\t\t\t\tif (tasks && tasks.length > 0) {\n\t\t\t\t\t\tlines.push(`### ${STATUS_ICONS[s] || '⬜'} ${s.replace('_', ' ').toUpperCase()}`);\n\t\t\t\t\t\tfor (const t of tasks) {\n\t\t\t\t\t\t\tconst tags = t.tags?.length ? ` [${t.tags.map((tg) => tg.name).join(', ')}]` : '';\n\t\t\t\t\t\t\tconst desc = t.description\n\t\t\t\t\t\t\t\t? ` — ${t.description.substring(0, 60)}${t.description.length > 60 ? '...' : ''}`\n\t\t\t\t\t\t\t\t: '';\n\t\t\t\t\t\t\tlines.push(`- **${t.title}** (\\`${t.id.substring(0, 5)}\\`) · ${t.priority}${tags}${desc}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlines.push('');\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n\t\t\t} catch (error) {\n\t\t\t\tconst err = formatApiError(error);\n\t\t\t\treturn { content: [{ type: 'text' as const, text: `Error: ${err.message}` }], isError: true };\n\t\t\t}\n\t\t}\n\t);\n\n\t// search_tasks — GET /projects/:projectId/tasks?search=\n\tserver.tool(\n\t\t'search_tasks',\n\t\t'Search tasks by name or description in the active project. Returns matching tasks with their IDs and status.',\n\t\t{\n\t\t\tquery: z.string().describe('Search query to match against task titles and descriptions')\n\t\t},\n\t\tasync ({ query }) => {\n\t\t\ttry {\n\t\t\t\tconst config = requireProject();\n\t\t\t\tconst api = getApiClient();\n\n\t\t\t\tconst { data } = await api.get<TaskResponse[]>(\n\t\t\t\t\t`/projects/${config.currentProjectId}/tasks?search=${encodeURIComponent(query)}`\n\t\t\t\t);\n\n\t\t\t\tif (data.length === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text' as const, text: `No tasks found matching \"${query}\"` }]\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst lines = data.map(\n\t\t\t\t\t(t) =>\n\t\t\t\t\t\t`- **${t.title}** (\\`${t.id.substring(0, 5)}\\`) · ${STATUS_ICONS[t.status] || ''} ${t.status} · ${t.priority}`\n\t\t\t\t);\n\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'text' as const,\n\t\t\t\t\t\t\ttext: `## Search results for \"${query}\"\\n\\n${lines.join('\\n')}`\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tconst err = formatApiError(error);\n\t\t\t\treturn { content: [{ type: 'text' as const, text: `Error: ${err.message}` }], isError: true };\n\t\t\t}\n\t\t}\n\t);\n\n\t// get_full_task — Full task context retrieval\n\t// PRD 6.3: Returns full task context in one retrieval\n\tserver.tool(\n\t\t'get_full_task',\n\t\t'Retrieve the full context of a task including description, plan, walkthrough, metadata, and history — all in one call. This is the primary tool for understanding a task before starting work. Supports both full UUIDs and truncated IDs.',\n\t\t{\n\t\t\ttaskId: z.string().describe('Task ID (full UUID or truncated prefix like \"22b50\")')\n\t\t},\n\t\tasync ({ taskId }) => {\n\t\t\ttry {\n\t\t\t\tconst config = requireProject();\n\t\t\t\tconst api = getApiClient();\n\n\t\t\t\tlet taskData: TaskResponse;\n\n\t\t\t\tconst isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(taskId);\n\n\t\t\t\tif (isUuid) {\n\t\t\t\t\tconst { data } = await api.get<TaskResponse>(`/projects/${config.currentProjectId}/tasks/${taskId}`);\n\t\t\t\t\ttaskData = data;\n\t\t\t\t} else {\n\t\t\t\t\t// Fuzzy search by name or truncated ID\n\t\t\t\t\tconst { data } = await api.get<TaskResponse[]>(\n\t\t\t\t\t\t`/projects/${config.currentProjectId}/tasks?search=${encodeURIComponent(taskId)}`\n\t\t\t\t\t);\n\n\t\t\t\t\tif (data.length === 0) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: 'text' as const,\n\t\t\t\t\t\t\t\t\ttext: `No task found matching \"${taskId}\". Use \\`list_tasks\\` or \\`search_tasks\\` to find the right task.`\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tisError: true\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\ttaskData = data[0];\n\t\t\t\t}\n\n\t\t\t\t// Record retrieval timestamp for duration tracking\n\t\t\t\tconst existingMetadata = (taskData.implementationMetadata as Record<string, unknown>) || {};\n\t\t\t\tawait api.patch(`/projects/${config.currentProjectId}/tasks/${taskData.id}`, {\n\t\t\t\t\timplementationMetadata: {\n\t\t\t\t\t\t...existingMetadata,\n\t\t\t\t\t\tlastRetrievedAt: new Date().toISOString()\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Build comprehensive markdown context\n\t\t\t\tconst sections: string[] = [];\n\t\t\t\tsections.push(`# ${taskData.title}`);\n\t\t\t\tsections.push('');\n\t\t\t\tsections.push(\n\t\t\t\t\t`**ID**: \\`${taskData.id}\\` · **Status**: ${STATUS_ICONS[taskData.status] || ''} ${taskData.status} · **Priority**: ${taskData.priority}`\n\t\t\t\t);\n\n\t\t\t\tif (taskData.tags?.length) {\n\t\t\t\t\tsections.push(`**Tags**: ${taskData.tags.map((t) => t.name).join(', ')}`);\n\t\t\t\t}\n\n\t\t\t\t// Description\n\t\t\t\tsections.push('## Description');\n\t\t\t\tsections.push(taskData.description ? stripPrivate(taskData.description) : '_(no description)_');\n\t\t\t\tsections.push('');\n\n\t\t\t\t// Plan\n\t\t\t\tif (taskData.plan) {\n\t\t\t\t\tsections.push('## Plan');\n\t\t\t\t\tsections.push(stripPrivate(taskData.plan));\n\t\t\t\t\tsections.push('');\n\t\t\t\t}\n\n\t\t\t\t// Walkthrough (included for rework context — PRD 7.5)\n\t\t\t\tif (taskData.walkthrough) {\n\t\t\t\t\tsections.push('## Walkthrough');\n\t\t\t\t\tsections.push(stripPrivate(taskData.walkthrough));\n\t\t\t\t\tsections.push('');\n\t\t\t\t}\n\n\t\t\t\t// Implementation Metadata\n\t\t\t\tif (taskData.implementationMetadata) {\n\t\t\t\t\tconst meta = taskData.implementationMetadata;\n\t\t\t\t\tsections.push('## Implementation Metadata');\n\t\t\t\t\tsections.push('```json');\n\t\t\t\t\tsections.push(JSON.stringify(meta, null, 2));\n\t\t\t\t\tsections.push('```');\n\t\t\t\t\tsections.push('');\n\t\t\t\t}\n\n\t\t\t\treturn { content: [{ type: 'text' as const, text: sections.join('\\n') }] };\n\t\t\t} catch (error) {\n\t\t\t\tconst err = formatApiError(error);\n\t\t\t\treturn { content: [{ type: 'text' as const, text: `Error: ${err.message}` }], isError: true };\n\t\t\t}\n\t\t}\n\t);\n}\n","import os from 'node:os';\nimport { execSync } from 'node:child_process';\nimport type { ExecutionMetadata } from './schemas.js';\n\n/**\n * Strips <private>...</private> tags from content before returning to LLM.\n * PRD Section 10: Security & Privacy — Redaction\n */\nexport function stripPrivate(content: string): string {\n return content.replace(/<private>[\\s\\S]*?<\\/private>/gi, '[REDACTED]');\n}\n\n/**\n * Determines the AI provider from a model name string.\n * Mirrors CLI logic in getProvider().\n */\nexport function getProvider(model?: string): string {\n if (!model) return 'unknown';\n const m = model.toLowerCase();\n if (m.includes('claude')) return 'anthropic';\n if (m.includes('gpt')) return 'openai';\n if (m.includes('gemini')) return 'google';\n if (m.includes('llama')) return 'meta';\n if (m.includes('mistral')) return 'mistral';\n return 'unknown';\n}\n\n/**\n * Gathers git info (commit, branch, diff stats).\n * Mirrors CLI logic in getGitInfo().\n */\nexport function getGitInfo(): Record<string, unknown> | null {\n try {\n const commit = execSync('git rev-parse HEAD', {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .toString()\n .trim();\n const branch = execSync('git rev-parse --abbrev-ref HEAD', {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .toString()\n .trim();\n\n const stats = execSync('git diff --stat', {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .toString()\n .trim();\n\n const filesChanged = stats ? stats.split('\\n').length - 1 : 0;\n const linesMatch = stats.match(/(\\d+) insertion.*(\\d+) deletion/);\n const insertions = linesMatch ? parseInt(linesMatch[1]) : 0;\n const deletions = linesMatch ? parseInt(linesMatch[2]) : 0;\n\n return {\n commit,\n branch,\n metrics: {\n filesChanged: filesChanged > 0 ? filesChanged : 0,\n linesAdded: insertions,\n linesDeleted: deletions,\n },\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Builds execution metadata for write operations.\n * Mirrors CLI buildMetadata() adapted for MCP usage.\n * PRD Section 8.2: Every write MUST include execution_metadata.\n */\nexport function buildExecutionMetadata(\n content: string,\n options?: {\n model?: string;\n agent?: string;\n lastRetrievedAt?: string;\n extraTokens?: { input?: number; output?: number; total?: number };\n },\n): ExecutionMetadata & Record<string, unknown> {\n let durationMs: number | undefined;\n if (options?.lastRetrievedAt) {\n const start = new Date(options.lastRetrievedAt).getTime();\n durationMs = Date.now() - start;\n }\n\n const provider = getProvider(options?.model);\n\n return {\n timestamp: new Date().toISOString(),\n durationMs,\n agent: options?.agent || 'mcp-server',\n model: options?.model,\n provider,\n tokens: {\n estimate: Math.ceil(content.length / 4),\n ...options?.extraTokens,\n },\n git: getGitInfo(),\n env: {\n os: os.platform(),\n node: process.version,\n },\n };\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { requireProject } from '../config.js';\nimport { getApiClient, formatApiError } from '../api.js';\nimport { PlanSchema, WalkthroughSchema } from '../schemas.js';\nimport { buildExecutionMetadata } from '../utils.js';\n\ninterface TaskResponse {\n id: string;\n plan?: string | null;\n walkthrough?: string | null;\n implementationMetadata?: Record<string, unknown> | null;\n}\n\n/**\n * Phase 2 + 3: Task write tools\n * PRD Sections 6.4, 8.2 (auto-inject execution_metadata on writes)\n */\nexport function registerTaskWriteTools(server: McpServer): void {\n // update_task_plan — PATCH with structured plan\n server.tool(\n 'update_task_plan',\n 'Submit or update an implementation plan for a task. The plan must follow the structured schema with summary, steps, files_affected, etc. Use this after retrieving a task with `get_full_task` and analyzing the requirements. Plans are versioned — previous versions are preserved in history.',\n {\n taskId: z.string().describe('Task ID (full UUID or truncated prefix)'),\n plan: PlanSchema,\n model: z.string().describe('Model used for this plan (e.g. \"claude-sonnet-4-20250514\")'),\n agent: z.string().describe('Agent/client name (e.g. \"cursor\", \"claude-desktop\")'),\n },\n async ({ taskId, plan, model, agent }) => {\n try {\n // Validate plan schema\n const parsed = PlanSchema.parse(plan);\n const planContent = JSON.stringify(parsed, null, 2);\n\n const config = requireProject();\n const api = getApiClient();\n\n // Fetch current task for metadata context\n const { data: currentTask } = await api.get<TaskResponse>(\n `/projects/${config.currentProjectId}/tasks/${taskId}`,\n );\n\n const existingMetadata = (currentTask.implementationMetadata as Record<string, unknown>) || {};\n const history = (existingMetadata.history as unknown[]) || [];\n\n // Build execution metadata (Phase 3: auto-inject)\n const execution = buildExecutionMetadata(planContent, {\n model,\n agent,\n lastRetrievedAt: existingMetadata.lastRetrievedAt as string | undefined,\n });\n\n const updatedMetadata = {\n ...existingMetadata,\n lastExecution: execution,\n history: [...history, { ...execution, action: 'update_plan' }],\n };\n\n await api.patch(`/projects/${config.currentProjectId}/tasks/${taskId}`, {\n plan: planContent,\n implementationMetadata: updatedMetadata,\n });\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `✔ Plan updated for task \\`${taskId}\\`.\\n\\n**Steps**: ${parsed.steps.length}\\n**Files affected**: ${parsed.files_affected.length}\\n**Complexity**: ${parsed.estimated_complexity || 'not specified'}`,\n },\n ],\n };\n } catch (error) {\n if (error instanceof z.ZodError) {\n const issues = error.issues.map((i) => `- ${i.path.join('.')}: ${i.message}`).join('\\n');\n return {\n content: [{ type: 'text' as const, text: `INVALID_INPUT: Plan validation failed:\\n${issues}` }],\n isError: true,\n };\n }\n const err = formatApiError(error);\n return { content: [{ type: 'text' as const, text: `Error: ${err.message}` }], isError: true };\n }\n },\n );\n\n // update_task_walkthrough — PATCH with structured walkthrough\n server.tool(\n 'update_task_walkthrough',\n 'Submit or update an implementation walkthrough for a task. The walkthrough must follow the structured schema with summary, changes, files_modified, decisions, testing, etc. Use this after completing implementation work. Walkthroughs are versioned — previous versions are preserved in history.',\n {\n taskId: z.string().describe('Task ID (full UUID or truncated prefix)'),\n walkthrough: WalkthroughSchema,\n model: z.string().describe('Model used for this walkthrough'),\n agent: z.string().describe('Agent/client name'),\n },\n async ({ taskId, walkthrough, model, agent }) => {\n try {\n const parsed = WalkthroughSchema.parse(walkthrough);\n const walkthroughContent = JSON.stringify(parsed, null, 2);\n\n const config = requireProject();\n const api = getApiClient();\n\n const { data: currentTask } = await api.get<TaskResponse>(\n `/projects/${config.currentProjectId}/tasks/${taskId}`,\n );\n\n const existingMetadata = (currentTask.implementationMetadata as Record<string, unknown>) || {};\n const history = (existingMetadata.history as unknown[]) || [];\n\n const execution = buildExecutionMetadata(walkthroughContent, {\n model,\n agent,\n lastRetrievedAt: existingMetadata.lastRetrievedAt as string | undefined,\n });\n\n const updatedMetadata = {\n ...existingMetadata,\n lastExecution: execution,\n history: [...history, { ...execution, action: 'update_walkthrough' }],\n };\n\n await api.patch(`/projects/${config.currentProjectId}/tasks/${taskId}`, {\n walkthrough: walkthroughContent,\n implementationMetadata: updatedMetadata,\n });\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `✔ Walkthrough updated for task \\`${taskId}\\`.\\n\\n**Changes**: ${parsed.changes.length}\\n**Files modified**: ${parsed.files_modified.length}`,\n },\n ],\n };\n } catch (error) {\n if (error instanceof z.ZodError) {\n const issues = error.issues.map((i) => `- ${i.path.join('.')}: ${i.message}`).join('\\n');\n return {\n content: [{ type: 'text' as const, text: `INVALID_INPUT: Walkthrough validation failed:\\n${issues}` }],\n isError: true,\n };\n }\n const err = formatApiError(error);\n return { content: [{ type: 'text' as const, text: `Error: ${err.message}` }], isError: true };\n }\n },\n );\n\n // update_task_metadata — PATCH for status/priority changes\n server.tool(\n 'update_task_metadata',\n 'Update task status, priority, or other metadata fields. Use this for lifecycle transitions (e.g. moving a task from \"todo\" to \"in_progress\" or marking it \"done\").',\n {\n taskId: z.string().describe('Task ID (full UUID or truncated prefix)'),\n status: z.string().optional().describe('New status: todo, in_progress, done, backlog, frozen'),\n priority: z.string().optional().describe('New priority: low, medium, high, urgent'),\n model: z.string().describe('Model used (for execution metadata tracking)'),\n agent: z.string().describe('Agent/client name'),\n },\n async ({ taskId, status, priority, model, agent }) => {\n try {\n const config = requireProject();\n const api = getApiClient();\n\n const updatePayload: Record<string, unknown> = {};\n if (status) updatePayload.status = status;\n if (priority) updatePayload.priority = priority;\n\n if (Object.keys(updatePayload).length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'INVALID_INPUT: Must provide at least one of: status, priority' }],\n isError: true,\n };\n }\n\n // Fetch current metadata for history tracking\n const { data: currentTask } = await api.get<TaskResponse>(\n `/projects/${config.currentProjectId}/tasks/${taskId}`,\n );\n\n const existingMetadata = (currentTask.implementationMetadata as Record<string, unknown>) || {};\n const history = (existingMetadata.history as unknown[]) || [];\n\n const execution = buildExecutionMetadata(JSON.stringify(updatePayload), {\n model,\n agent,\n lastRetrievedAt: existingMetadata.lastRetrievedAt as string | undefined,\n });\n\n updatePayload.implementationMetadata = {\n ...existingMetadata,\n lastExecution: execution,\n history: [...history, { ...execution, action: 'update_metadata', changes: updatePayload }],\n };\n\n await api.patch(`/projects/${config.currentProjectId}/tasks/${taskId}`, updatePayload);\n\n const changes = [];\n if (status) changes.push(`Status → ${status}`);\n if (priority) changes.push(`Priority → ${priority}`);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `✔ Task \\`${taskId}\\` updated: ${changes.join(', ')}`,\n },\n ],\n };\n } catch (error) {\n const err = formatApiError(error);\n return { content: [{ type: 'text' as const, text: `Error: ${err.message}` }], isError: true };\n }\n },\n );\n}\n","import { z } from 'zod';\n\n// --- PRD 4.2: Plan Schema ---\nexport const PlanSchema = z.object({\n summary: z.string().describe('Brief summary of the implementation plan'),\n steps: z.array(z.string()).describe('Ordered list of implementation steps'),\n files_affected: z.array(z.string()).describe('Files that will be created or modified'),\n risks: z.array(z.string()).optional().describe('Potential risks or blockers'),\n assumptions: z.array(z.string()).optional().describe('Assumptions made during planning'),\n open_questions: z.array(z.string()).optional().describe('Unresolved questions'),\n estimated_complexity: z.enum(['low', 'medium', 'high']).optional().describe('Estimated task complexity'),\n notes: z.string().optional().describe('Free-form narrative context (markdown). Do not duplicate structured fields.'),\n});\nexport type Plan = z.infer<typeof PlanSchema>;\n\n// --- PRD 4.2: Walkthrough Schema ---\nexport const WalkthroughSchema = z.object({\n summary: z.string().describe('Summary of what was accomplished'),\n changes: z.array(z.string()).describe('List of changes made'),\n files_modified: z.array(z.string()).describe('Files that were modified'),\n decisions: z.array(z.string()).optional().describe('Key decisions made during implementation'),\n testing: z.array(z.string()).optional().describe('Testing performed or verification steps'),\n known_issues: z.array(z.string()).optional().describe('Known issues remaining'),\n next_steps: z.array(z.string()).optional().describe('Recommended next steps'),\n notes: z.string().optional().describe('Free-form narrative context (markdown). Do not duplicate structured fields.'),\n});\nexport type Walkthrough = z.infer<typeof WalkthroughSchema>;\n\n// --- PRD 8.3: Execution Metadata Schema ---\nexport const TokensSchema = z.object({\n input: z.number().optional().describe('Input tokens used'),\n output: z.number().optional().describe('Output tokens used'),\n total: z.number().optional().describe('Total tokens used'),\n estimate: z.number().optional().describe('Estimated token count'),\n});\n\nexport const ExecutionMetadataSchema = z.object({\n durationMs: z.number().optional().describe('Time spent in milliseconds'),\n agent: z.string().optional().describe('Agent/client name (e.g. cursor, claude-desktop)'),\n model: z.string().optional().describe('Model identifier (e.g. gpt-4.1, claude-sonnet)'),\n provider: z.string().optional().describe('Provider name (e.g. openai, anthropic)'),\n tokens: TokensSchema.optional().describe('Token usage'),\n timestamp: z.string().optional().describe('ISO-8601 timestamp'),\n});\nexport type ExecutionMetadata = z.infer<typeof ExecutionMetadataSchema>;\n\n// --- Session Summary Schema (PRD 4.2) ---\nexport const SessionSummarySchema = z.object({\n goal: z.string().describe('What was the goal of this session'),\n tasks_worked_on: z.array(z.string()).describe('Task IDs worked on'),\n accomplished: z.array(z.string()).describe('What was accomplished'),\n blockers: z.array(z.string()).optional().describe('Any blockers encountered'),\n next_recommendations: z.array(z.string()).optional().describe('Recommended next actions'),\n});\nexport type SessionSummary = z.infer<typeof SessionSummarySchema>;\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\n\n// ─── Fenkit Memory Protocol ────────────────────────────────────────────────────\n// These instructions are written to client rule files so the agent knows\n// how and when to use Fenkit MCP tools.\nconst FENKIT_MEMORY_PROTOCOL = `## Fenkit Task Protocol\nYou are an AI agent with access to the Fenkit platform. Follow this protocol for seamless task coordination:\n\n### 1. Orientation & Session Start\n- **Always** call \\`get_status\\` at the beginning of a session to verify authentication and active project.\n- If no project is active, call \\`list_projects\\` and ask the user to select one, or try to auto-select if you're in a known repository.\n- After a long pause or context reset, call \\`get_status\\` to ensure you still have the correct task context.\n\n### 2. Task Lifecycle\n- **Discovery**: Use \\`list_tasks\\` or \\`search_tasks\\` to find your assignment.\n- **Loading**: Use \\`get_full_task(taskId)\\` to retrieve full context (Plan, Walkthrough, Status) before starting.\n- **Planning**: Before coding, call \\`update_task_plan(taskId, plan)\\` with your technical approach.\n- **Execution**: Set status to \\`in_progress\\` using \\`update_task_metadata(taskId, { status: \"in_progress\" })\\`.\n- **Completion**: After verification, call \\`update_task_walkthrough(taskId, walkthrough)\\` and set status to \\`done\\` via \\`update_task_metadata\\`.\n\n### 3. Compaction & Context Trimming\n- If the system notifies you of context trimming or compaction:\n - Immediately call \\`update_task_walkthrough\\` or \\`update_task_plan\\` to persist any unsaved progress.\n - After trimming, re-orient using \\`get_full_task(taskId)\\`.\n\n### 4. Automated Updates (Session End)\n- Do not wait for the user to ask you to record progress.\n- Record plans and walkthroughs as part of your natural workflow to keep the Fenkit platform updated.\n- Before ending the session, ensure the current task status reflects the actual progress.`;\n\n// ─── Config Path Helpers ───────────────────────────────────────────────────────\n\nexport type ClientType = 'claude' | 'cursor' | 'windsurf' | 'codex' | 'antigravity' | 'claudecode';\n\nexport const CLIENTS: ClientType[] = ['claude', 'cursor', 'windsurf', 'codex', 'antigravity', 'claudecode'];\n\nconst isWindows = process.platform === 'win32';\nconst homeDir = os.homedir();\nconst appData = process.env['APPDATA'] ?? path.join(homeDir, 'AppData', 'Roaming');\n\nfunction getServerPath(): string {\n // argv[1] is the path to the current script (index.js)\n return process.argv[1] ?? path.join(homeDir, '.fnk', 'fenkit-mcp', 'dist', 'index.js');\n}\n\nfunction claudeConfigPath(): string {\n if (isWindows) {\n return path.join(appData, 'Claude', 'claude_desktop_config.json');\n }\n return path.join(homeDir, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');\n}\n\nfunction windsurfConfigPath(): string {\n if (isWindows) {\n return path.join(process.env['USERPROFILE'] ?? homeDir, '.windsurf', 'mcp.json');\n }\n return path.join(homeDir, '.windsurf', 'mcp.json');\n}\n\nfunction antigravityConfigPath(): string {\n return path.join(homeDir, '.gemini', 'antigravity', 'mcp_config.json');\n}\n\nfunction antigravityRulesPath(): string {\n return path.join(homeDir, '.gemini', 'GEMINI.md');\n}\n\nfunction codexConfigPath(): string {\n if (isWindows) {\n return path.join(appData, 'codex', 'config.toml');\n }\n return path.join(homeDir, '.codex', 'config.toml');\n}\n\nfunction claudeCodeConfigPath(): string {\n return path.join(homeDir, '.claude', 'config.json');\n}\n\nfunction codexInstructionsPath(): string {\n if (isWindows) {\n return path.join(appData, 'codex', 'fenkit-instructions.md');\n }\n return path.join(homeDir, '.codex', 'fenkit-instructions.md');\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction ensureDir(filePath: string): void {\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n}\n\nfunction readJsonOrDefault<T extends Record<string, unknown>>(filePath: string, defaultValue: T): T {\n if (!fs.existsSync(filePath)) return { ...defaultValue };\n try {\n return JSON.parse(fs.readFileSync(filePath, 'utf-8')) as T;\n } catch {\n return { ...defaultValue };\n }\n}\n\nfunction fenKitMcpEntry(serverPath: string) {\n return {\n command: 'node',\n args: [serverPath],\n };\n}\n\n// ─── Client Setup Functions ───────────────────────────────────────────────────\n\nexport function setupClaude(serverPath: string): { path: string; action: string } {\n const configPath = claudeConfigPath();\n ensureDir(configPath);\n\n const config = readJsonOrDefault<Record<string, unknown>>(configPath, {});\n const mcpServers = (config['mcpServers'] as Record<string, unknown>) ?? {};\n mcpServers['fenkit'] = fenKitMcpEntry(serverPath);\n config['mcpServers'] = mcpServers;\n\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');\n return { path: configPath, action: 'Updated claude_desktop_config.json' };\n}\n\nexport function setupWindsurf(serverPath: string): { path: string; action: string } {\n const configPath = windsurfConfigPath();\n ensureDir(configPath);\n\n const config = readJsonOrDefault<Record<string, unknown>>(configPath, {});\n const mcpServers = (config['mcpServers'] as Record<string, unknown>) ?? {};\n mcpServers['fenkit'] = fenKitMcpEntry(serverPath);\n config['mcpServers'] = mcpServers;\n\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');\n\n // Append protocol to .windsurfrules if not already present\n const rulesPath = path.join(homeDir, '.windsurfrules');\n const rulesContent = fs.existsSync(rulesPath) ? fs.readFileSync(rulesPath, 'utf-8') : '';\n if (!rulesContent.includes('Fenkit Task Protocol')) {\n fs.appendFileSync(rulesPath, `\\n\\n${FENKIT_MEMORY_PROTOCOL}`, 'utf-8');\n }\n\n return { path: configPath, action: 'Updated ~/.windsurf/mcp.json and ~/.windsurfrules' };\n}\n\nexport function setupCursor(serverPath: string, projectPath?: string): { path: string; action: string } {\n // Project-level config\n const basePath = projectPath ?? process.cwd();\n const configPath = path.join(basePath, '.cursor', 'mcp.json');\n ensureDir(configPath);\n\n const config = readJsonOrDefault<Record<string, unknown>>(configPath, {});\n const mcpServers = (config['mcpServers'] as Record<string, unknown>) ?? {};\n mcpServers['fenkit'] = fenKitMcpEntry(serverPath);\n config['mcpServers'] = mcpServers;\n\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');\n\n // Write .cursor/rules/fenkit.mdc memory protocol\n const rulesDir = path.join(basePath, '.cursor', 'rules');\n if (!fs.existsSync(rulesDir)) {\n fs.mkdirSync(rulesDir, { recursive: true });\n }\n const mdcPath = path.join(rulesDir, 'fenkit.mdc');\n if (!fs.existsSync(mdcPath)) {\n const mdcContent = `---\\nalwaysApply: true\\n---\\n\\n${FENKIT_MEMORY_PROTOCOL}`;\n fs.writeFileSync(mdcPath, mdcContent, 'utf-8');\n }\n\n return { path: configPath, action: `Updated .cursor/mcp.json and .cursor/rules/fenkit.mdc in ${basePath}` };\n}\n\nexport function setupAntigravity(serverPath: string): { path: string; action: string } {\n const configPath = antigravityConfigPath();\n ensureDir(configPath);\n\n const config = readJsonOrDefault<Record<string, unknown>>(configPath, {});\n const mcpServers = (config['mcpServers'] as Record<string, unknown>) ?? {};\n mcpServers['fenkit'] = fenKitMcpEntry(serverPath);\n config['mcpServers'] = mcpServers;\n\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');\n\n // Append protocol to ~/.gemini/GEMINI.md if not already present\n const rulesPath = antigravityRulesPath();\n ensureDir(rulesPath);\n const rulesContent = fs.existsSync(rulesPath) ? fs.readFileSync(rulesPath, 'utf-8') : '';\n if (!rulesContent.includes('Fenkit Task Protocol')) {\n fs.appendFileSync(rulesPath, `\\n\\n${FENKIT_MEMORY_PROTOCOL}`, 'utf-8');\n }\n\n return { path: configPath, action: 'Updated ~/.gemini/antigravity/mcp_config.json and ~/.gemini/GEMINI.md' };\n}\n\nexport function setupCodex(serverPath: string): { path: string; action: string } {\n const configPath = codexConfigPath();\n const instructionsPath = codexInstructionsPath();\n\n ensureDir(configPath);\n\n // Write fenkit-instructions.md\n fs.writeFileSync(instructionsPath, FENKIT_MEMORY_PROTOCOL, 'utf-8');\n\n // Read existing TOML config or start fresh\n let tomlContent = '';\n if (fs.existsSync(configPath)) {\n tomlContent = fs.readFileSync(configPath, 'utf-8');\n }\n\n // Add model_instructions_file if not present\n if (!tomlContent.includes('model_instructions_file')) {\n const header = `model_instructions_file = \"${instructionsPath}\"\\n\\n`;\n tomlContent = header + tomlContent;\n }\n\n // Add [mcp_servers.fenkit] block if not present\n if (!tomlContent.includes('[mcp_servers.fenkit]')) {\n const block = `\\n[mcp_servers.fenkit]\\ncommand = \"node\"\\nargs = [\"${serverPath}\"]\\n`;\n tomlContent += block;\n }\n\n fs.writeFileSync(configPath, tomlContent, 'utf-8');\n return { path: configPath, action: `Updated ${configPath} and wrote ${instructionsPath}` };\n}\n\nexport function setupClaudeCode(serverPath: string): { path: string; action: string } {\n const configPath = claudeCodeConfigPath();\n ensureDir(configPath);\n\n const config = readJsonOrDefault<Record<string, unknown>>(configPath, {});\n const mcpServers = (config['mcpServers'] as Record<string, unknown>) ?? {};\n mcpServers['fenkit'] = fenKitMcpEntry(serverPath);\n config['mcpServers'] = mcpServers;\n\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');\n\n // Write .clauderules in the current project\n const rulesPath = path.join(process.cwd(), '.clauderules');\n let rulesContent = fs.existsSync(rulesPath) ? fs.readFileSync(rulesPath, 'utf-8') : '';\n if (!rulesContent.includes('Fenkit Task Protocol')) {\n rulesContent += `\\n\\n${FENKIT_MEMORY_PROTOCOL}`;\n fs.writeFileSync(rulesPath, rulesContent, 'utf-8');\n }\n\n return { path: configPath, action: 'Updated ~/.claude/config.json and .clauderules' };\n}\n\n// ─── Tool Registration ─────────────────────────────────────────────────────────\n\nexport const setupHandlers: Record<ClientType, (serverPath: string, projectPath?: string) => { path: string; action: string }> = {\n claude: setupClaude,\n windsurf: setupWindsurf,\n cursor: setupCursor,\n antigravity: setupAntigravity,\n codex: setupCodex,\n claudecode: setupClaudeCode,\n};\n\n/**\n * Setup tools — automate client MCP configuration.\n * Supports: Claude Desktop, Cursor, Windsurf, Codex, Antigravity.\n */\nexport function registerSetupTools(server: McpServer): void {\n server.tool(\n 'setup_client',\n 'Configure a supported AI client (Claude Desktop, Cursor, Windsurf, Codex, or Antigravity) to use the Fenkit MCP server. This writes the appropriate config files so you never have to do it manually.',\n {\n client: z\n .enum(['claude', 'cursor', 'windsurf', 'codex', 'antigravity', 'claudecode'])\n .describe(\n 'The AI client to configure. Options: claude (Claude Desktop), cursor (Cursor IDE), windsurf (Windsurf IDE), codex (OpenAI Codex CLI), antigravity (Google Antigravity IDE), claudecode (Claude Code CLI).',\n ),\n path: z\n .string()\n .optional()\n .describe(\n 'Absolute path to a project directory for project-local config (used by Cursor). Defaults to current working directory.',\n ),\n },\n async ({ client, path: projectPath }) => {\n try {\n const serverPath = getServerPath();\n const result = setupHandlers[client](serverPath, projectPath);\n\n const lines = [\n `✅ **Fenkit MCP configured for ${client}**`,\n ``,\n `**Action**: ${result.action}`,\n `**Config path**: \\`${result.path}\\``,\n `**Server**: \\`node ${serverPath}\\``,\n ``,\n `**Next steps**:`,\n `1. Restart ${client === 'claude' ? 'Claude Desktop' : client === 'cursor' ? 'Cursor' : client === 'windsurf' ? 'Windsurf' : client === 'codex' ? 'Codex' : 'Antigravity'} to load the new config.`,\n `2. Run \\`get_status\\` to verify authentication.`,\n `3. Use \\`login_browser\\` with your Fenkit API key if not yet authenticated.`,\n ];\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: 'text' as const, text: `Error setting up ${client}: ${msg}` }],\n isError: true,\n };\n }\n },\n );\n\n // get_setup_instructions — show raw config snippets without touching the filesystem\n server.tool(\n 'get_setup_instructions',\n 'Get manual setup instructions for any supported AI client. Returns the exact JSON/TOML config blocks to copy-paste, without modifying any files. Useful when you want to review before applying.',\n {\n client: z\n .enum(['claude', 'cursor', 'windsurf', 'codex', 'antigravity', 'claudecode'])\n .describe('The AI client you want instructions for.'),\n },\n async ({ client }) => {\n const serverPath = getServerPath();\n const entry = `{\\n \"command\": \"node\",\\n \"args\": [\"${serverPath}\"]\\n}`;\n\n const instructions: Record<string, string> = {\n claude: [\n `**Claude Desktop** — Edit \\`${claudeConfigPath()}\\`:`,\n '```json',\n '{',\n ' \"mcpServers\": {',\n ' \"fenkit\": ' + entry.replace(/\\n/g, '\\n '),\n ' }',\n '}',\n '```',\n ].join('\\n'),\n\n cursor: [\n `**Cursor** — Add to \\`.cursor/mcp.json\\` in your project:`,\n '```json',\n '{',\n ' \"mcpServers\": {',\n ' \"fenkit\": ' + entry.replace(/\\n/g, '\\n '),\n ' }',\n '}',\n '```',\n '',\n 'Also create `.cursor/rules/fenkit.mdc`:',\n '```',\n '---',\n 'alwaysApply: true',\n '---',\n '',\n FENKIT_MEMORY_PROTOCOL,\n '```',\n ].join('\\n'),\n\n windsurf: [\n `**Windsurf** — Edit \\`${windsurfConfigPath()}\\`:`,\n '```json',\n '{',\n ' \"mcpServers\": {',\n ' \"fenkit\": ' + entry.replace(/\\n/g, '\\n '),\n ' }',\n '}',\n '```',\n '',\n 'Also add to `~/.windsurfrules`:',\n '```',\n FENKIT_MEMORY_PROTOCOL,\n '```',\n ].join('\\n'),\n\n antigravity: [\n `**Antigravity** — Edit \\`${antigravityConfigPath()}\\`:`,\n '```json',\n '{',\n ' \"mcpServers\": {',\n ' \"fenkit\": ' + entry.replace(/\\n/g, '\\n '),\n ' }',\n '}',\n '```',\n '',\n 'Also add to `~/.gemini/GEMINI.md`:',\n '```markdown',\n FENKIT_MEMORY_PROTOCOL,\n '```',\n ].join('\\n'),\n\n codex: [\n `**Codex** — Edit \\`${codexConfigPath()}\\`:`,\n '```toml',\n `model_instructions_file = \"${codexInstructionsPath()}\"`,\n '',\n '[mcp_servers.fenkit]',\n 'command = \"node\"',\n `args = [\"${serverPath}\"]`,\n '```',\n '',\n `Also create \\`${codexInstructionsPath()}\\` with the Fenkit protocol:`,\n '```markdown',\n FENKIT_MEMORY_PROTOCOL,\n '```',\n ].join('\\n'),\n claudecode: [\n `**Claude Code** — Edit \\`${claudeCodeConfigPath()}\\`:`,\n '```json',\n '{',\n ' \"mcpServers\": {',\n ' \"fenkit\": ' + entry.replace(/\\n/g, '\\n '),\n ' }',\n '}',\n '```',\n '',\n 'Also add to `.clauderules` in your project root:',\n '```markdown',\n FENKIT_MEMORY_PROTOCOL,\n '```',\n ].join('\\n'),\n };\n\n return {\n content: [{ type: 'text' as const, text: instructions[client] }],\n };\n },\n );\n\n // native MCP prompt for instructions\n server.prompt(\n 'task-protocol',\n 'Get the Fenkit Task Protocol instructions for AI agents. Use this to understand how to interact with Fenkit tools autonomously.',\n {},\n () => ({\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: FENKIT_MEMORY_PROTOCOL,\n },\n },\n ],\n }),\n );\n}\n"],"mappings":"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","names":["server","z","server","loadConfig","z","z","os","server","z","z","z","server","z","z","fs","path","os","server","client","client"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fenkit-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Fenkit MCP Server — LLM-native task coordination layer",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"bin": {
|
|
11
|
+
"fenkit-mcp": "dist/index.js",
|
|
12
|
+
"fnk": "dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsup",
|
|
16
|
+
"dev": "tsup --watch",
|
|
17
|
+
"start": "node dist/index.js",
|
|
18
|
+
"lint": "eslint src"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"mcp",
|
|
22
|
+
"fenkit",
|
|
23
|
+
"llm",
|
|
24
|
+
"tasks"
|
|
25
|
+
],
|
|
26
|
+
"author": "FENKIT APP",
|
|
27
|
+
"license": "ISC",
|
|
28
|
+
"homepage": "https://github.com/DiegoEDG/fenkit-mcp",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/DiegoEDG/fenkit-mcp"
|
|
32
|
+
},
|
|
33
|
+
"packageManager": "pnpm@10.7.1",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
36
|
+
"axios": "^1.13.6",
|
|
37
|
+
"dotenv": "^16.5.0",
|
|
38
|
+
"open": "^11.0.0",
|
|
39
|
+
"zod": "^4.3.6"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@eslint/js": "^10.0.1",
|
|
43
|
+
"@types/node": "^25.5.0",
|
|
44
|
+
"eslint": "^10.1.0",
|
|
45
|
+
"globals": "^17.4.0",
|
|
46
|
+
"tsup": "^8.5.1",
|
|
47
|
+
"typescript": "^6.0.2",
|
|
48
|
+
"typescript-eslint": "^8.57.2"
|
|
49
|
+
}
|
|
50
|
+
}
|