Skip to main content
Glama
chrisguidry

paperless-mcp

by chrisguidry

paperless-mcp

A read-only MCP server for your paperless-ngx document archive. It lets an AI assistant search your documents by full text, tags, correspondents, dates, and custom field values, find documents similar to one, find unfiled documents, and read the text and notes of any document. It cannot change or delete anything.

Setup

uv sync

You'll need an API token from your paperless-ngx instance: log in, open your profile (the person icon in the top right), and copy or generate the API token there.

The server is configured entirely through environment variables:

export PAPERLESS_URL=https://paperless.example.com
export PAPERLESS_TOKEN=your-api-token

Related MCP server: paperlessngx-mcp

Connecting a client

For Claude Code:

claude mcp add paperless \
  -e PAPERLESS_URL=https://paperless.example.com \
  -e PAPERLESS_TOKEN=your-api-token \
  -- uv run --directory /path/to/paperless-mcp paperless-mcp

For Claude Desktop, add this to claude_desktop_config.json:

{
  "mcpServers": {
    "paperless": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/paperless-mcp", "paperless-mcp"],
      "env": {
        "PAPERLESS_URL": "https://paperless.example.com",
        "PAPERLESS_TOKEN": "your-api-token"
      }
    }
  }
}

Tools

Tool

What it does

search_documents

Full-text search (tantivy syntax) or documents similar to one, plus filters for title, content, tags (all, any, or none of them, or whether it has any), the inbox, correspondent, document type, and storage path (by ID, or whether one is set), custom field values, and dates

get_document

One document's full metadata, with its notes, custom field values, and optional inline text content

list_tags

Tags, filterable by name or IDs

list_correspondents

Correspondents with the date of their newest document, filterable by name or IDs

list_document_types

Document types, filterable by name or IDs

list_storage_paths

Storage paths, filterable by name or IDs

list_custom_fields

Custom field definitions with the options of select fields, filterable by name or IDs

Every tool declares itself read-only to the client, with the MCP read_only_hint annotation and a read tag. The ids filter on the list tools resolves the IDs on a document back to names.

Every document result includes a uri like paperless://documents/42 that can be read as an MCP resource, and a web_url that opens the document in the Paperless web UI.

The custom_field_query filter on search_documents takes a list of conditions, each a custom field, an operator, and a value, and matches documents that meet all of them or any of them. It supports every operator of Paperless's custom field query except NOT, nested groups, and date-part operators like year__exact. It needs paperless-ngx 2.13 or later.

When Paperless refuses a request, the tool's error carries Paperless's own explanation, such as Paperless returned 404: No Document matches the given query. Other unexpected errors reach the client without their details. The server gives up on a request to Paperless after 30 seconds.

Resources

Resource

Contents

paperless://documents/{id}

The document's full text

paperless://documents/{id}/thumbnail

A WebP thumbnail of the first page

paperless://documents/{id}/notes

The document's notes, as a JSON list

Security

This server is read-only by construction: it only ever issues GET requests to paperless-ngx, and it exposes no way to create, modify, or delete documents. It performs no authentication of its own. Anyone who can reach the running server can read whatever the configured token can read, so treat the token accordingly and run the server close to where you use it.

Available Tools

7 tools
get_documentGet documentA
Read-only

Get a single document's full metadata, with its notes and custom fields.

The preferred way to read a document's text is its MCP resource at paperless://documents/{document_id}.

NameRequiredDescriptionDefault
document_idYesThe document's ID, from search_documents (required)
include_contentNoWhether to include the full text content. Pass true only if you cannot read MCP resources (default: false)

Output Schema

NameRequiredDescription
idYes
uriYesMCP resource URI for the document's full text content
tagsYesTag IDs, resolvable with list_tags(ids=[...])
addedYesWhen the document entered the archive
notesNo
titleYes
contentNoFull text content, included only when requested
createdYesThe date on the document itself
web_urlNoLink to open this document in the Paperless web UI
modifiedYes
mime_typeNo
page_countNo
search_hitNoPresent only on results of a full-text query
storage_pathYesStorage path ID, resolvable with list_storage_paths(ids=[...])
correspondentYesCorrespondent ID, resolvable with list_correspondents(ids=[...])
custom_fieldsNo
document_typeYesDocument type ID, resolvable with list_document_types(ids=[...])
original_file_nameNo
archive_serial_numberNo

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds what the payload contains (metadata, notes, custom fields) and that text access is better served elsewhere, but says nothing about error behavior for a missing/inaccessible document ID.

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 short sentences, zero waste, with the primary action stated first and the alternative path second. Nothing to trim.

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?

Output schema exists so return shape needs no explanation, and annotations carry the safety profile. The description still covers what is returned and how it relates to the resource path, leaving no actionable gap for calling it correctly.

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 both parameters are documented, including the default and the 'only if you cannot read MCP resources' caveat for include_content. The description restates that resource preference rather than adding new parameter detail, so baseline 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 and resource with explicit scope: 'a single document's full metadata, with its notes and custom fields.' This clearly separates it from the search_/list_ siblings, which operate over collections rather than one document.

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?

Gives explicit routing guidance: use the MCP resource at paperless://documents/{document_id} as the preferred way to read text, i.e. when-not to use this tool's content path. That is a genuine alternative with a selection condition, not just context.

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

list_correspondentsList correspondentsA
Read-only

List correspondents: the people and organizations that documents are from or to.

Use the returned IDs with search_documents(correspondent_id=...).

NameRequiredDescriptionDefault
idsNoReturn only the correspondents with these IDs (default: none)
pageNoPage number, starting at 1 (default: 1)
page_sizeNoNumber of correspondents per page (default: 100)
name_containsNoCase-insensitive substring of the name (default: none)

Output Schema

NameRequiredDescription
paginationYesThe position of one page of results in the full result set.
correspondentsYes

TDQS

A3.6/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety and scope are covered externally. The description adds only that IDs are intended for search_documents lookups; it says nothing about ordering, completeness of the listing, or pagination behavior beyond what the schema already encodes.

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 short sentences, zero filler, with the entity definition front-loaded and the follow-up pattern second. Nothing could be removed without losing information.

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?

With full schema coverage, an output schema, and annotations covering the safety profile, the description is complete enough to call correctly. The only missing element is guidance on which filter (name_contains vs. ids) to reach for, which is minor given the schema.

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 every parameter (ids, page, page_size, name_contains) is documented in the schema, so the baseline of 3 applies. The description adds no meaning beyond the schema – notably it does not explain that name_contains is a case-insensitive substring or that ids can batch lookups.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (correspondents), and defines the entity as 'the people and organizations that documents are from or to,' which makes it distinguishable from sibling list_* tools covering tags, types, and paths. It does not explicitly name any sibling it is not, so it falls short of a 5.

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 second sentence gives a downstream usage pattern ('Use the returned IDs with search_documents(correspondent_id=...)'), which implies why and when to call this tool, but there is no explicit when-to-use vs. alternative guidance and no mention of when not to call it or how to narrow results with name_contains.

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

list_custom_fieldsList custom fieldsA
Read-only

List the custom fields defined in the archive.

get_document returns a document's custom field values by field ID. A select field's value is the id of one of the field's select_options. Search custom field values with search_documents, using a query like "custom_fields.value:overdue".

NameRequiredDescriptionDefault
idsNoReturn only the custom fields with these IDs (default: none)
pageNoPage number, starting at 1 (default: 1)
page_sizeNoNumber of custom fields per page (default: 100)
name_containsNoCase-insensitive substring of the name (default: none)

Output Schema

NameRequiredDescription
paginationYesThe position of one page of results in the full result set.
custom_fieldsYes

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuine domain context beyond that: select fields carry select_options and their values are option IDs, which an agent needs to interpret results. It omits pagination/ordering behavior, but that is largely schema-covered, so a 4 is fair.

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?

Purpose is front-loaded in the first sentence, followed by tightly related data-model and search guidance. Slightly sprawling across three topics with line breaks in odd places, but every sentence carries information.

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?

With an output schema present, return values needn't be explained, and the description fills the remaining gaps: what a custom field value looks like and how to search by it. Minor omission of result ordering/limits keeps it from a 5.

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%, with ids, name_contains, page, and page_size all documented inline including defaults. The description adds nothing about parameter syntax or interactions, so the schema carries it and the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb and resource ("List the custom fields defined in the archive") that is immediately distinguishable from siblings like list_tags and list_correspondents by the resource name alone. It doesn't explicitly name an alternative list tool, so it stops short of a 5, but the scope is unambiguous.

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?

It explicitly routes the agent: use get_document to read a document's field values by field ID, and use search_documents with a concrete query example ("custom_fields.value:overdue") to find documents by field value. These are concrete when-to-use-this-vs-siblings signals with a worked example.

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

list_document_typesList document typesA
Read-only

List document types, like invoice or receipt.

Use the returned IDs with search_documents(document_type_id=...).

NameRequiredDescriptionDefault
idsNoReturn only the document types with these IDs (default: none)
pageNoPage number, starting at 1 (default: 1)
page_sizeNoNumber of document types per page (default: 100)
name_containsNoCase-insensitive substring of the name (default: none)

Output Schema

NameRequiredDescription
paginationYesThe position of one page of results in the full result set.
document_typesYes

TDQS

A3.9/5.0
Behavior3/5

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

Annotations already declare this is a safe read (readOnlyHint=true) over a closed dataset (openWorldHint=false), so the safety profile needs no restating. The description adds that the meaningful output is IDs for reuse elsewhere, but says nothing about pagination defaults, result-set size, or filtering behavior that would set expectations for a large instance.

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 short sentences, zero waste, with purpose front-loaded and the consumption pattern immediately after. Nothing here could be removed without losing information.

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?

All four parameters are optional and fully described in the schema, an output schema exists so return values need no narrative, and annotations cover the safety profile. Purpose plus the routing hint to search_documents is everything an agent needs to call this correctly.

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 ids, name_contains, page, and page_size are already fully documented with defaults and semantics. The description mentions none of them, adding no meaning beyond the schema. Baseline 3 applies when the schema carries the full parameter burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("List document types") and grounds it with concrete examples ("like invoice or receipt"), so an agent knows exactly what taxonomy entities come back. Sibling list_* tools cover different resources, so no explicit differentiation is required, but it also doesn't confirm the relationship to those siblings.

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 second sentence gives actionable downstream guidance: use the returned IDs with search_documents(document_type_id=...). That establishes the tool's role as a lookup/enumeration prerequisite for search. It stops short of stating when not to call it or that calling it is optional if the agent already knows the type ID.

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

list_storage_pathsList storage pathsA
Read-only

List storage paths: the filing locations of documents.

Use the returned IDs with search_documents(storage_path_id=...).

NameRequiredDescriptionDefault
idsNoReturn only the storage paths with these IDs (default: none)
pageNoPage number, starting at 1 (default: 1)
page_sizeNoNumber of storage paths per page (default: 100)
name_containsNoCase-insensitive substring of the name (default: none)

Output Schema

NameRequiredDescription
paginationYesThe position of one page of results in the full result set.
storage_pathsYes

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds a workflow pointer (IDs are filter inputs elsewhere) but says nothing about ordering, total counts, or default behavior of an unfiltered call beyond what the schema shows.

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 short sentences with zero filler; the purpose comes first and the follow-up action second. Nothing could be removed without losing information.

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?

An output schema exists and annotations cover safety, so the description only needs purpose plus routing, both of which are present. A minor gap is whether pagination matters in practice (e.g., common number of paths), but nothing essential for correct invocation 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%, so ids, page, page_size, and name_contains are all documented inline with defaults and semantics. The description adds no parameter-level meaning beyond the mention of storage_path_id as a downstream filter, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("List storage paths") and clarifies the concept for anyone unfamiliar with Paperless-style data: "the filing locations of documents." The resource is distinct from siblings list_tags/list_correspondents/list_document_types, though it doesn't explicitly say so.

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?

Gives a clear downstream usage context: the returned IDs feed search_documents(storage_path_id=...), which tells the agent why and when to call this tool first. It doesn't state when not to use it or how to choose among the other list_* taxonomies, but the pattern is evident.

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

list_tagsList tagsA
Read-only

List tags.

Use the returned IDs with search_documents(tag_ids=[...]).

NameRequiredDescriptionDefault
idsNoReturn only the tags with these IDs, such as the tags on a document (default: none)
pageNoPage number, starting at 1 (default: 1)
page_sizeNoNumber of tags per page (default: 100)
name_containsNoCase-insensitive substring of the name (default: none)

Output Schema

NameRequiredDescription
tagsYes
paginationYesThe position of one page of results in the full result set.

TDQS

A3.6/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds the useful fact that IDs are meant to be fed into search_documents, but says nothing about pagination behavior, result ordering, or what happens when no tags match — though the schema covers paging and an output schema exists.

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 short sentences with zero filler; the purpose is front-loaded and the follow-up action comes second. Nothing would be lost by trimming because there is nothing extraneous.

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?

With a full output schema and complete parameter documentation, the description only needs to convey purpose and the key integration point, both of which it does. The only gap is guidance on choosing among the sibling list_* tools.

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%, with ids, page, page_size, and name_contains all documented in the schema itself. The description implies the ids align with document tags via the search_documents reference but adds no new syntax or filtering semantics beyond that. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("List tags"), which unambiguously distinguishes it from most siblings like search_documents and get_document. It doesn't explicitly contrast with list_custom_fields or list_correspondents, but the resource noun alone is enough to disambiguate.

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 second sentence gives a clear downstream usage (use returned IDs with search_documents(tag_ids=[...])), which is genuinely helpful routing. However, it says nothing about when to call this tool versus the other list_* siblings, nor any prerequisites or exclusions.

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

search_documentsSearch documentsA
Read-only

Search and filter documents in the archive.

All parameters combine as AND conditions, except that query and more_like_document_id cannot be used together. query is full-text search over document contents using tantivy syntax: plain terms ("electric bill"), boolean operators ("chase AND (mortgage OR escrow)"), field prefixes ("correspondent:university", "type:invoice", "tag:unpaid", "created:[2020 to 2023]"), and wildcards ("electr*"). Notes and custom fields are structured fields with dotted paths: "notes.note:reimbursed", "custom_fields.value:overdue", "custom_fields.name:warranty". Plain terms do NOT match them, only titles and content. Full-text results include a search_hit with highlights.

more_like_document_id finds documents whose text is similar to one document's, ranked by similarity in search_hit.rank. The results leave out that document itself, and the other filters narrow them. Leave ordering unset to keep the ranking.

To find unfiled documents, use is_in_inbox=true, or has_tags, has_correspondent, has_document_type, or has_storage_path set to false.

custom_field_query compares custom field values, like "Amount over 100" or "Warranty Expires before 2027-01-01". Every field type supports exact, in, exists, and isnull. Date, integer, float, and monetary fields add gt, gte, lt, lte, and range. String, URL, long text, and monetary fields add icontains, istartswith, and iendswith. Document link fields add contains. Paperless refuses an operator that the field's type does not support.

Each result carries a uri, which you can read as an MCP resource for the document's full text, and a web_url that links to the document in the Paperless web UI. Read paperless://documents/{id}/notes for a document's notes, or call get_document for its notes and custom field values.

NameRequiredDescriptionDefault
pageNoPage number, starting at 1 (default: 1)
queryNoFull-text query in tantivy syntax, described above (default: none)
tag_idsNoMatch documents that have ALL of these tags (default: none)
has_tagsNotrue matches documents with at least one tag, and false matches documents with no tags (default: none)
orderingNoField to sort by. Prefix it with "-" for descending order, like "-created". Without it, full-text results are ranked by relevance (default: none)
page_sizeNoNumber of documents per page (default: 25)
added_afterNoMatch documents added to the archive at or after this ISO 8601 date and time (default: none)
any_tag_idsNoMatch documents that have at least one of these tags (default: none)
is_in_inboxNotrue matches documents with at least one inbox tag, and false matches documents with none (default: none)
added_beforeNoMatch documents added to the archive at or before this ISO 8601 date and time (default: none)
created_afterNoMatch documents dated on or after this date, as YYYY-MM-DD (default: none)
created_beforeNoMatch documents dated on or before this date, as YYYY-MM-DD (default: none)
title_containsNoCase-insensitive substring of the title (default: none)
storage_path_idNoMatch documents filed under this storage path (default: none)
content_containsNoCase-insensitive substring of the text content (default: none)
correspondent_idNoMatch documents from or to this correspondent (default: none)
document_type_idNoMatch documents of this type (default: none)
excluded_tag_idsNoMatch documents that have NONE of these tags (default: none)
has_storage_pathNotrue matches documents with a storage path, and false matches documents without one (default: none)
has_correspondentNotrue matches documents with a correspondent, and false matches documents without one (default: none)
has_document_typeNotrue matches documents with a document type, and false matches documents without one (default: none)
custom_field_queryNoConditions on custom field values, described above. Name each field by its ID or exact name from list_custom_fields (default: none)
more_like_document_idNoMatch documents similar to the document with this ID. Cannot be combined with query (default: none)

Output Schema

NameRequiredDescription
documentsYes
paginationYesThe position of one page of results in the full result set.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only declare read-only and closed-world; the description adds much more: all filters combine as AND, `query` and `more_like_document_id` are mutually exclusive, similarity results exclude the seed document and are ranked in search_hit.rank unless `ordering` is set, and 'Paperless refuses an operator that the field's type does not support'. These are non-obvious behavioral constraints an agent could not infer from the annotations.

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 purpose and the AND/mutual-exclusion rules, then organized into paragraphs per parameter family, which is appropriate for a 23-parameter tool. It loses a point because the custom_field_query paragraph restates operator-by-type rules the schema already enumerates at length, and the final paragraph about uri/web_url borders on return-value explanation that the output schema covers.

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?

For a 23-parameter search tool with an output schema, the description covers the semantics that actually determine correct invocation: filter combination logic, query syntax, the query/more_like_document_id exclusion, ranking behavior, and the unfiled-document shortcut. Nothing an agent needs in order to construct a correct call is missing.

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

Parameters5/5

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

Schema coverage is 100%, so the baseline would be 3, but the description adds meaning the schema cannot express: concrete tantivy syntax with worked examples, the field prefixes available (correspondent, type, tag, created), the crucial caveat that 'Plain terms do NOT match' notes and custom fields, and dotted-path syntax for structured fields. That is well beyond what the JSON Schema conveys.

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?

Opening sentence states a specific verb and resource with scope ('Search and filter documents in the archive'), immediately telling the agent this is a query tool over the whole archive rather than a per-document fetch. It also names the sibling it is not ('call get_document for its notes and custom field values'), so it is distinguishable from get_document without opening either schema.

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?

Gives real routing guidance: 'To find unfiled documents, use is_in_inbox=true, or has_tags, has_correspondent... set to false', and 'Leave `ordering` unset to keep the ranking'. It also redirects to get_document / the notes resource when the agent wants notes or custom field values. What is missing is an explicit statement of when to prefer this over a direct get_document lookup by ID, so it stops just short of full when/when-not coverage.

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.

  1. 7 tool updatesv0.1.0
    • First observedget_document
    • First observedlist_correspondents
    • First observedlist_custom_fields
    • First observedlist_document_types
    • First observedlist_storage_paths
    • First observedlist_tags
    • First observedsearch_documents

TDQS

A4/5.0

Scored across 7 tools

Disambiguation5/5

Each tool targets a distinct operation: one broad search, one document fetch, and five entity-specific listers. The list_* tools could superficially look alike, but each names a clearly different Paperless resource and explicitly cross-references the corresponding search parameter, leaving no realistic misselection risk.

Naming Consistency5/5

All tools follow a clean verb_noun snake_case pattern (search_documents, get_document, list_tags, list_correspondents, list_document_types, list_storage_paths, list_custom_fields). No mixed casing or stray verbs.

Tool Count5/5

Seven tools is well-scoped: one flexible search, one detail fetcher, and the minimum set of lookup tools needed to resolve IDs for filtering. Nothing appears redundant or padding the surface.

Completeness3/5

The surface is entirely read-only: search, get, and list exist but there is no upload_document, update_document, delete_document, or create/update for tags, correspondents, document types, storage paths, or custom fields. Core retrieval workflows are covered, but lifecycle operations for a document management archive are notably absent.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    An Agentic RAG MCP Server that transforms Paperless-ngx into a conversational document assistant, enabling LLMs to search, filter, and summarize documents using natural language.
    4
    GPL 3.0
  • F
    license
    A
    quality
    B
    maintenance
    A privacy-first MCP server for Paperless-ngx that lets an LLM agent search, organize, tag, and reference documents without exposing full text unless explicitly requested.
    13
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    A read-only and write MCP server for Paperless-ngx, enabling document listing, metadata retrieval, and creation of tags, correspondents, document types, and sorting workflows via natural language.
    MIT