Update Environment
update_environmentUpdate an environment's name, URL, or description by providing its UUID. Only specified fields change; others remain untouched. Returns the updated environment object or an error if the UUID does not exist.
Instructions
Patch an environment by UUID. Only specified fields (name, url, description) change — other fields are left intact. Returns {updated: true, environment: {...}} with the updated resource. Defaults to the project resolved from the current git repo; pass projectUuid to target a different project. Returns isError:true with NotFound when the uuid doesn't exist.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| uuid | Yes | UUID of the environment to update. Required. | |
| name | No | Optional: new name. | |
| url | No | Optional: new base URL. | |
| description | No | Optional: new description. | |
| projectUuid | No | Optional: UUID of the target project. Defaults to git-auto-detect. |
Implementation Reference
- Main handler function that executes the update_environment tool logic. It patches environment fields (name/url/description), and handles credential sub-actions: remove, update, add. Resolves projectUuid via git repo detection if not provided. Returns structured response with updated environment and credential changes.
export async function updateEnvironmentHandler( input: UpdateEnvironmentInput, _context: ToolContext, ): Promise<ToolResponse> { const start = Date.now(); logger.toolStart('update_environment', { uuid: input.uuid, hasEnvPatch: !!(input.name || input.url || input.description), addCount: input.addCredentials?.length ?? 0, updateCount: input.updateCredentials?.length ?? 0, removeCount: input.removeCredentialIds?.length ?? 0, projectUuid: input.projectUuid, }); try { const client = new DebuggAIServerClient(config.api.key); await client.init(); let projectUuid = input.projectUuid; if (!projectUuid) { const repoName = detectRepoName(); if (!repoName) return notFound(input.uuid, 'no git repo detected and no projectUuid provided'); const project = await client.findProjectByRepoName(repoName); if (!project) return notFound(input.uuid, `no project found for repo "${repoName}"`); projectUuid = project.uuid; } // ── Env field patch (only if any env field is present) ────────────────── const hasEnvPatch = input.name !== undefined || input.url !== undefined || input.description !== undefined; let environment: any = null; if (hasEnvPatch) { try { environment = await client.updateEnvironment(projectUuid, input.uuid, { name: input.name, url: input.url, description: input.description, }); } catch (err: any) { if (err?.statusCode === 404 || err?.response?.status === 404) { return notFound(input.uuid, `backend returned 404 for project ${projectUuid}`); } throw err; } } else { // Echo the uuid so the response shape stays consistent. Include projectUuid // for downstream tooling. Only populate `environment` if we patched. environment = { uuid: input.uuid }; } // ── Cred sub-actions (remove → update → add) ──────────────────────────── const warnings: Array<{ op: 'add' | 'update' | 'remove'; label?: string; uuid?: string; error: string }> = []; const addedCredentials: SafeCredential[] = []; const updatedCredentials: SafeCredential[] = []; const removedCredentialIds: string[] = []; if (input.removeCredentialIds) { for (const credUuid of input.removeCredentialIds) { try { await client.deleteCredential(projectUuid, input.uuid, credUuid); removedCredentialIds.push(credUuid); } catch (err: any) { warnings.push({ op: 'remove', uuid: credUuid, error: err?.message ?? String(err) }); } } } if (input.updateCredentials) { for (const patch of input.updateCredentials) { try { const updated = await client.updateCredential( projectUuid, input.uuid, patch.uuid, { label: patch.label, username: patch.username, password: patch.password, role: patch.role, }, ); updatedCredentials.push(stripPassword(updated)); } catch (err: any) { warnings.push({ op: 'update', uuid: patch.uuid, error: err?.message ?? String(err) }); } } } if (input.addCredentials) { for (const seed of input.addCredentials) { try { const cred = await client.createCredential(projectUuid, input.uuid, { label: seed.label, username: seed.username, password: seed.password, role: seed.role, }); addedCredentials.push(stripPassword(cred)); } catch (err: any) { warnings.push({ op: 'add', label: seed.label, error: err?.message ?? String(err) }); } } } // ── Build response ────────────────────────────────────────────────────── const payload: Record<string, any> = { updated: hasEnvPatch, environment, }; if (addedCredentials.length > 0) payload.addedCredentials = addedCredentials; if (updatedCredentials.length > 0) payload.updatedCredentials = updatedCredentials; if (removedCredentialIds.length > 0) payload.removedCredentialIds = removedCredentialIds; if (warnings.length > 0) payload.credentialWarnings = warnings; logger.toolComplete('update_environment', Date.now() - start); return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] }; } catch (error) { logger.toolError('update_environment', error as Error, Date.now() - start); throw handleExternalServiceError(error, 'DebuggAI', 'update_environment'); } } - types/index.ts:112-122 (schema)Zod schema and inferred TypeScript type for UpdateEnvironmentInput. Defines input shape: uuid (required), optional name/url/description/projectUuid, plus credential mutation arrays (addCredentials, updateCredentials, removeCredentialIds).
export const UpdateEnvironmentInputSchema = z.object({ uuid: z.string().uuid(), name: z.string().min(1).optional(), url: z.string().url().optional(), description: z.string().optional(), projectUuid: z.string().uuid().optional(), addCredentials: z.array(CredentialSeedSchema).optional(), updateCredentials: z.array(CredentialUpdateSchema).optional(), removeCredentialIds: z.array(z.string().uuid()).optional(), }).strict(); export type UpdateEnvironmentInput = z.infer<typeof UpdateEnvironmentInputSchema>; - tools/index.ts:24-59 (registration)Tool registration: buildUpdateEnvironmentTool() and buildValidatedUpdateEnvironmentTool() are called in initTools() to register update_environment in the tool registry.
export function initTools(ctx: ProjectContext | null): void { const tools: Tool[] = [ buildTestPageChangesTool(ctx), buildTriggerCrawlTool(ctx), buildProbePageTool(), buildSearchProjectsTool(), buildSearchEnvironmentsTool(), buildCreateEnvironmentTool(), buildUpdateEnvironmentTool(), buildDeleteEnvironmentTool(), buildUpdateProjectTool(), buildDeleteProjectTool(), buildSearchExecutionsTool(), buildCreateProjectTool(), ]; const validated: ValidatedTool[] = [ buildValidatedTestPageChangesTool(ctx), buildValidatedTriggerCrawlTool(ctx), buildValidatedProbePageTool(), buildValidatedSearchProjectsTool(), buildValidatedSearchEnvironmentsTool(), buildValidatedCreateEnvironmentTool(), buildValidatedUpdateEnvironmentTool(), buildValidatedDeleteEnvironmentTool(), buildValidatedUpdateProjectTool(), buildValidatedDeleteProjectTool(), buildValidatedSearchExecutionsTool(), buildValidatedCreateProjectTool(), ]; _tools = tools; _validatedTools = validated; toolRegistry.clear(); for (const v of validated) toolRegistry.set(v.name, v); } - services/index.ts:337-359 (helper)Service-layer helper method that calls the backend API (PATCH api/v1/projects/{projectUuid}/environments/{envUuid}/) to update environment fields.
public async updateEnvironment( projectUuid: string, envUuid: string, patch: { name?: string; url?: string; description?: string }, ): Promise<{ uuid: string; name: string; url: string; isActive: boolean; description: string | null; endpointType: string }> { if (!this.tx) throw new Error('Client not initialized — call init() first'); const body: Record<string, any> = {}; if (patch.name !== undefined) body.name = patch.name; if (patch.url !== undefined) body.url = patch.url; if (patch.description !== undefined) body.description = patch.description; const e = await this.tx.patch<any>( `api/v1/projects/${projectUuid}/environments/${envUuid}/`, body, ); return { uuid: envUuid, // echo from input; backend PATCH response omits it name: e.name, url: e.url ?? '', isActive: e.isActive, description: e.description ?? null, endpointType: e.endpointType, }; } - tools/updateEnvironment.ts:7-30 (registration)Tool definition file: buildUpdateEnvironmentTool() constructs the Tool object with name 'update_environment', description, and inputSchema. buildValidatedUpdateEnvironmentTool() wraps it with Zod schema and handler.
export function buildUpdateEnvironmentTool(): Tool { return { name: 'update_environment', title: 'Update Environment', description: DESCRIPTION, inputSchema: { type: 'object', properties: { uuid: { type: 'string', description: 'UUID of the environment to update. Required.' }, name: { type: 'string', description: 'Optional: new name.', minLength: 1 }, url: { type: 'string', description: 'Optional: new base URL.' }, description: { type: 'string', description: 'Optional: new description.' }, projectUuid: { type: 'string', description: 'Optional: UUID of the target project. Defaults to git-auto-detect.' }, }, required: ['uuid'], additionalProperties: false, }, }; } export function buildValidatedUpdateEnvironmentTool(): ValidatedTool { const tool = buildUpdateEnvironmentTool(); return { ...tool, inputSchema: UpdateEnvironmentInputSchema, handler: updateEnvironmentHandler }; }