Skip to main content
Glama

Deepwiki MCP Server

by regenrek
deepwikiSearch.ts3.37 kB
import type { McpToolContext } from '../types' import { z } from 'zod' import { htmlToMarkdown } from '../converter/htmlToMarkdown' import { crawl } from '../lib/httpCrawler' import { FetchRequest } from '../schemas/deepwiki' /* ------------------------------------------------------------------ */ /* Schema */ /* ------------------------------------------------------------------ */ const SearchRequest = FetchRequest.extend({ /** Case-insensitive literal search term */ query: z.string().min(1, 'query cannot be empty'), /** Hard cap on number of snippets to return (default 10) */ maxMatches: z.number().int().positive().max(100).default(10), }) /* ------------------------------------------------------------------ */ /* Tool registration */ /* ------------------------------------------------------------------ */ export function deepwikiSearchTool({ mcp }: McpToolContext) { mcp.tool( 'deepwiki_search', `Download pages from a deepwiki.com, look for a case-insensitive substring, and return up to maxMatches short snippets with the match wrapped in **bold**. Required: • url – root Deepwiki repo • query – plain text (literal string) Optional: • maxDepth – crawl depth (default 1, like deepwiki.fetch) • maxMatches – limit on snippets (default 10) • mode – "aggregate" | "pages" (affects link rewriting only) • verbose – log progress to stderr`, SearchRequest.shape, async (raw) => { /* Helper to wrap everything into the MCP chat-message envelope */ const toMsg = (body: unknown) => ({ content: [{ type: 'text', text: JSON.stringify(body) }], }) /* ---------- validate input ---------- */ const parsed = SearchRequest.safeParse(raw) if (!parsed.success) { return toMsg({ status: 'error', code: 'VALIDATION', details: parsed.error.flatten(), }) } const req = parsed.data const root = new URL(req.url) /* ---------- crawl ---------- */ const { html } = await crawl({ root, maxDepth: req.maxDepth, emit: () => {}, verbose: req.verbose, }) /* ---------- build regex ---------- */ const safe = req.query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') const re = new RegExp(safe, 'i') const matches: { path: string, snippet: string }[] = [] /* ---------- convert + search ---------- */ for (const [path, sourceHtml] of Object.entries(html)) { if (matches.length >= req.maxMatches) break const md = await htmlToMarkdown(sourceHtml, req.mode) let m: RegExpExecArray | null while ((m = re.exec(md)) !== null) { const start = Math.max(0, m.index - 80) const end = Math.min(md.length, m.index + m[0].length + 80) const rawSnippet = md.slice(start, end) const snippet = rawSnippet.replace(re, s => `**${s}**`) matches.push({ path, snippet }) if (matches.length >= req.maxMatches) break } } /* ---------- reply ---------- */ return toMsg({ status: 'ok', query: req.query, matches, totalSearchedPages: Object.keys(html).length, }) }, ) }

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/regenrek/deepwiki-mcp'

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