Skip to main content
Glama
smeet666

mcp-stashbox

Search studios

search_studios
Read-only

Search studios across configured stash-box catalogues using text queries or typed filters, with per-catalogue results and counts kept separate.

Instructions

Search studios across every configured stash-box catalogue. Two exclusive paths: 'query' runs each catalogue's own text index, which reads the words as a union, and the typed arguments narrow as an intersection. Writing both is refused. The answer says per catalogue which of three it met: a failure, a catalogue nobody asked, and an emptiness it established. Counts are never added across them.

Input Schema

NameRequiredDescriptionDefault
nameNo
pageNoWhich page of its own order every catalogue asked is read at, counted from 1. A search written with words alone reads the first rows each text index answers with, since those routes take no page.
sortNo
limitNoHow many rows one page of one catalogue carries. An answer holding several carries up to this many from each: their pages are their own and nothing here interleaves them into one.
queryNoWords for the catalogue's own text index, which reads them as a union. It is exclusive with the typed arguments, which narrow as an intersection.
sourcesNo
directionNo
parent_idNo
has_parentNo

Output Schema

NameRequiredDescriptionDefault
notesYes
cachedNoReplayed from this client's store.
windowNoThe page and the row limit this answer was read at, absent where no catalogue answered.
resultsYes
orderingYesHow the rows were laid out, which a reader needs before reading the first.
per_sourceYes
result_countYesHow many rows this page carries.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changedv2.1.0
    • removedOutput schema / properties / results / items / properties / name / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / results / items / properties / name / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / results / items / properties / parent / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "id": {
      -        "type": "string"
      -      },
      -      "name": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "status": {
      -        "enum": [
      -          "established",
      -          "merged",
      -          "deleted"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "id",
      -      "name",
      -      "status"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "id": {
      +        "type": "string"
      +      },
      +      "name": {
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "status": {
      +        "enum": [
      +          "established",
      +          "merged",
      +          "deleted"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "id",
      +      "name",
      +      "status"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / results / items / properties / pending_edits / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / results / items / properties / pending_edits / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / results / items / properties / scene_count / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / results / items / properties / scene_count / type
      Added value: +[
      +  "number",
      +  "null"
      +]
  2. Changed19 schema fields changedv1.0.0
    • changedInput schema / properties / limit / description
      Previous value: -"How many rows one page of one catalogue carries. An answer holding several catalogues carries up to this many from each of them, since their pages are their own and nothing here interleaves them into one."New value: +"How many rows one page of one catalogue carries. An answer holding several carries up to this many from each: their pages are their own and nothing here interleaves them into one."
    • changedInput schema / properties / page / description
      Previous value: -"The page of each catalogue's own order. A route that reads words alone takes no page, and the answer reports it as one that catalogue did not receive."New value: +"Which page of its own order every catalogue asked is read at, counted from 1. A search written with words alone reads the first rows each text index answers with, since those routes take no page."
    • changedOutput schema / properties / per_source / items / properties / index_total / description
      Previous value: -"What its own index holds for this question, the rows on this page included."New value: +"What its own index holds for the question it received, the rows on this page included. A narrowing it could not receive, or received in part, leaves that question wider than the one written."
    • changedOutput schema / properties / per_source / items / properties / narrowings_not_received / description
      Previous value: -"Narrowings this catalogue cannot receive. This is the one field that says a catalogue cannot do something."New value: +"Narrowings that shaped no part of the request this catalogue received, whether its route declares no field for one or nothing written was left for one to decide."
    • addedOutput schema / properties / per_source / items / properties / narrowings_received_in_part / description
      Added value: +"Narrowings it received short of what was written, the rest of the list naming records another catalogue minted. It answered a wider question than the one asked."
    • addedOutput schema / properties / results / items / properties / aliases
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / results / items / properties / also_held_at
      Added value: +{
      +  "description": "The same record on another catalogue, read from a link this one publishes to it. A shared name is no join.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "id": {
      +        "type": "string"
      +      },
      +      "source": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "source",
      +      "id"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / results / items / properties / linked_unfollowed
      Added value: +{
      +  "description": "A link to another catalogue naming the record by something this client cannot address. The link is written, and following it is what failed.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "source": {
      +        "type": "string"
      +      },
      +      "url": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "source",
      +      "url"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / results / items / properties / name
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / results / items / properties / parent
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "id": {
      +          "type": "string"
      +        },
      +        "name": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "status": {
      +          "enum": [
      +            "established",
      +            "merged",
      +            "deleted"
      +          ],
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "id",
      +        "name",
      +        "status"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "The studio this one sits under, where its catalogue records one."
      +}
    • addedOutput schema / properties / results / items / properties / pending_edits
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Edits open against it, null where its catalogue publishes no such count."
      +}
    • addedOutput schema / properties / results / items / properties / pending_edits_unreadable
      Added value: +{
      +  "description": "The count of open edits came back in a shape this client could not read.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / results / items / properties / retrieved_at
      Added value: +{
      +  "description": "The moment this client read it there.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / results / items / properties / rows_skipped
      Added value: +{
      +  "description": "Entries of this record's own lists that could not be read and are left out.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / results / items / properties / rows_skipped_in
      Added value: +{
      +  "description": "Which of its lists lost them.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / results / items / properties / scene_count
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Scenes this one catalogue indexes on it, null where it publishes no such count. Never added to another catalogue's."
      +}
    • addedOutput schema / properties / results / items / properties / status / description
      Added value: +"What the identifier addresses on that catalogue now. A folded record answers with a marker, which describes the record and never what it once named."
    • changedOutput schema / properties / results / items / required
      Previous value: -[
      -  "id",
      -  "source",
      -  "source_url",
      -  "status"
      -]New value: +[
      +  "id",
      +  "source",
      +  "source_url",
      +  "retrieved_at",
      +  "status",
      +  "also_held_at",
      +  "linked_unfollowed",
      +  "name",
      +  "aliases",
      +  "parent",
      +  "scene_count"
      +]
    • changedOutput schema / properties / window / description
      Previous value: -"The page a catalogue paged through, absent where none was given one."New value: +"The page and the row limit this answer was read at, absent where no catalogue answered."
  3. Addedv0.9.0

TDQS

A3.5/5.0
Behavior4/5

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

Annotations cover read-only and open-world, and the description adds genuinely non-obvious behavior: per-catalogue results in three distinct states, no cross-catalogue aggregation of counts, and rejection of combined query+typed-args requests. The phrasing of the three states is oblique ('a catalogue nobody asked') but the disclosure is substantive.

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

Conciseness3/5

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

Front-loaded and free of filler, but the prose turns oracular in places ('an emptiness it established', 'which of three it met'), forcing the reader to decode rather than read. The exclusivity rule, arguably the most important constraint, is buried mid-paragraph.

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

Completeness3/5

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

An output schema exists, so explaining return format is optional, yet the description chooses to describe result semantics while omitting how sources default and whether any filters are mandatory. For a 9-parameter multi-catalogue search this leaves meaningful gaps.

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?

With only 33% schema coverage across 9 parameters, the description needs to compensate; it explains query versus typed-argument semantics well but says nothing about name, sources (defaulting, selection), sort/direction per catalogue, or parent_id/has_parent filtering. Schema handles page and limit; the rest is left thin.

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 names a specific verb (search) and resource (studios) and scopes it to stash-box catalogues, which differentiates it from the scene/performer/tag search siblings by resource alone. It stops short of explicitly contrasting itself with get_studio or naming which sibling handles what.

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 clearly states the mutual exclusivity of 'query' and the typed arguments and that writing both is refused, which is real usage guidance. It gives no guidance on when to prefer this tool over search_scenes or get_studio, nor when each path is the better choice beyond the union/intersection hint.

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