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
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states this is an update operation (implying mutation) and mentions the 'at least one field required' constraint, but doesn't disclose other important behaviors like authentication requirements, error conditions, whether updates are reversible, or what happens to unspecified fields. For a mutation tool with zero annotation coverage, this leaves significant gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste. The first sentence states the purpose and parameters, the second specifies the required constraint. Every word earns its place, and the most critical information (what it does and the constraint) is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given this is a mutation tool with no annotations and no output schema, the description provides adequate basic information about what can be updated and the required constraint. However, it lacks details about the update's effects, error handling, or return values, which would be important for a tool that modifies data. The description is minimally complete but has clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description must compensate for the schema's lack of parameter documentation. It explains that 'slug' identifies the project, 'project_knowledge' contains knowledge graph data, and 'project_diagram' contains Mermaid.js format structure diagrams. It also clarifies the 'at least one required' constraint between the two data fields, adding significant value beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Updates') and the resource ('project's knowledge graph data and/or its structure diagram'), specifying both content types. It distinguishes this from sibling tools like 'get_project' (read-only) and 'start_project' (initial creation).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool: when updating a project identified by slug, with at least one of the two data fields provided. It doesn't explicitly mention when not to use it or name alternatives like 'start_project' for creation, but the context is sufficient for basic usage decisions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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