zed.mcp
Version:
MCP server for project analysis, AI rules reading, and dependency checking
87 lines (79 loc) • 2.12 kB
text/typescript
import { z } from "zod";
import path from "path";
import type { ToolDefinition, ToolHandler, ToolResponse } from "../types/index";
import {
getIgnorePatterns,
buildStructureString,
isDirectory,
} from "../utils/index";
/**
* Input schema for project structure tool
*/
const ProjectStructureInput = z.object({
projectPath: z
.string()
.describe("The absolute path to the project root directory."),
});
type ProjectStructureParams = z.infer<typeof ProjectStructureInput>;
/**
* Tool definition for showing project structure
*/
export const projectStructureDefinition: ToolDefinition = {
name: "show-project-structure",
title: "Show Project Structure",
description:
"Recursively lists files and directories in a project, respecting .gitignore and other common exclusions for LLMs.",
inputSchema: {
projectPath: ProjectStructureInput.shape.projectPath,
},
};
/**
* Handler for showing project structure
*/
export const projectStructureHandler: ToolHandler<ProjectStructureParams> = async ({
projectPath,
}): Promise<ToolResponse> => {
try {
const isDirValid = await isDirectory(projectPath);
if (!isDirValid) {
return {
content: [
{
type: "text",
text: "Error: The provided path is not a directory.",
},
],
isError: true,
};
}
const ignorePatterns = await getIgnorePatterns(projectPath);
const structure = await buildStructureString(
projectPath,
projectPath,
ignorePatterns,
);
if (!structure) {
return {
content: [
{
type: "text",
text: "Project is empty or all files are ignored.",
},
],
};
}
return {
content: [{ type: "text", text: structure.trim() }],
};
} catch (error: any) {
return {
content: [
{
type: "text",
text: `An unexpected error occurred: ${error.message}`,
},
],
isError: true,
};
}
};