> For the complete documentation index, see [llms.txt](https://docs.durohub.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.durohub.com/ai-integration/tools.md).

# Tool Reference

Every tool the [Duro MCP server](/ai-integration/mcp.md) exposes. You never call these by name — you describe what you want and the assistant chooses. They're listed here so you know what's possible, and so you can tell what happened after the fact.

**Read** tools only look. **Write** tools change something in your library, attributed to you.

## Library

| Tool                 |      | What it does                                                             |
| -------------------- | ---- | ------------------------------------------------------------------------ |
| `duro_library_get`   | Read | Which library the connection is scoped to, and its organization          |
| `duro_category_list` | Read | Every category in the library — Resistor, PCBA, Fastener, and so on      |
| `duro_status_list`   | Read | Lifecycle statuses and what each maps to (Design, Production, Obsolete…) |

Categories and statuses are per-library and configurable, so the assistant reads them rather than assuming. If you ask for "parts in production" and your library calls that status something else, this is how it finds out.

## Search

Three tools, in descending order of how often they're the right one.

| Tool                    |      | What it does                                                                                  |
| ----------------------- | ---- | --------------------------------------------------------------------------------------------- |
| `duro_component_search` | Read | Natural language. "Resistors in production changed this month"                                |
| `duro_component_query`  | Read | The [structured query syntax](/advanced-topics/search-query-syntax.md), or a bare keyword     |
| `duro_component_list`   | Read | Name (partial match), exact CPN, category, category type, lifecycle status, or your bookmarks |

`duro_component_search` is the default. It handles anything conversational, resolves names of people and statuses and categories for you, and understands relative dates.

`duro_component_query` is for when the search is already precise — `type:part status:Design modifiedBy:"Sarah Chen"`. It parses deterministically, so it's faster and doesn't cost an AI call. A bare word is a text search across name, CPN, and description. It also takes the [sourcing keys](/advanced-topics/search-query-syntax.md#sourcing-keys), so "parts we get from Acme" becomes `vendor:acme` and finds Acme parts even when Acme isn't in the name or description.

`duro_component_list` is the cheapest of the three, for when you already have a CPN or a category name in hand. Its status filter takes the lifecycle stage — Design, Development, Production, Maintenance, Obsolete — not your library's own status names.

### Reading a search result

Search results carry a `search` block describing what was actually searched, separate from the rows themselves. It matters more than it sounds like it should.

Both search backends **drop the part of a query they can't resolve and run the rest**, rather than failing it. Ask for resistors modified by someone who isn't a member of the library and you don't get an error — you get every resistor, with a note that the name went unmatched. Ask with a typo in a status name and that condition is dropped, returning more than you meant.

If nothing in the query resolves, so the search would return the whole library, it is refused instead and the assistant tells you why.

So the block reports:

* **`interpretation`** — how the query was read, in plain English
* **`applied`** — the filters that actually ran
* **`notice`** — present only when part of your question didn't land, saying so in words

A good assistant relays the notice before presenting the rows. If yours doesn't, `applied` is the ground truth: compare it against what you asked for.

{% hint style="warning" %}
An unmatched name is sometimes replaced with the closest one that does exist, not dropped. Asking for "parts modified by John Smith" in a library that has a John Griffin can return John Griffin's parts. The `applied` list is what tells you — it will name Griffin, not Smith.
{% endhint %}

## Components

| Tool                      |       | What it does                                                         |
| ------------------------- | ----- | -------------------------------------------------------------------- |
| `duro_component_get`      | Read  | Full record for one component, by CPN                                |
| `duro_component_create`   | Write | Create a component. Needs a category name                            |
| `duro_component_update`   | Write | Update name, description, status, category, attributes, or thumbnail |
| `duro_component_bookmark` | Write | Set or clear your own bookmark on a component                        |
| `duro_validate`           | Read  | Run Duro's own validation rules without saving anything              |

`duro_validate` runs the same checks the web app runs — field limits, category and status existence, attribute types, name uniqueness, revision format — and returns every problem at once, each with a field path and a fix. Worth asking for explicitly before a bulk change: *"validate these 40 rows against duro before creating anything."*

## Assemblies

| Tool                          |       | What it does                                    |
| ----------------------------- | ----- | ----------------------------------------------- |
| `duro_assembly_list`          | Read  | Components that have a BOM                      |
| `duro_assembly_bom`           | Read  | Bill of materials for an assembly, with nesting |
| `duro_assembly_link_children` | Write | Add child components to an assembly's BOM       |

Assemblies are components, so everything in the Components section applies to them too. `duro_assembly_bom` walks the hierarchy — ask for a specific depth if you don't want the whole tree.

## Change orders

| Tool                               |       | What it does                                                                        |
| ---------------------------------- | ----- | ----------------------------------------------------------------------------------- |
| `duro_change_order_template_list`  | Read  | The workflow templates this library offers                                          |
| `duro_change_order_list`           | Read  | Change orders, by status or resolution, or only those awaiting your review          |
| `duro_change_order_get`            | Read  | Full detail — stages, reviewers, items, submission status                           |
| `duro_change_order_create`         | Write | Create a change order, in DRAFT                                                     |
| `duro_change_order_add_items`      | Write | Add components to a change order                                                    |
| `duro_change_order_submit`         | Write | Submit for review — DRAFT to OPEN                                                   |
| `duro_change_order_stage_review`   | Write | Approve or reject the current stage as one of its reviewers, with an optional note  |
| `duro_change_order_comment_create` | Write | Post a comment on the change order's Discussions tab. Everyone mentioned is emailed |

`duro_change_order_stage_review` records a real decision: it can end the stage, resolve or close the change order, and an approval of the last stage can start a release. The assistant previews what your decision will do and asks you to confirm before recording it. Ask *"what's waiting on my review?"* to find the change orders it applies to.

{% hint style="info" %}
If your library has more than one workflow template, creating a change order **asks you which one** rather than guessing. The template decides who reviews the change and what has to be approved before anything releases, and it can't be corrected by editing the change order afterwards — so it's not a decision worth defaulting.
{% endhint %}

## Files and documents

| Tool                        |       | What it does                                    |
| --------------------------- | ----- | ----------------------------------------------- |
| `duro_file_upload_request`  | Write | Request signed upload URLs, singly or in batch  |
| `duro_file_upload_confirm`  | Write | Confirm the upload completed                    |
| `duro_document_link_create` | Write | Link a document component to a part or assembly |

Uploading is three steps: request the signed URL, send the file to it, then confirm. On the hosted server (`mcp.durohub.com`) the middle step is your client's job, because the server cannot read files on your machine — so attaching a file needs a client that can upload to the signed URL itself, as Claude Code can. Batches upload in parallel.

## What isn't here

The MCP server covers component, assembly, change order, and document workflows. Editing sourcing, webhooks, RBAC administration, and library configuration are API-only for now — see [Core Concepts](/core-concepts/components.md) and [Advanced Topics](/advanced-topics/rbac.md).

Anything the assistant can do here, you can do directly against the [GraphQL API](/getting-started/introduction.md). The MCP server is a front end to the same API, with the same permissions.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.durohub.com/ai-integration/tools.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
