list_projects
Retrieve all logged conversation projects to track AI-developer interactions, with optional statistics for analysis and continuity management.
Instructions
List all projects with optional statistics
Tool call template
This tool declares no required parameters. Add optional parameters from the input schema as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {},
"name": "list_projects"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| includeStats | No | Include statistics for each project |
Implementation Reference
- src/tools/conversationLogger.ts:240-296 (handler)Main tool handler: validates input with validateListProjects, lists projects via fileManager.listProjects(), optionally computes stats with getProjectStats, and returns formatted markdown response.
async listProjects(params: unknown): Promise<{ content: Array<{ type: string; text: string }> }> { try { const validatedParams = validateListProjects(params); const { includeStats } = validatedParams; const projects = await this.fileManager.listProjects(); if (projects.length === 0) { return { content: [ { type: 'text', text: '📁 暂无项目记录。\n\n使用 log_conversation 工具开始记录对话到新项目。' } ] }; } let result = `📁 共找到 ${projects.length} 个项目:\n\n`; if (includeStats) { for (const project of projects) { const stats = await this.getProjectStats(project); result += `## ${stats.name}\n`; result += `- 总对话数: ${stats.totalConversations}\n`; result += `- 最后活动: ${stats.lastActivity}\n`; result += `- 支持平台: ${stats.platforms.join(', ') || '无'}\n`; result += `- 常用标签: ${stats.tags.slice(0, 5).join(', ') || '无'}\n\n`; } } else { projects.forEach(project => { result += `- ${project}\n`; }); } return { content: [ { type: 'text', text: result } ] }; } catch (error) { const errorMessage = error instanceof ValidationError ? `参数验证失败: ${error.message}` : `获取项目列表时出错: ${String(error)}`; return { content: [ { type: 'text', text: `❌ ${errorMessage}` } ] }; } } - src/validation/schemas.ts:63-65 (schema)Zod schema definition for list_projects input parameters.
export const ListProjectsSchema = z.object({ includeStats: z.boolean().optional().default(false) }); - src/index.ts:170-171 (registration)Tool dispatch/registration in the CallToolRequest handler switch statement.
case 'list_projects': return await this.conversationLogger.listProjects(args || {}); - src/index.ts:139-151 (registration)Tool metadata registration (name, description, inputSchema) in the ListToolsRequest handler.
name: 'list_projects', description: 'List all projects with optional statistics', inputSchema: { type: 'object', properties: { includeStats: { type: 'boolean', description: 'Include statistics for each project', default: false } } } } - src/storage/fileManager.ts:124-159 (helper)Core utility method that lists projects by checking registry, current project, or scanning projects directory.
async listProjects(): Promise<string[]> { // For the new design, we primarily work with the current project // But we can also scan the global registry for known projects const registryPath = join(this.getIndexDir(), 'projects-registry.json'); try { const registryContent = await this.readFile(registryPath); if (registryContent) { const registry = JSON.parse(registryContent); return Object.keys(registry); } } catch { // Registry doesn't exist or is corrupted } // If no registry, return current project if detected const projectInfo = await this.getProjectInfo(); if (projectInfo.root) { return [projectInfo.name]; } // Fallback: scan home config directory try { const projectsDir = join(this.homeConfigDir, 'projects'); const entries = await fs.readdir(projectsDir, { withFileTypes: true }); return entries .filter(entry => entry.isDirectory()) .map(entry => entry.name); } catch (error) { if ((error as { code?: string }).code === 'ENOENT') { return []; } const projectsDir = join(this.homeConfigDir, 'projects'); throw new FileOperationError(`Failed to list projects`, projectsDir, 'readdir'); } }