wiki_update_page
Update or create Azure DevOps wiki pages by specifying the organization, project, wiki ID, path, and content in Markdown format.
Instructions
Update content of an existing wiki page or create a new page if it does not exist
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | New page content (Markdown) | |
| organization | No | Azure DevOps organization name | |
| path | Yes | Page path or page ID | |
| project | No | Project name | |
| wikiId | Yes | Wiki identifier |
Input Schema (JSON Schema)
{
"properties": {
"content": {
"description": "New page content (Markdown)",
"type": "string"
},
"organization": {
"description": "Azure DevOps organization name",
"type": "string"
},
"path": {
"description": "Page path or page ID",
"type": "string"
},
"project": {
"description": "Project name",
"type": "string"
},
"wikiId": {
"description": "Wiki identifier",
"type": "string"
}
},
"required": [
"wikiId",
"path",
"content"
],
"type": "object"
}
Implementation Reference
- src/azure-client.ts:284-395 (handler)Core handler function that performs the actual wiki page update/create using Azure DevOps Wiki REST API, handling existence check, versioning, and error handling.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/server.ts:289-310 (handler)MCP server tool handler for 'wiki_update_page' that validates input using schema and delegates to AzureDevOpsWikiClient.updatePageprivate 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/server.ts:108-137 (registration)Registration of the 'wiki_update_page' tool in the MCP server's tool list, including 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'] } },
- src/types.ts:24-30 (schema)Zod schema definition for WikiUpdatePageRequest used for input validation in the tool handler.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(), });