Skip to main content
Glama

update_project

Modify a project's knowledge graph data or structure diagram using its unique slug to update information and visual representations.

Instructions

Updates a project's knowledge graph data and/or its structure diagram (in Mermaid.js format). The project is identified by its unique 'slug'. At least one of 'project_knowledge' or 'project_diagram' must be provided for an update to occur.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
slugYes
project_knowledgeNo
project_diagramNo

Implementation Reference

  • Core handler function that executes the tool logic: validates input, calls SecureApiClient.put to update project data via /project/slug/{slug}, handles responses and errors.
    async execute(input: UpdateProjectInput): Promise<unknown> {
      logger.info('Executing update-project tool', input);
    
      try {
        // Use the injected API client to update project
        if (!this.apiClient) {
          throw new Error('API client not available - tool not properly initialized');
        }
    
        // Extract project slug
        const { slug, ...updateData } = input;
        
        // Update project using the API endpoint
        const url = `/project/slug/${slug.toUpperCase()}`;
        logger.debug(`Making PUT request to: ${url}`);
        
        const responseData = await this.apiClient.put<UpdateProjectApiResponse>(url, updateData) as unknown as UpdateProjectApiResponse;
    
        if (!responseData.success) {
          const apiErrorMessage = responseData.message || 'API reported update failure without a specific message.';
          logger.warn(`Update project API call for ${slug} returned success:false. Message: ${apiErrorMessage}`);
          return {
            isError: true,
            content: [{ type: "text", text: `Update for project ${slug} failed: ${apiErrorMessage}` }]
          };
        }
    
        // At this point, responseData.success is true
        const updatedFieldsList = Object.keys(updateData).join(', ') || 'no specific fields (refresh)';
        const apiMessage = responseData.message || 'Project successfully updated.';
    
        if (responseData.project) {
          const diagramFromResponse = responseData.project.project_diagram; // snake_case access
    
          return {
            slug: responseData.project.slug,
            name: responseData.project.name, 
            description: responseData.project.description, 
            project_knowledge: responseData.project.project_knowledge || {}, // snake_case access and output
            project_diagram: diagramFromResponse || '', // Use the new variable (already snake_case)
            updateConfirmation: `Project ${responseData.project.slug} updated fields: ${updatedFieldsList}. API: ${apiMessage}`
          };
        } else {
          // responseData.success is true, but responseData.project is missing.
          logger.warn(`Update project API call for ${slug} succeeded but returned no project data. API message: ${apiMessage}`);
          return {
            slug: slug, 
            name: '', 
            description: '', 
            project_knowledge: input.project_knowledge || {}, // Input is snake_case from Zod schema
            project_diagram: input.project_diagram || '',   // Input is snake_case from Zod schema
            updateConfirmation: `Project ${slug} update reported success by API, but full project details were not returned. Attempted to update fields: ${updatedFieldsList}. API: ${apiMessage}`
          };
        }
      } catch (error) {
        let errorMessage = (error instanceof Error) ? error.message : 'An unknown error occurred';
        logger.error(`Error in update-project tool: ${errorMessage}`, error instanceof Error ? error : undefined);
    
        if (error instanceof Error && (error as any).status === 404) {
           errorMessage = `Project with slug '${input.slug}' not found.`;
        } else if (error instanceof Error && error.message.includes('not found')) { // Fallback for other not found indications
           errorMessage = `Project with slug '${input.slug}' not found or update failed.`;
        }
        
        return {
          isError: true,
          content: [{ type: "text", text: errorMessage }]
        };
      }
    }
  • Zod schema for update_project tool input validation, including slug (required), project_knowledge and project_diagram (at least one required), with detailed constraints.
    const UpdateProjectSchema = z.object({
      // Required field to identify the project
      slug: z.string({
        required_error: "Project slug is required to identify the project",
        invalid_type_error: "Project slug must be a string"
      })
      .regex(/^[A-Za-z]{3}$/, { message: "Project slug must be three letters (e.g., CRD or crd). Case insensitive." })
      .describe("Project slug to identify the project to update (case insensitive)"),
      
      // Optional fields that can be updated with security constraints
      project_knowledge: ProjectKnowledgeSchema.optional().describe("Project knowledge graph data (structured JSON object with size limits)"),
      project_diagram: z.string()
        .max(15000, "Project diagram cannot exceed 15000 characters")
        .optional()
        .describe("Project structure diagram (Mermaid.js format)"),
    }).strict().refine(
      // Ensure at least one field to update is provided
      (data) => {
        const updateFields = ['project_knowledge', 'project_diagram'];
        return updateFields.some(field => field in data);
      },
      {
        message: 'At least one field to update must be provided',
        path: ['updateFields']
      }
    );
  • src/index.ts:315-330 (registration)
    Registration of UpdateProjectTool instance with SecureApiClient in the production MCP server, added to tools array and registered via tool.register(server).
    const tools: any[] = [
      new StartProjectTool(secureApiClient),
      new GetPromptTool(secureApiClient),
      new GetTaskTool(secureApiClient),
      new GetProjectTool(secureApiClient),
      new UpdateTaskTool(secureApiClient),
      new UpdateProjectTool(secureApiClient),
      new ListProjectsTool(secureApiClient),
      new ListTasksTool(secureApiClient),
      new NextTaskTool(secureApiClient),
    ];
    
    // Register each tool with the server
    tools.forEach(tool => {
      tool.register(server);
    });
  • Supporting schema for project_knowledge field, defining flexible structure for components, dependencies, technologies, architecture, etc., with size limits.
    const ProjectKnowledgeSchema = z.object({
      // Core project information - flexible to support both strings and objects
      components: z.array(
        z.union([
          z.string().max(500, "Component description too long"),
          z.object({
            name: z.string().max(100, "Component name too long"),
            type: z.string().max(50, "Component type too long").optional(),
            status: z.string().max(50, "Component status too long").optional(),
            description: z.string().max(500, "Component description too long").optional(),
          }).passthrough() // Allow additional properties
        ])
      ).max(50, "Too many components").optional(),
      
      dependencies: z.array(
        z.union([
          z.string().max(500, "Dependency description too long"),
          z.object({
            name: z.string().max(100, "Dependency name too long"),
            version: z.string().max(50, "Dependency version too long").optional(),
            purpose: z.string().max(500, "Dependency purpose too long").optional(),
          }).passthrough()
        ])
      ).max(50, "Too many dependencies").optional(),
      
      technologies: z.array(
        z.union([
          z.string().max(500, "Technology description too long"), // Increased from 50 to 500
          z.object({
            name: z.string().max(100, "Technology name too long"),
            type: z.string().max(50, "Technology type too long").optional(),
            purpose: z.string().max(500, "Technology purpose too long").optional(),
            version: z.string().max(50, "Technology version too long").optional(),
          }).passthrough()
        ])
      ).max(30, "Too many technologies").optional(), // Increased from 20 to 30
      
      // Architecture and design
      architecture: z.string().max(3000, "Architecture description too long").optional(), // Increased from 2000
      patterns: z.array(
        z.union([
          z.string().max(200, "Pattern description too long"), // Increased from 100
          z.object({
            name: z.string().max(100, "Pattern name too long"),
            description: z.string().max(500, "Pattern description too long").optional(),
          }).passthrough()
        ])
      ).max(30, "Too many patterns").optional(), // Increased from 20
      
      // Documentation and notes
      notes: z.string().max(10000, "Notes too long").optional(), // Increased from 5000
      links: z.array(z.string().url("Invalid URL format").max(500, "URL too long")).max(20, "Too many links").optional(), // Increased from 10
      
      // Custom metadata (controlled) - more flexible
      metadata: z.record(
        z.union([
          z.string().max(1000, "Metadata value too long"), // Increased from 500
          z.object({}).passthrough() // Allow objects in metadata
        ])
      ).optional(),
    }).passthrough(); // Allow additional properties for maximum flexibility

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/PixdataOrg/coderide-mcp'

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