Skip to main content
Glama

search_document

Regex-search a .docx and get back the matching blocks, ready to edit — WITHOUT pulling the whole document into the conversation.

Use this to locate text in a document that is too large to read_document whole, or to jump straight to the passages you care about before editing. The document is converted to the SAME HTML representation read_document returns, and pattern is matched against BOTH that HTML and the text a reader sees in it — so a phrase Word split across runs, or spelled with a non-breaking space, still matches when typed plainly, AND a pattern naming markup (a class, an , a tag) still works. If the pattern only matches with a relaxation (case, or a repeated space), that is applied and note says so.

pattern is a Python regular expression, e.g.:

  • "Effective Date" -> literal text

  • "termination|terminate" -> either word

  • "(?i)confidential" -> case-insensitive

  • "$[0-9,]+(?:.[0-9]{2})?" -> dollar amounts . matches newlines (DOTALL), so a pattern can span lines.

Each match is a COMPLETE BLOCK — verbatim HTML for the whole ///heading the match sits in, tags and all, with nothing cut off. For a content-only edit of that block, COPY match_text STRAIGHT INTO edit_document AS old; it needs no trimming. For an insertion or structural edit, first treat match_text as a locator. If it is not the nearest same-role structure the new content should resemble, read the reported page and expand old to include that structural example plus the insertion boundary. A match also carries:

  • matched — what your pattern actually matched inside the block, so you can see why it hit.

  • page — the 1-based page it falls on, the SAME numbering read_document uses, so you can read_document(start_page=...) if you want the surrounding context.

  • unique — false when that block's text appears elsewhere in the document too, so pasting it as old would be ambiguous. Add a neighbouring block from the same page to pin it down (see edit_document's MAKE 'old' UNIQUE).

When a match sits inside a semantic list item, match_text is the complete nearest <li>...</li> rather than its inner paragraph or the surrounding <ol>/<ul>. That item is enough for a one-item content edit. Before a structural list edit though, use read_document on the reported page to inspect the parent list's type/start, sibling items, and nesting.

total_matches is how many spots match in the WHOLE document; the blocks returned in one call fit a bounded budget, so has_more tells you some are still waiting and you get them with start_at (1-based index of the first match you want, e.g. start_at=9 after eight came back). note states all of this in one line — read it. Nothing is silently dropped, so you never have to narrow a pattern just to see the rest of its matches.

Two spots that read identically (a running footer, a repeated placeholder) are two matches with the same match_text, both marked unique: false — not a mistake, and not a reason to search again. They differ by page, which is how you pick the one you want.

Only the document's CONTENT is searched, never the stylesheet in its , so a pattern naming a CSS class finds the blocks carrying that class and not the rule that defines it.

Comment markup is searchable too. <aside finds comment threads, while <article finds individual comments and replies; each result returns its complete <aside> thread so it remains a valid edit anchor. Consequently, the total for <article\b is the document's comment count, whereas <aside\b is the thread count.

Input Schema

NameRequiredDescriptionDefault
patternYesRegex to run over the document's HTML projection.
start_atNo1-based index of the first match to return.

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so richly: matching runs against both the HTML and the reader-visible text, relaxed matches are flagged in `note`, DOTALL is on, matches are complete blocks not fragments, pagination via total_matches/has_more/start_at drops nothing silently, duplicate identical matches are expected and distinguished by page, stylesheets in <head> are never searched, and comment markup is searchable. Also discloses the non-obvious case that `<article` counts comments while `<aside` counts threads.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Long, but front-loaded with the purpose and scope in the first sentence, then organized by concern (pattern behavior, match anatomy, pagination, duplicates, markup). Every section carries real information, though the density of secondary details (comment markup, stylesheet exclusion) makes it heavier than strictly necessary.

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?

An output schema exists and the description still explains the match fields an agent must act on (matched, page, unique, match_text, note, total_matches, has_more) in terms of what to do with them. For a two-parameter search tool with no annotations, nothing an agent needs to call or interpret it correctly is missing.

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 the baseline is 3, but the description genuinely adds meaning beyond the schema: `pattern` is a Python regex, dot matches newlines, it is matched against both HTML and rendered text, and relaxation rules apply. It also illustrates `start_at` semantics with a concrete worked example ('start_at=9 after eight came back'). It falls short of 5 only because the per-parameter syntax details (four example patterns) shade into usage rather than pure parameter semantics.

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?

Specific verb (regex-search) plus resource (.docx) and a concrete deliverable (matching blocks ready to edit) with an explicit scope boundary ('WITHOUT pulling the whole document into the conversation'). It also distinguishes itself from both siblings, read_document and edit_document, which is stated directly rather than implied.

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?

Names the exact condition for use ('a document that is too large to read_document whole', 'jump straight to the passages you care about before editing') and routes the agent onward to read_document(start_page=...) for context and edit_document for the actual edit. When-not is implicit but the alternative paths are spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources