Skip to main content
Glama

search-page-by-prefix

Read-onlyIdempotent

Retrieve wiki page titles that start with a specified prefix, enabling autocomplete and title lookup. Returns up to 500 titles per request.

Instructions

Returns wiki page titles beginning with a given prefix (suited to autocomplete and title lookup). Only titles are returned — no snippets, sizes, or IDs. Accepts up to 500 titles per call (default 10); additional matches beyond the cap are flagged in the response. For full-text content search, use search-page.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
prefixYesWiki page title prefix
limitNoMaximum number of results to return
namespaceNoNamespace ID to restrict the search to

Implementation Reference

  • The handle function that executes the search-page-by-prefix tool logic. It calls the MediaWiki API 'allpages' list with the given prefix, limit, and optional namespace, then formats the results as page titles, IDs, and namespaces. Detects truncation via the 'continue' field in the API response.
    	async handle({ prefix, limit, namespace }, ctx: ToolContext): Promise<CallToolResult> {
    		const mwn = await ctx.mwn();
    
    		const params: Record<string, string | number | boolean> = {
    			action: 'query',
    			list: 'allpages',
    			apprefix: prefix,
    			formatversion: '2',
    		};
    		if (limit !== undefined) {
    			params.aplimit = limit;
    		}
    		if (namespace !== undefined) {
    			params.apnamespace = namespace;
    		}
    
    		const response = await mwn.request(params);
    		const pages: AllPagesEntry[] = response.query?.allpages ?? [];
    
    		const truncation: TruncationInfo | null = response.continue
    			? {
    					reason: 'capped-no-continuation',
    					returnedCount: pages.length,
    					limit: limit ?? 10,
    					itemNoun: 'titles',
    					narrowHint: 'narrow the prefix or raise limit (max 500)',
    				}
    			: null;
    
    		return ctx.format.ok({
    			results: pages.map((p) => ({
    				title: p.title,
    				pageId: p.pageid,
    				namespace: p.ns,
    			})),
    			...(truncation !== null ? { truncation } : {}),
    		});
    	},
    };
  • Input schema for the tool: prefix (string, required), limit (number, 1-500, optional, default 10), namespace (non-negative integer, optional). Defined using zod.
    const inputSchema = {
    	prefix: z.string().describe('Wiki page title prefix'),
    	limit: z
    		.number()
    		.int()
    		.min(1)
    		.max(500)
    		.optional()
    		.describe('Maximum number of results to return'),
    	namespace: z
    		.number()
    		.int()
    		.nonnegative()
    		.optional()
    		.describe('Namespace ID to restrict the search to'),
    } as const;
  • The full tool object export including name 'search-page-by-prefix', description, annotations, failureVerb, target extractor, and the handle function.
    export const searchPageByPrefix: Tool<typeof inputSchema> = {
    	name: 'search-page-by-prefix',
    	description:
    		'Returns wiki page titles beginning with a given prefix (suited to autocomplete and title lookup). Only titles are returned — no snippets, sizes, or IDs. Accepts up to 500 titles per call (default 10); additional matches beyond the cap are flagged in the response. For full-text content search, use search-page.',
    	inputSchema,
    	annotations: {
    		title: 'Search page by prefix',
    		readOnlyHint: true,
    		destructiveHint: false,
    		idempotentHint: true,
    		openWorldHint: true,
    	} as ToolAnnotations,
    	failureVerb: 'retrieve search data',
    	target: (a) => a.prefix,
    
    	async handle({ prefix, limit, namespace }, ctx: ToolContext): Promise<CallToolResult> {
    		const mwn = await ctx.mwn();
    
    		const params: Record<string, string | number | boolean> = {
    			action: 'query',
    			list: 'allpages',
    			apprefix: prefix,
    			formatversion: '2',
    		};
    		if (limit !== undefined) {
    			params.aplimit = limit;
    		}
    		if (namespace !== undefined) {
    			params.apnamespace = namespace;
    		}
    
    		const response = await mwn.request(params);
    		const pages: AllPagesEntry[] = response.query?.allpages ?? [];
    
    		const truncation: TruncationInfo | null = response.continue
    			? {
    					reason: 'capped-no-continuation',
    					returnedCount: pages.length,
    					limit: limit ?? 10,
    					itemNoun: 'titles',
    					narrowHint: 'narrow the prefix or raise limit (max 500)',
    				}
    			: null;
    
    		return ctx.format.ok({
    			results: pages.map((p) => ({
    				title: p.title,
    				pageId: p.pageid,
    				namespace: p.ns,
    			})),
    			...(truncation !== null ? { truncation } : {}),
    		});
    	},
    };
  • The registerAllTools function that registers searchPageByPrefix (and all other tools) with the MCP server via the register() helper. The tool is included in the standardTools array at line 48.
    export function registerAllTools(
    	server: McpServer,
    	reconcile: Reconcile,
    	ctx: ToolContext,
    ): Map<string, RegisteredTool> {
    	const registered = new Map<string, RegisteredTool>();
    
    	// oxlint-disable-next-line typescript/no-explicit-any
    	const allStandardTools: Tool<any>[] = [
    		...standardTools,
    		...extensionPacks.flatMap((p) => p.tools),
    	];
    	for (const tool of allStandardTools) {
    		try {
    			registered.set(tool.name, register(server, tool, dispatch(tool, ctx)));
    		} catch (error) {
    			logger.error('Error registering tool', { error: errorMessage(error) });
    		}
    	}
    
    	const mgmtCtx: ManagementContext = { ...ctx, reconcile };
    	for (const tool of managementTools) {
    		try {
    			registered.set(tool.name, register(server, tool, dispatch(tool, mgmtCtx)));
    		} catch (error) {
    			logger.error('Error registering tool', { error: errorMessage(error) });
    		}
    	}
    
    	// Extension-gated tools start disabled. They're enabled by reconcile() once
    	// the extension detector confirms the relevant extension is installed on
    	// the active wiki. This avoids a race where tools/list arrives before the
    	// initial reconcile completes.
    	for (const pack of extensionPacks) {
    		for (const tool of pack.tools) {
    			const reg = registered.get(tool.name);
    			if (reg && reg.enabled) {
    				reg.disable();
    			}
    		}
    	}
    
    	return registered;
    }
  • The register() helper function that binds a Tool object to an MCP server via server.registerTool(), passing the tool name, description, inputSchema, and annotations.
    export function register<TSchema extends ZodRawShape, TCtx extends ToolContext>(
    	server: McpServer,
    	tool: Tool<TSchema, TCtx>,
    	handler: (args: z.infer<z.ZodObject<TSchema>>) => Promise<CallToolResult>,
    ): RegisteredTool {
    	return server.registerTool(
    		tool.name,
    		{
    			description: tool.description,
    			inputSchema: tool.inputSchema,
    			annotations: tool.annotations,
    		},
    		// The SDK callback signature is `(args, extra) => ...`. Our descriptor
    		// handlers ignore the `extra` parameter, so we widen the type here. The
    		// `ZodRawShape` constraint from zod is the same shape as the SDK's
    		// `ZodRawShapeCompat` (Record<string, AnySchema>) — TypeScript just
    		// can't unify them through the generic boundary.
    		// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- generic boundary; MCP SDK's ToolCallback can't be unified with our typed handler
    		handler as unknown as ToolCallback<TSchema>,
    	);
    }
Behavior5/5

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

Annotations already indicate readOnlyHint, idempotentHint, and non-destructive. The description adds that only titles are returned (no snippets, sizes, IDs) and that a cap with flagging exists, providing useful behavioral context beyond annotations.

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?

Three sentences, no filler. Purpose, key constraints, and sibling reference are concisely communicated. Front-loaded with the core functionality.

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

Completeness5/5

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

Despite lacking an output schema, the description sufficiently explains the return format (only titles, cap flagging) and default behavior. It also references the appropriate sibling for full search, making the tool self-contained for its niche use case.

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?

Schema coverage is 100%, so baseline is 3. The description adds meaningful extra context: explains the default limit of 10, the cap of 500, and that additional matches are flagged. This compensates for the minimal schema descriptions.

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 tool returns wiki page titles matching a prefix, specifically for autocomplete and title lookup. It explicitly distinguishes itself from the sibling search-page for full-text content.

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

Usage Guidelines5/5

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

Provides explicit guidance: 'suited to autocomplete and title lookup' and directly directs to 'For full-text content search, use search-page.' Also explains the result cap and flagging behavior.

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/ProfessionalWiki/MediaWiki-MCP-Server'

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