wiki_update_page
Update content of an existing Azure DevOps wiki page or create a new page if it does not exist.
Instructions
Update content of an existing wiki page or create a new page if it does not exist
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| organization | No | Azure DevOps organization name | |
| project | No | Project name | |
| wikiId | Yes | Wiki identifier | |
| path | Yes | Page path or page ID | |
| content | Yes | New page content (Markdown) |
Implementation Reference
- src/server.ts:289-310 (handler)Handler function `handleUpdatePage` that parses request via `WikiUpdatePageRequestSchema`, validates org/project, calls `AzureDevOpsWikiClient.updatePage()`, and returns the result.
private async handleUpdatePage(args: any) { const request = WikiUpdatePageRequestSchema.parse(args); const organization = request.organization || this.config.defaultOrganization; const project = request.project || this.config.defaultProject; if (!organization) { throw new Error('Organization is required either as parameter or in server configuration'); } if (!project) { throw new Error('Project is required either as parameter or in server configuration'); } const client = await this.getClient(organization, project); const result = await client.updatePage(request); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } - src/azure-client.ts:284-395 (handler)Core implementation of `updatePage()` method on `AzureDevOpsWikiClient`. Checks if the page exists (to get version for If-Match header), then does a PUT request to the Azure DevOps Wiki REST API to update or create the page.
async updatePage(request: WikiUpdatePageRequest): Promise<WikiPageUpdateResult> { if (!this.wikiApi || !this.connection) { throw new Error('Azure DevOps client not initialized'); } try { const organization = request.organization || this.config.organization; const project = request.project || this.config.project; if (!organization || !project) { throw new Error('Organization and project must be provided'); } // Set encoded pagePath const encodedPath = encodeURIComponent(request.path); // Get wiki object const wiki = await this.wikiApi.getWiki(request.wikiId, project); // Fix: Access the first element of versions array safely and get its version property const wikiVersion = Array.isArray(wiki.versions) && wiki.versions.length > 0 ? wiki.versions[0].version : 'wikiMaster'; // First, check if page exists to get version for updates let pageVersion: string | undefined; let pageExists = false; try { let wikiPageResponse = await this.wikiApi.http.get(`${wiki.url}/pages?path=${encodedPath}`); if (wikiPageResponse.message && wikiPageResponse.message.statusCode === 200) { pageExists = true; pageVersion = wikiPageResponse.message.headers.etag; } } catch (checkError) { // Page doesn't exist, we'll create it pageExists = false; } // Create headers object with proper typing const headers: { [key: string]: string } = { 'Content-Type': 'application/json' }; // Only add If-Match header if page exists and we have a version // For new pages, don't include If-Match header if (pageExists && pageVersion) { headers['If-Match'] = pageVersion; } const requestBody = { content: request.content }; // TODO: Add versionDescriptor.versionType and versionDescriptor.version as optional environment variables const apiUrl = `${wiki.url}/pages?path=${encodedPath}&api-version=7.1&versionDescriptor.versionType=branch&versionDescriptor.version=${wikiVersion}`; const response = await this.wikiApi.http.put(apiUrl, JSON.stringify(requestBody), headers); if (!response.message || (response.message.statusCode !== 200 && response.message.statusCode !== 201)) { // Enhanced error information for debugging const errorDetails: { statusCode: number | undefined; statusMessage: string | undefined; headers: { [key: string]: string | string[] | undefined } | undefined; url: string; requestHeaders: { [key: string]: string }; requestBody: { content: string }; pageExists: boolean; pageVersion: string | undefined; responseBody?: string; } = { statusCode: response.message?.statusCode, statusMessage: response.message?.statusMessage, headers: response.message?.headers, url: apiUrl, requestHeaders: headers, requestBody: requestBody, pageExists, pageVersion }; throw new Error(`Failed to ${pageExists ? 'update' : 'create'} page: HTTP ${response.message?.statusCode || 'Unknown'}. Details: ${JSON.stringify(errorDetails, null, 2)}`); } const responseBody = await response.readBody(); if (!responseBody) { throw new Error('Empty response body'); } const data = JSON.parse(responseBody); // Handle the response structure let pageData = data.value || data; if (!pageData || pageData === null || (data.value !== undefined && data.value === null)) { throw new Error(`Failed to ${pageExists ? 'update' : 'create'} page: ${request.path}`); } return { id: pageData.id?.toString() || '', path: pageData.path || request.path, title: pageData.path ? pageData.path.split('/').pop() || '' : '', version: pageData.version || response.message.headers.etag || '', isParentPage: pageData.isParentPage || false, order: pageData.order || 0, gitItemPath: pageData.gitItemPath || '' }; } catch (error) { throw new Error(`Failed to update page: ${error instanceof Error ? error.message : String(error)}`); } } - src/types.ts:24-30 (schema)Zod schema `WikiUpdatePageRequestSchema` defining the input fields: organization (optional), project (optional), wikiId (required), path (required), content (required).
export const WikiUpdatePageRequestSchema = z.object({ organization: z.string().min(1).optional(), project: z.string().min(1).optional(), wikiId: z.string().min(1), path: z.string().min(1), content: z.string(), }); - src/types.ts:72-80 (schema)Return type `WikiPageUpdateResult` interface with fields: id, path, title, version, isParentPage, order, gitItemPath.
export interface WikiPageUpdateResult { id: string; path: string; title: string; version: string; isParentPage: boolean; order: number; gitItemPath: string; } - src/server.ts:108-137 (registration)Registration of `wiki_update_page` tool in the `ListToolsRequestSchema` handler with name, description, and input schema definition.
{ name: 'wiki_update_page', description: 'Update content of an existing wiki page or create a new page if it does not exist', inputSchema: { type: 'object', properties: { organization: { type: 'string', description: 'Azure DevOps organization name' }, project: { type: 'string', description: 'Project name' }, wikiId: { type: 'string', description: 'Wiki identifier' }, path: { type: 'string', description: 'Page path or page ID' }, content: { type: 'string', description: 'New page content (Markdown)' } }, required: ['wikiId', 'path', 'content'] } },