Skip to main content
Glama
omarnagy91
by omarnagy91

legal-intake-mcp

A Model Context Protocol server for law firm document intake, Arabic and English.

It turns a contract file into structured, citable context: normalised text with paragraph anchors, clauses split along both Arabic and English numbering conventions, dates resolved across the Gregorian and Hijri calendars with the deadlines that follow from them, parties and signatories, and clause search by legal concept.

Safety line, stated plainly: this server extracts and cites. It does not give legal advice, it does not decide anything, and it does not judge whether a clause is fair or enforceable. Every item it returns carries an anchor pointing at the exact paragraph of the source document it came from, so a qualified lawyer can verify each one against the original before relying on it.


Why an MCP server is the right shape for this

The temptation with a task like "review this contract" is to build a service that reads the document, calls a model, and returns an answer. That is the wrong shape, for three reasons.

The deterministic work and the reasoning work are different work. Parsing a PDF, mapping Arabic presentation forms back to real letters, converting 15 Ramadan 1446 to a Gregorian date, and subtracting sixty days from a term end are all deterministic. They should be done once, correctly, in code that can be tested. Deciding whether an auto renewal clause is a problem for this client is judgement, and it belongs to the model and to the lawyer supervising it.

It means no API key and no secrets. This server makes no network call and holds no credentials. You point Claude at it, and Claude does the reasoning it was already going to do, with better inputs. Nothing about a client's contract leaves the machine because of this server.

It makes the output checkable. Because the server returns anchors rather than conclusions, every statement built on it can be traced back to a paragraph. C12 is a clause, P34 is a paragraph, and both mean the same thing in every tool. A reviewer who does not trust the summary can open the anchor.

The division of labour is the point: the server does the document work, the client model does the legal reasoning, and the anchors let a human check both.


Related MCP server: document-intelligence-mcp

Arabic is first class

Arabic contract text breaks tools that were built for English and then localised. The specific failures this server handles:

Problem

What happens without handling

What this server does

Arabic-Indic numerals ٦٠

Any parser built on \d finds no numbers at all

Accepts ٠-٩ and Persian and Urdu ۰-۹ everywhere a numeral can appear

Arabic clause numbering

The whole contract comes back as one clause, destroying every citation

Handles المادة (٣), البند الأول, أولاً, ٣-٢, الملحق رقم (١)

Hijri dates

1446 is read as a nonsense year, or silently converted with no tolerance

Parsed, labelled, converted with the tabular civil calendar, with the divergence flagged

Tatweel الســـرية

A search for the plain word misses the very heading that names it

Kashida stripped before matching

Alef and hamza variants أ إ آ ا, teh marbuta ة/ه

الأول and الاول are treated as different words

Folded for matching only, never in the text you are given

Presentation forms in PDFs

Text extracts as unreadable, unsearchable glyph codes

Detected and mapped back to base letters, and reported

Visual order text

Every Arabic word comes out reversed

Detected on strong evidence only, repaired, and reported

RTL run order in PDFs

Phrases come back in reverse sequence, a date landing before the sentence that introduces it

Runs on each line are sorted into reading order using the line's own direction

Mixed direction documents

One direction is forced on the whole file

Direction computed per paragraph

Two rules govern all of it:

  1. Text you are given is verbatim. The only changes ever applied are repairs to an encoding defect in the source file itself. Every repair that fires is listed in the document's normalisations field. A clean file produces an empty list.

  2. Folding is for matching only. The aggressive normalisation that makes الأول match الاول is used to decide whether a pattern matched. The span returned to you is always cut from the original text.

On Hijri conversion

Conversion uses the tabular civil Hijri calendar. That calendar is arithmetic, and it can differ by about a day from the sighting based calendar a court or ministry actually applies. So conversions are labelled as tabular, and where a contract states its own Gregorian equivalent, the stated value is preserved and any divergence is reported rather than resolved.

The Arabic sample contract is dated ١٥ رمضان ١٤٤٦هـ الموافق ١٤ مارس ٢٠٢٥م. The tabular conversion gives 2025-03-15, the contract says 2025-03-14. The server reports both and says which is which. Silently picking one would hide a real discrepancy that only a person can settle.


Install

Requires Node 20 or newer.

git clone https://github.com/omarnagy91/legal-intake-mcp.git
cd legal-intake-mcp && npm install

That is the whole install. npm install also builds, because the prepare script runs tsc. There is no API key, no .env, and no configuration file.

Verify it:

npm test     # runs the full suite
npm run demo # runs every tool on both sample contracts over the real MCP protocol

Connect it

Claude Code

claude mcp add legal-intake -- node /absolute/path/to/legal-intake-mcp/dist/src/index.js

Claude Desktop

Add this to claude_desktop_config.json. On macOS that file lives at ~/Library/Application Support/Claude/claude_desktop_config.json, and on Windows at %APPDATA%\Claude\claude_desktop_config.json.

{
  "mcpServers": {
    "legal-intake": {
      "command": "node",
      "args": ["/absolute/path/to/legal-intake-mcp/dist/src/index.js"]
    }
  }
}

Use an absolute path, and restart Claude Desktop afterwards. The server speaks stdio and needs no environment variables.


Tools

Every tool takes a path to a .pdf, .docx, or plain text file. The format is detected from the file content rather than its extension, because a mislabelled file in an intake pile otherwise gets parsed confidently and wrongly.

load_document

Loads a contract and returns normalised text with an anchor on every paragraph.

Input: path (required), includeText (boolean, default true), maxParagraphs (integer, optional).

Output: format, pageCount (null for formats without pages), paragraphCount, characterCount, languageMix (Arabic and Latin character counts and shares, dominant script, text direction), normalisations (encoding repairs applied), warnings, and paragraphs, each with anchor, page, direction and text.

Warnings that matter: a PDF whose text layer maps a share of its glyphs to nothing is reported as lossy, with the percentage, rather than returning text with silent holes in it. A PDF with no text layer at all is reported as needing OCR.

segment_clauses

Splits the document into numbered clauses and headings.

Input: path (required), includeText (boolean, default true), maxClauses (integer, optional).

Output: clauseCount, numberingConventions (a count per convention found), and clauses, each with anchor (C14), label exactly as the document writes it, normalisedLabel in ASCII for comparison across scripts, numbering, heading, depth, parentAnchor, paragraphAnchors, page, direction and text.

Parent links are structural, not numeric. Real contracts contain misnumbered sub clauses, and matching on the number alone drops them.

extract_dates

Extracts every date, classifies its role, and computes the deadlines that follow.

Input: path (required).

Output: dates, each with raw as written, calendar, iso, hijri components where applicable, role (execution, commencement, term_end, renewal, notice, payment, delivery, signature, unclassified), roleEvidence quoting the wording that justified the role, anchor, clauseAnchor, and notes. Plus noticePeriods found in the text and computedDeadlines.

A deadline is only computed where a fixed date in the document anchors it. A period such as "within thirty (30) days of the invoice date" has no fixed anchor, so it is reported as a period and not turned into a date that would look more certain than it is.

extract_parties

Input: path (required).

Output: parties with name, definedTerm, role, identifiers, address, anchor and language. signatories with name, title, onBehalfOf, date, anchor, additionalAnchors and source.

It reads both drafting traditions: the English numbered recital with a bracketed defined term, and the Arabic ordinal block with the ويشار إليه formula and the ويمثلها في التوقيع representative clause, which names the person who actually bound the company and is often the only place they are named.

find_clauses

Searches by legal concept and returns the matching clauses with their real text.

Input: path (required), concept (optional enum), query (optional free text, Arabic or English), limit (default 5). At least one of concept or query is required.

Concepts: auto_renewal, unilateral_termination, penalty, governing_law, arbitration, confidentiality, non_compete, limitation_of_liability, notice, payment_terms, force_majeure, assignment, entire_agreement.

Output: matchCount and matches, each a full clause plus score and matchedTerms, so the ranking can be audited. The full clause text is returned deliberately, so the model reviews the wording rather than the fact that something matched. A sub clause inherits its section heading for search purposes, because clause 7.1 never says "non-compete", it just states the restraint; the word is in the heading above it.

When nothing matches, that is reported as a finding rather than papered over.

document_summary

A structured skeleton for the model to reason over.

Input: path (required).

Output: parties, signatories, term (execution, commencement, term end, whether it renews automatically, the renewal clause anchors, computed deadlines), obligations with the party bound by each, flaggedClauses, structureNotes, and a disclaimer.

Clauses are flagged only because they belong to categories a reviewer normally reads closely, never because the server judged them. There is no risk rating and no recommendation, because those belong to the reviewing lawyer.


Worked example

Real output, taken from npm run demo against samples/services-agreement-ar.txt. Trimmed for length, otherwise unedited.

load_document

{
  "format": "text",
  "paragraphCount": 58,
  "languageMix": {
    "arabicChars": 4615, "latinChars": 55,
    "arabicShare": 0.988, "latinShare": 0.012,
    "dominant": "arabic", "direction": "rtl"
  },
  "normalisations": [],
  "warnings": []
}

segment_clauses finds 49 clauses and reports which conventions produced them:

{
  "clauseCount": 49,
  "numberingConventions": {
    "none": 1, "arabic-ordinal": 2, "heading": 1,
    "arabic-article": 13, "arabic-decimal": 28, "lettered": 4
  },
  "clauses": [
    { "anchor": "C5", "label": "المادة (١)", "normalisedLabel": "1",
      "numbering": "arabic-article", "heading": "التمهيد وملحقات العقد", "depth": 0 },
    { "anchor": "C12", "label": "٣-٢", "normalisedLabel": "3.2",
      "numbering": "arabic-decimal", "depth": 1, "parentAnchor": "C10" }
  ]
}

extract_dates reads the Hijri date, converts it, and flags the divergence from the equivalent the contract states for itself:

{
  "raw": "١٥ رمضان ١٤٤٦",
  "calendar": "hijri",
  "iso": "2025-03-15",
  "hijri": { "year": 1446, "month": 9, "day": 15, "monthName": "رمضان" },
  "role": "execution",
  "anchor": "P2",
  "statedGregorian": "2025-03-14",
  "notes": [
    "Gregorian value is a tabular civil Hijri conversion and can differ by one day from the sighting based calendar used officially. Confirm against the calendar the contract is subject to.",
    "The contract states 2025-03-14 as the Gregorian equivalent. The tabular conversion gives 2025-03-15, a difference of -1 day(s). The stated equivalent is what the parties wrote and normally governs."
  ]
}

and computes the deadline that follows from the auto renewal clause:

{
  "description": "Written notice of non-renewal must be given on or before this date, otherwise the agreement renews automatically.",
  "period": "60 days", "days": 60, "direction": "before",
  "anchorDate": "2026-03-31", "anchorDateRole": "term_end",
  "deadline": "2026-01-30",
  "clauseAnchor": "C12", "paragraphAnchor": "P17",
  "notes": [
    "Computed as 2026-03-31 minus 60 day(s), taken from the notice period in clause ٣-٢.",
    "Calendar days, not business days, unless the contract says otherwise. Verify against the notice clause before relying on it."
  ]
}

extract_parties reads the Arabic party block, including the representative named inside it:

{
  "parties": [
    { "name": "شركة الواحة للاستشارات الإدارية ذات مسؤولية محدودة",
      "definedTerm": "مقدم الخدمة", "role": "الطرف الأول",
      "identifiers": ["1183097"],
      "address": "٢٢ شارع النصر، مدينة نصر، القاهرة", "anchor": "P4" },
    { "name": "مؤسسة نور الشرق للتجارة والتوريدات",
      "definedTerm": "العميل", "role": "الطرف الثاني",
      "identifiers": ["9144722"],
      "address": "٧ شارع الجلاء، الإسكندرية", "anchor": "P5" }
  ],
  "signatories": [
    { "name": "كريم عبد الرحمن", "title": "المدير التنفيذي",
      "onBehalfOf": "شركة الواحة للاستشارات الإدارية ذات مسؤولية محدودة",
      "date": "١٤ مارس ٢٠٢٥",
      "anchor": "P4", "additionalAnchors": ["P50"], "source": "party_block" }
  ]
}

find_clauses with concept: "auto_renewal" returns the operative clause with its text and the reason it matched:

{
  "matchCount": 4,
  "matches": [
    {
      "anchor": "C12", "label": "٣-٢", "score": 9,
      "matchedTerms": ["يتجدد هذا العقد تلقائياً", "عدم التجديد", "يتجدد"],
      "text": "٣-٢ يتجدد هذا العقد تلقائياً لمدة أو مدد مماثلة ما لم يخطر أحد الطرفين الطرف الآخر كتابةً برغبته في عدم التجديد قبل ستين (٦٠) يوماً على الأقل من تاريخ انتهاء المدة السارية."
    }
  ]
}

The same contract in English produces the same commencement date, the same term end, and the same computed deadline of 2026-01-30. There is a test asserting exactly that, because the two files agreeing is the clearest evidence that the Arabic path is doing real work rather than approximating it.


Samples

samples/ holds two contracts written for this repository, one English and one Arabic, with invented parties. They are not translations of each other; the Arabic one is drafted the way an Egyptian services agreement is actually drafted, with المادة numbering, a Hijri date, and the representative named in the party block.

File

Format

Notes

services-agreement-en.txt

plain text

English services agreement

services-agreement-en.docx

Word

the same contract, exercising the DOCX reader

services-agreement-en.pdf

PDF, 5 pages

the same contract, exercising the PDF reader and page anchoring

services-agreement-ar.txt

plain text

Arabic services agreement

services-agreement-ar.docx

Word

the same contract, right to left

scripts/make-samples.mjs regenerates the DOCX and PDF from the text files. Reviewers never need to run it.

On the absence of an Arabic PDF sample

There is not one, and the reason is worth stating plainly, because it is the most interesting thing this project learned.

Arabic PDF text extraction depends entirely on how the producing tool wrote its text layer. Three distinct defect classes were measured during development, not assumed:

  1. Presentation forms. One generator stored every letter as its joined glyph rather than its base character, so the text extracted as unreadable Arabic Presentation Forms. The same file also had a ToUnicode map that resolved a large share of glyphs to U+0000, meaning characters that simply are not recoverable from the file.

  2. Reversed run order. A second generator wrote clean logical Unicode, but pdf.js returns runs in positional order, which for a right to left line is the reverse of reading order. The line تحرر هذا العقد في مدينة القاهرة بتاريخ ١٥ رمضان ١٤٤٦هـ came back with the date first and the sentence last. This one the server now fixes, by sorting the runs on each line using the line's own resolved direction. There is a unit test built from the exact pdf.js items that exposed it.

  3. Character level ligature transposition. That same otherwise clean file still emitted certain shaped clusters with their two codepoints in visual order, so الموافق extracted as املوافق and بين as بني. This is below the level any consumer of the text layer can reliably detect or repair, because the output is well formed Unicode that happens to be wrong.

Defect 3 is why no Arabic PDF ships here. Shipping a fixture whose words are quietly transposed would contradict the one rule this server is built on, that text handed to a lawyer is text they can cite.

So the repository ships the English PDF, which extracts cleanly and proves the PDF path end to end including page numbers, and covers the Arabic defect classes with unit tests built on fixtures reproducing exactly what was measured. In real use the server detects presentation forms and maps them back, sorts RTL runs into reading order, repairs whole line visual ordering on strong evidence, and reports a lossy text layer as a warning with the percentage rather than returning text with silent holes in it. What it cannot do is invent characters a PDF never encoded, or detect a transposition that produces valid Unicode, and it says so rather than pretending otherwise.

The practical guidance that falls out of this: for Arabic, prefer .docx at intake where you can get it, and treat any Arabic PDF as needing a human to eyeball the extracted text before it is quoted.


Tests

npm test

108 tests, all passing. They cover:

  • Arabic specifically: digit conversion including Persian forms, presentation form de-shaping, lam alef ligature splitting, visual order repair including the negative case where it must refuse to act, tatweel stripping, alef and teh marbuta folding, offset preserving folds, script mix, per paragraph direction, and right to left PDF run ordering driven by the real pdf.js items that exposed the bug.

  • Dates: the Hijri epoch, a modern Hijri conversion checked against the observed date, ISO arithmetic across month, year and leap day boundaries, role classification, and the assertion that a renewal term length is not mistaken for a notice period.

  • Clause segmentation: every Arabic and English numbering convention, and the assertion that the Arabic contract segments into many clauses rather than one, which is the test that fails for any splitter written only for English.

  • Anchors: that every paragraph belongs to exactly one clause, that no tool cites an anchor another tool does not know, and that clause text is verbatim from its paragraphs.

  • Formats: that the same contract as .txt, .docx and .pdf produces the same clause labels, the same dates and the same parties.

  • The MCP protocol itself: the suite spawns the built server as a child process and speaks real JSON-RPC over stdio, running initialize, tools/list and every tool against all five sample files.


Design notes

Dependencies are two. @modelcontextprotocol/sdk and pdfjs-dist, both pinned to exact versions. The DOCX reader is written against Node's own zlib, because a .docx is a ZIP holding an XML part and that needs a central directory walk and a raw inflate, not a library. Tests use node:test. There is no test framework, no bundler and no linter config to install.

pdf.js rather than a hand rolled parser, because the part that matters here is resolving glyph codes back to Unicode through the font's ToUnicode map, which is exactly the part that is hard, and the part Arabic depends on entirely.

Right to left run ordering was a real bug found by reading the output of a generated Arabic PDF rather than by reasoning about the code. It is fixed, and its fix is the difference between a legible Arabic contract and a scrambled one.

Paragraph grouping in PDFs uses a low percentile of the observed line gaps as the line spacing rather than the median. In a contract most paragraphs are one or two lines, so the median gap is the paragraph gap, and a median based threshold merges an entire page into one block. That was a real bug, found by checking the output rather than by reading the code.

Documents are addressed by path, not by a handle. There is no session state to get out of sync, and a restart loses nothing. Loading is cached on path, size and modification time, so repeated calls are cheap and an edited file is picked up immediately.


Licence

MIT. See LICENSE.

Built by Omar G. Nagy.

Available Tools

6 tools
document_summaryA

Build a structured skeleton of the contract for the model to reason over: parties and signatories, the term and whether it renews automatically, the obligations with the party bound by each, and the anchors of clauses that commonly need a closer look (auto renewal, unilateral termination, penalties, non compete, liability caps, arbitration). It returns structure and citations only. It contains no legal opinion, no risk rating and no recommendation, because those are the reviewing lawyer's to make.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesPath to the document. Accepts .pdf, .docx or a plain text file (.txt, .md). Absolute paths are safest. The format is detected from the file content, not the extension.

TDQS

A4/5.0
Behavior4/5

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

With no annotations present, the description carries the full disclosure burden and does substantial work: it states the deliverable is 'structure and citations only' and explicitly discloses that it deliberately omits legal opinion, risk rating, and recommendation. It could go further on failure behavior or exact return format, but for a read-only summarization tool it gives the critical behavioral boundaries.

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?

Two dense sentences with a clear front-loaded purpose, a compact list of output elements, and a final sentence that earns its place by preventing misuse. There is no filler or repetition.

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

Completeness4/5

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

For a tool with one documented parameter and no output schema, the description covers the main things an agent needs: what the tool produces, what fields are included, and what it intentionally withholds. It is slightly incomplete on exact output format/citation shape and on how to choose it against the sibling tools, but it is sufficient for correct invocation in most cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the path parameter is already well described in the schema (accepted formats, absolute paths, content-based detection). The description adds no parameter-level semantics, so the baseline of 3 is appropriate — the schema carries the heavy lifting.

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 names a specific verb and resource ('Build a structured skeleton of the contract') and enumerates the concrete output fields: parties/signatories, term/renewal, obligations with bound party, and clause anchors. It also clearly differentiates from the sibling extractor tools by framing it as a holistic model-facing summary rather than a single extraction, and explicitly excludes legal opinion/risk rating/recommendation.

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

Usage Guidelines3/5

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

It provides a clear usage context — when the model needs a structured skeleton of the whole contract to reason over — and it tells the agent what it will not get (legal opinion, risk rating, recommendation). However, it never names the sibling alternatives (extract_parties, find_clauses, etc.) or states explicitly when the lower-level extractors should be preferred, so the when-to-use guidance is implied rather than explicit.

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

extract_datesA

Extract every date, classify what it is for, and compute the deadlines that follow from it. Handles Gregorian and Hijri, Arabic-Indic and Persian digits, and month names in the Egyptian and Gulf, Levantine and Iraqi, and Hijri naming traditions. Each date reports its calendar, an ISO value, the role it plays (execution, commencement, term_end, renewal, notice, payment, delivery, signature) and the wording that justified that role. Hijri dates are converted with the tabular civil calendar and labelled as such, and where the contract states its own Gregorian equivalent any divergence is reported rather than resolved. Also returns notice periods found in the text and, where a fixed date anchors them, computed deadlines such as the date by which notice of non-renewal must be given.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesPath to the document. Accepts .pdf, .docx or a plain text file (.txt, .md). Absolute paths are safest. The format is detected from the file content, not the extension.

TDQS

A4.4/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 excels: it discloses the Hijri conversion method ('tabular civil calendar and labelled as such'), the divergence policy ('reported rather than resolved' when the contract states its own Gregorian equivalent), and the exact result shape (calendar, ISO value, role, justifying wording, notice periods, computed deadlines). This is precisely the behavioral context an agent needs beyond any structured metadata.

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?

Front-loaded with the core function, then layered into supported formats, output structure, conversion policy, and derived results. Every sentence carries unique information and the density is justified by the tool's complexity, though the enumeration of role values and naming traditions is slightly long.

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?

There is no output schema, so the description must explain return values — it does so thoroughly: each date reports calendar, ISO value, role, and justifying wording, plus notice periods and deadlines anchored to fixed dates. For a multi-calendar, multi-dialect tool, nothing an agent needs to invoke it correctly or interpret its output is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: the single 'path' parameter is fully documented in the schema, including accepted extensions, the absolute-path recommendation, and content-based format detection. The description adds no parameter-specific detail, which is acceptable at the baseline of 3 for full schema coverage.

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 opens with a specific verb+resource ('Extract every date') and immediately adds what distinguishes this tool: classification of each date's role and computation of follow-on deadlines. No sibling (load_document, extract_parties, find_clauses, segment_clauses, document_summary) overlaps with date extraction, so an agent can tell them apart without opening any schemas.

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

Usage Guidelines4/5

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

The scope is so clearly delineated — date extraction across calendars, digit systems, and regional month-name traditions, plus notice periods and deadlines — that the context for when to use it is unmistakable. However, it never explicitly states 'use this when you need dates/deadlines' nor names alternatives or exclusion conditions, leaving routing slightly implicit.

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

extract_partiesA

Extract the parties, their defined terms and roles, their registration identifiers and addresses, and the signatories with their titles, each with an anchor. Reads both drafting traditions: the English numbered recital with a bracketed defined term, and the Arabic ordinal block with the ويشار إليه formula and the ويمثلها في التوقيع representative clause, which names the person who actually bound the company and is often the only place they are named.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesPath to the document. Accepts .pdf, .docx or a plain text file (.txt, .md). Absolute paths are safest. The format is detected from the file content, not the extension.

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and mostly delivers. It discloses cross-tradition reading, the anchor behavior, and the practical insight that the Arabic representative clause is often the only place the signatory is named. It stops short of describing output structure or failure modes, but the behavioral traits it reveals are specific and useful.

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?

The first sentence front-loads the complete list of extracted entities, and the second sentence adds essential format-recognition nuance without fluff. Every clause earns its place, including the Arabic terminology, which is necessary for correctly recognizing the target structures. It avoids repeating schema content.

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

Completeness4/5

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

The description is rich enough for an agent to invoke the tool on the right document and understand what it returns at a semantic level. However, there is no output schema, so the exact return structure (e.g., fields, nesting, anchor representation) is not specified. This is a minor gap given the detailed entity enumeration.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the single parameter (path) is already well documented in the schema, including accepted formats and content-based detection. The description adds no parameter-specific detail, but none is needed. The baseline score of 3 applies.

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?

States a specific verb ('Extract') and a precise resource: parties, defined terms, roles, registration identifiers, addresses, signatories, titles, and anchors. This clearly differentiates it from sibling extraction tools like extract_dates and find_clauses. There is no ambiguity about what the tool returns.

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

Usage Guidelines4/5

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

The description gives clear context on the two drafting traditions the tool handles, including the English bracketed defined term and the Arabic ordinal block with representative clause. This helps an agent decide when this tool fits a document. It does not explicitly name alternatives or state when-not-to-use, but the contextual guidance is strong.

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

find_clausesA

Find the clauses that deal with a legal concept and return their real text with anchors, so the model reviews the actual wording instead of a summary of it. Supported concepts: auto_renewal, unilateral_termination, penalty, governing_law, arbitration, confidentiality, non_compete, limitation_of_liability, notice, payment_terms, force_majeure, assignment, entire_agreement. Matching runs over an Arabic aware folded copy of the text, so a clause still matches whichever way it spells a term. Pass query instead of, or as well as, concept to search for free text. Results are ranked, and every result lists the terms that matched so the ranking can be audited.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesPath to the document. Accepts .pdf, .docx or a plain text file (.txt, .md). Absolute paths are safest. The format is detected from the file content, not the extension.
limitNoMaximum number of clauses to return. Default 5.
queryNoFree text to search for, in Arabic or English. Can be used on its own or alongside a concept to narrow it.
conceptNoThe legal concept to search for.

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral burden. It discloses that matching uses an Arabic-aware folded copy, results are ranked, and each result lists matched terms for auditability. This meaningfully explains how the tool behaves beyond just 'find clauses'.

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?

The description is a bit long but front-loaded with the core purpose. The supported-concept list and matching/ranking details all earn their place, though the concept list duplicates the schema enum. No filler or vague phrasing.

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

Completeness4/5

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

Given there is no output schema, the description adequately explains return behavior: real clause text, anchors, ranked results, and matched terms. One minor gap is that it does not state what happens if neither concept nor query is provided, even though the schema only requires path.

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. The description adds value beyond the schema by explaining that query can substitute for or complement concept, that matching is Arabic-aware, and that results are ranked with matched terms. This goes beyond simple parameter names and types.

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 states a specific verb and resource: find clauses by legal concept and return their real text with anchors. It also distinguishes itself from summary-like tools by explicitly saying the model reviews actual wording instead of a summary, and the supported concept list makes the scope highly concrete.

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

Usage Guidelines4/5

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

The description gives clear context for when to use the tool: when you need clauses matching a legal concept or free-text query. It also explains how query can be used alone or alongside concept. It does not explicitly name alternatives or exclusions, but the intended usage is clear enough.

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

load_documentA

Load a contract and return its normalised text with a citation anchor on every paragraph, plus the detected language mix. Start here. Returns the format, page count where the format has pages, per paragraph text direction for correct rendering of mixed Arabic and English, any encoding repairs that were applied, and any warnings such as a PDF with a lossy or missing text layer. Paragraph anchors look like "P12" and are the same anchors every other tool reports.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesPath to the document. Accepts .pdf, .docx or a plain text file (.txt, .md). Absolute paths are safest. The format is detected from the file content, not the extension.
includeTextNoInclude the full text of every paragraph. Default true. Set false for a structural overview of a long document without the body text.
maxParagraphsNoReturn at most this many paragraphs. Omit for all of them.

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations provided, the description carries the full disclosure burden and largely meets it: it itemizes return fields (format, page count, per-paragraph text direction, encoding repairs, warnings) and flags edge cases like a PDF with a lossy or missing text layer. It stops short of disclosing error behavior for invalid paths or file-size limits, so not a 5.

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?

Four sentences, each earning its place: core purpose, entry-point cue, full return enumeration, and the anchor-convention note that ties the tool to its siblings. It is dense but front-loaded — the first sentence states the function and 'Start here' before any detail.

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

Completeness4/5

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

Lacking both annotations and an output schema, the description substitutes a detailed return specification, which covers the main operational unknowns an agent must know before calling. The remaining gaps — error handling, file-size limits, and an explicit read-only statement — are minor for a 3-parameter load tool whose schema is fully documented.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline of 3 applies — the schema already documents path format acceptance, content-based detection, includeText's default and purpose, and maxParagraphs semantics. The description reinforces the paragraph concept that includeText and maxParagraphs hinge on but adds no parameter-level facts beyond the schema.

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 opening sentence names a specific verb ('Load') and resource ('a contract') and enumerates exactly what it returns: normalised text, per-paragraph citation anchors, and detected language mix. The sibling tools are all downstream analysis operations (segment_clauses, extract_dates, find_clauses), so this is unmistakably the document-ingestion step. 'Start here' reinforces the distinct role.

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

Usage Guidelines4/5

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

'Start here' explicitly positions this tool as the entry point in the workflow, before any sibling analysis tool. The note that anchors are 'the same anchors every other tool reports' implies the siblings operate on what this tool loads. It lacks explicit when-not-to-use or named-alternative routing, but the entry-point context is clear.

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

segment_clausesA

Split the document into numbered clauses and headings, handling English and Arabic numbering conventions. English decimal (1, 1.1, 1.1.1), lettered and roman sub items, and the Arabic conventions المادة (٣), البند الأول, standalone ordinals أولاً and ثانياً, and Arabic decimal ٣-٢ written with a hyphen. Each clause gets a stable anchor such as "C14", its label exactly as the document writes it, an ASCII normalised label for comparison, its nesting depth, its parent clause, and the paragraph anchors it covers. Cite these anchors so the reader can find the exact clause.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesPath to the document. Accepts .pdf, .docx or a plain text file (.txt, .md). Absolute paths are safest. The format is detected from the file content, not the extension.
maxClausesNoReturn at most this many clauses. Omit for all of them.
includeTextNoInclude each clause full text. Default true.

TDQS

A4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly discloses that the tool handles English and Arabic numbering schemes, produces normalized labels, preserves the document's original labels, and returns parent/child relationships. It does not mention error behavior or performance limits, but the extraction behavior is well specified.

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?

The description is dense but every sentence adds value: the first sentence states the core action, the second enumerates the numbering conventions, and the third lists the output fields and their purpose. It is front-loaded with the primary behavior and avoids filler.

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

Completeness4/5

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

Given there is no output schema, the description adequately explains the return fields (anchor, label, depth, parent, paragraph anchors) and the complexity of the numbering conventions. It falls slightly short of 5 because it does not explicitly state the return container format (e.g., list of clause objects) or any failure modes, but these are reasonably inferable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already covers all three parameters with descriptions at 100% coverage, so the baseline is 3. The tool description adds no parameter-level detail beyond the schema, but it does not need to because the schema is complete.

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 opens with a specific verb and resource: 'Split the document into numbered clauses and headings.' It then details the exact output fields (stable anchor, label, depth, parent, paragraph anchors), making the tool's purpose unmistakable and distinct from siblings like extract_dates or extract_parties.

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

Usage Guidelines3/5

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

The intended use is implied by the final sentence, 'Cite these anchors so the reader can find the exact clause,' and by the focus on numbering conventions. However, there is no explicit guidance about when to prefer this tool over find_clauses or other siblings, and no exclusion criteria.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 6 tool updatesv1.0.0
    • First observeddocument_summary
    • First observedextract_dates
    • First observedextract_parties
    • First observedfind_clauses
    • First observedload_document
    • First observedsegment_clauses

TDQS

A4.3/5.0
Disambiguation5/5

Each tool has a clearly distinct stage in the intake pipeline: load, segment, extract dates, extract parties, summarize, and search clauses. Although segment_clauses and find_clauses both involve clauses, one is structural segmentation and the other is semantic retrieval of actual wording, so there is no real ambiguity.

Naming Consistency4/5

Five tools follow a clean verb_noun snake_case pattern (load_document, segment_clauses, extract_dates, extract_parties, find_clauses). document_summary breaks the verb pattern and reads as a noun, which is a minor deviation but still readable and consistent in style.

Tool Count5/5

Six tools is a well-scoped set for a legal contract intake server. It covers ingestion, structural segmentation, date extraction, party extraction, summarization, and semantic clause retrieval without redundancy or unnecessary bloat.

Completeness5/5

The surface covers the full intake pipeline: load and normalize the document, segment clauses, extract dates and parties, build a structured summary, and retrieve the actual wording of relevant clauses. There are no obvious dead ends or missing operations that would prevent an agent from completing a contract intake workflow.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    F
    maintenance
    Enables PDF document processing including text, image, and table extraction, as well as intelligent classification and similarity analysis across multiple languages.
    49
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Local document intelligence for AI agents — extract text, detect tables, read metadata, analyze structure, search keywords, and detect language from PDF and DOCX files. No cloud API required, no API key needed.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Decodes agreements and policy documents into plain language with verified citations, risk flags, obligation calendars, and comparisons, running in TEE-attested enclaves and producing cryptographically sealed, anchored reports.
    MIT

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/omarnagy91/legal-intake-mcp'

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