Skip to main content
Glama
Tiberriver256

Azure DevOps MCP Server

search_wiki

Search for content across wiki pages in Azure DevOps projects to find specific information quickly.

Instructions

Search for content across wiki pages in a project

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
searchTextYesThe text to search for in wikis
organizationIdNoThe ID or name of the organization (Default: mycompany)
projectIdNoThe ID or name of the project to search in (Default: MyProject). If not provided, the default project will be used.
filtersNoOptional filters to narrow search results
topNoNumber of results to return (default: 100, max: 1000)
skipNoNumber of results to skip for pagination (default: 0)
includeFacetsNoWhether to include faceting in results (default: true)

Implementation Reference

  • Core handler function that executes the wiki search using the Azure DevOps ALM search API, handling authentication, request preparation, and error wrapping.
    export async function searchWiki(
      connection: WebApi,
      options: SearchWikiOptions,
    ): Promise<WikiSearchResponse> {
      try {
        // Prepare the search request
        const searchRequest: WikiSearchRequest = {
          searchText: options.searchText,
          $skip: options.skip,
          $top: options.top,
          filters: options.projectId
            ? {
                Project: [options.projectId],
              }
            : {},
          includeFacets: options.includeFacets,
        };
    
        // Add custom filters if provided
        if (
          options.filters &&
          options.filters.Project &&
          options.filters.Project.length > 0
        ) {
          if (!searchRequest.filters) {
            searchRequest.filters = {};
          }
    
          if (!searchRequest.filters.Project) {
            searchRequest.filters.Project = [];
          }
    
          searchRequest.filters.Project = [
            ...(searchRequest.filters.Project || []),
            ...options.filters.Project,
          ];
        }
    
        // Get the authorization header from the connection
        const authHeader = await getAuthorizationHeader();
    
        // Extract organization and project from the connection URL
        const { organization, project } = extractOrgAndProject(
          connection,
          options.projectId,
        );
    
        // Make the search API request
        // If projectId is provided, include it in the URL, otherwise perform organization-wide search
        const searchUrl = options.projectId
          ? `https://almsearch.dev.azure.com/${organization}/${project}/_apis/search/wikisearchresults?api-version=7.1`
          : `https://almsearch.dev.azure.com/${organization}/_apis/search/wikisearchresults?api-version=7.1`;
    
        const searchResponse = await axios.post<WikiSearchResponse>(
          searchUrl,
          searchRequest,
          {
            headers: {
              Authorization: authHeader,
              'Content-Type': 'application/json',
            },
          },
        );
    
        return searchResponse.data;
      } catch (error) {
        // If it's already an AzureDevOpsError, rethrow it
        if (error instanceof AzureDevOpsError) {
          throw error;
        }
    
        // Handle axios errors
        if (axios.isAxiosError(error)) {
          const status = error.response?.status;
          const message = error.response?.data?.message || error.message;
    
          if (status === 404) {
            throw new AzureDevOpsResourceNotFoundError(
              `Resource not found: ${message}`,
            );
          } else if (status === 400) {
            throw new AzureDevOpsValidationError(
              `Invalid request: ${message}`,
              error.response?.data,
            );
          } else if (status === 401 || status === 403) {
            throw new AzureDevOpsPermissionError(`Permission denied: ${message}`);
          } else {
            // For other axios errors, wrap in a generic AzureDevOpsError
            throw new AzureDevOpsError(`Azure DevOps API error: ${message}`);
          }
    
          // This return is never reached but helps TypeScript understand the control flow
          return null as never;
        }
    
        // Otherwise, wrap it in a generic error
        throw new AzureDevOpsError(
          `Failed to search wiki: ${error instanceof Error ? error.message : String(error)}`,
        );
      }
    }
  • Zod schema for validating input arguments to the search_wiki tool.
    export const SearchWikiSchema = z.object({
      searchText: z.string().describe('The text to search for in wikis'),
      organizationId: z
        .string()
        .optional()
        .describe(`The ID or name of the organization (Default: ${defaultOrg})`),
      projectId: z
        .string()
        .optional()
        .describe(
          `The ID or name of the project to search in (Default: ${defaultProject}). If not provided, the default project will be used.`,
        ),
      filters: z
        .object({
          Project: z
            .array(z.string())
            .optional()
            .describe('Filter by project names'),
        })
        .optional()
        .describe('Optional filters to narrow search results'),
      top: z
        .number()
        .int()
        .min(1)
        .max(1000)
        .default(100)
        .describe('Number of results to return (default: 100, max: 1000)'),
      skip: z
        .number()
        .int()
        .min(0)
        .default(0)
        .describe('Number of results to skip for pagination (default: 0)'),
      includeFacets: z
        .boolean()
        .default(true)
        .describe('Whether to include faceting in results (default: true)'),
    });
  • ToolDefinition object registering the search_wiki tool with its name, description, and input schema.
    {
      name: 'search_wiki',
      description: 'Search for content across wiki pages in a project',
      inputSchema: zodToJsonSchema(SearchWikiSchema),
    },
  • Dispatch handler in the search feature that routes search_wiki requests, parses arguments, calls the core handler, and formats the response.
    case 'search_wiki': {
      const args = SearchWikiSchema.parse(request.params.arguments);
      const result = await searchWiki(connection, args);
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
      };
    }
  • Helper function to obtain the authorization header for API calls using environment-based authentication.
    async function getAuthorizationHeader(): Promise<string> {
      try {
        // For PAT authentication, we can construct the header directly
        if (
          process.env.AZURE_DEVOPS_AUTH_METHOD?.toLowerCase() === 'pat' &&
          process.env.AZURE_DEVOPS_PAT
        ) {
          // For PAT auth, we can construct the Basic auth header directly
          const token = process.env.AZURE_DEVOPS_PAT;
          const base64Token = Buffer.from(`:${token}`).toString('base64');
          return `Basic ${base64Token}`;
        }
    
        // For Azure Identity / Azure CLI auth, we need to get a token
        // using the Azure DevOps resource ID
        // Choose the appropriate credential based on auth method
        const credential =
          process.env.AZURE_DEVOPS_AUTH_METHOD?.toLowerCase() === 'azure-cli'
            ? new AzureCliCredential()
            : new DefaultAzureCredential();
    
        // Azure DevOps resource ID for token acquisition
        const AZURE_DEVOPS_RESOURCE_ID = '499b84ac-1321-427f-aa17-267ca6975798';
    
        // Get token for Azure DevOps
        const token = await credential.getToken(
          `${AZURE_DEVOPS_RESOURCE_ID}/.default`,
        );
    
        if (!token || !token.token) {
          throw new Error('Failed to acquire token for Azure DevOps');
        }
    
        return `Bearer ${token.token}`;
      } catch (error) {
        throw new AzureDevOpsValidationError(
          `Failed to get authorization header: ${error instanceof Error ? error.message : String(error)}`,
        );
      }
    }

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/Tiberriver256/mcp-server-azure-devops'

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