Skip to main content
Glama

SansFiction MCP & Agent Skill

sansfiction-mcp MCP server

Connect AI agents to SansFiction — a digital library for books, collections, reading journals, and discovery.

The same capabilities are exposed two ways, both authenticated with the same bearer token:

  • MCP server (Streamable HTTP): https://sansfiction.com/api/mcp

  • REST API (v1): https://sansfiction.com/api/v1

Quick start (MCP)

claude mcp add --transport http sansfiction https://sansfiction.com/api/mcp

Or point any MCP client at the streamable-HTTP endpoint above. Public catalog tools need no auth; personal library tools require a bearer token (generate one at sansfiction.com/docs/agents).

Related MCP server: Personal Research Assistant MCP

Quick start (REST)

# Public catalog — no auth
curl "https://sansfiction.com/api/v1/catalog/search?q=dune&limit=5"

# Personal library — bearer token
curl -H "Authorization: Bearer $SF_TOKEN" \
  "https://sansfiction.com/api/v1/library/books?status=reading"

Capabilities

Public catalog (no auth)

  • GET /api/v1/catalog/search?q=…&searchType=all|author|series|mood|isbn

  • GET /api/v1/catalog/books/{bookId}

  • GET /api/v1/catalog/series/{seriesId}

  • GET /api/v1/catalog/collections

Personal library (bearer token)

  • GET/POST /api/v1/library/books · PATCH/DELETE /api/v1/library/books/{bookId}

  • GET /api/v1/library/search

  • GET /api/v1/library/collections · GET /api/v1/library/collections/{id} · POST …/items

  • GET /api/v1/library/stats

Discovery

  • Agent Skill: SKILL.md — also served at https://sansfiction.com/.well-known/agent-skills/sansfiction-catalog/SKILL.md

  • MCP Registry manifest: server.json

  • OpenAPI: https://sansfiction.com/openapi.json

  • MCP server card: https://sansfiction.com/.well-known/mcp/server-card.json

Authentication

Generate a personal access token (sf_mcp_…) while signed in at sansfiction.com/docs/agents. The same token authenticates both the MCP server and the REST API. Rate limits: 60 req/min anonymous, 180 req/min authenticated.

License

The SansFiction service is proprietary. This repository documents its public agent interface for discovery and integration.

Run locally as an MCP server (stdio)

This repo also ships a small stdio MCP server that proxies to the hosted REST API, so you can run it anywhere an MCP client expects a local command:

npx sansfiction-mcp
# or
npm install && node index.js

Environment variables:

  • SANSFICTION_TOKEN — bearer token (sf_mcp_…) for the personal-library tools (generate at https://sansfiction.com/docs/agents). Public catalog tools need none.

  • SANSFICTION_BASE_URL — override the API base (default https://sansfiction.com).

Tools: search_books, get_book, get_series, list_public_collections, list_my_books, add_book_to_library, update_library_book, remove_book_from_library, search_my_library, list_my_collections, get_reading_stats.

Glama build configuration

  • Build steps: ["npm install"]

  • CMD arguments: ["mcp-proxy","--","node","index.js"]

tools/list requires no network or credentials, so the introspection check passes without a token.

Available Tools

11 tools
add_book_to_libraryA
Idempotent

Add a catalog book to the user's library. Idempotent upsert — calling again with a different status moves the book to that shelf rather than erroring. When to use: put a catalog book (book_id from search_books) onto a shelf for the first time. To edit an existing entry's status/rating/review/progress use update_library_book; to take a book off entirely use remove_book_from_library. Requires SANSFICTION_TOKEN (a bearer token from https://sansfiction.com/docs/agents).

ParametersJSON Schema
NameRequiredDescriptionDefault
statusNoShelf to place the book on. Default 'want' (to-read).
book_idYesCatalog book UUID (the `id` from search_books).
edition_idNoOptional specific edition UUID to associate with this library entry.

TDQS

A4.7/5.0
Behavior5/5

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

The description adds value beyond annotations by explaining the idempotent upsert behavior in detail and disclosing the required authentication token. Annotations already provide idempotentHint, but the description enriches it with the exact semantics of calling again with a different status. No contradictions.

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 concise, front-loading the core purpose and idempotent behavior, then providing usage guidelines, alternatives, and authentication info. Every sentence adds value, and the structure is logical.

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?

Given the tool's moderate complexity (3 parameters, no output schema), the description covers all necessary aspects: purpose, behavior, when to use, alternatives, and auth requirements. No gaps remain for an agent to invoke the tool 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%, so the baseline is 3. The description adds minimal extra meaning beyond the schema (e.g., mentions 'book_id from search_books' and 'Default 'want'' which are already in the schema). Credit for context but no significant enrichment.

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 clearly states the action ('Add a catalog book to the user's library') and specifies the resource. It distinguishes from sibling tools by mentioning alternative update and removal operations, making the purpose 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?

Explicitly states when to use ('put a catalog book...onto a shelf for the first time') and provides clear alternatives: use update_library_book for edits and remove_book_from_library for deletion. This gives the agent precise decision criteria.

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

get_bookA
Read-only

Get full public metadata for a single book by catalog UUID or slug. Returns { book } (title, authors, description, editions, series, identifiers). Returns a 404 error if not found. When to use: you already have a book_id or slug and need details/editions. If you only have a title or author, call search_books first to obtain the id.

ParametersJSON Schema
NameRequiredDescriptionDefault
book_idYesCatalog book UUID or slug, as returned in `id`/`slug` by search_books.
edition_idNoOptional edition UUID to resolve a specific edition (language, cover, ISBN) instead of the default/primary edition.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, so description's burden is lower. Description adds useful error behavior (404 if not found) and optional parameter effect (edition_id resolves to specific edition). No contradictions.

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?

Three sentences: first states purpose and return structure, second covers error behavior, third provides usage guidance with alternative. No filler, all information is essential and well-organized.

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 simple single-item retrieval tool, the description covers purpose, parameters, return structure (though no output schema, it lists fields), error case, and usage context. No gaps given the tool's complexity.

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%, baseline 3. Description adds value by explaining that book_id comes from search_books, and edition_id resolves to a specific edition with details (language, cover, ISBN). This goes beyond the schema's brief descriptions.

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?

Clearly states verb 'Get', resource 'full public metadata for a single book', and method 'by catalog UUID or slug'. Distinguishes from siblings like search_books (searching) and get_series (series info).

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?

Explicitly specifies when to use: 'you already have a book_id or slug and need details/editions'. Provides alternative: 'If you only have a title or author, call search_books first to obtain the id.'

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

get_reading_statsA
Read-only

Reading statistics for a time range, matching the app's Stats page. Choose the range in ONE of two ways: (a) scope + date — e.g. scope='monthly', date='2026-03-15' covers that whole month; or (b) an explicit from+to pair, which OVERRIDES scope/date when both are given. Returns { range:{start,end}, booksFinishedCount, totalPagesRead, dailyAverage, logsCount, logs? }. dailyAverage is computed only for monthly/yearly scopes (null for weekly and for explicit from/to ranges). When to use: aggregate metrics (pages read, books finished, averages) over a period. To list the underlying books use list_my_books; to record progress that feeds these numbers use update_library_book with current_page. Requires SANSFICTION_TOKEN (a bearer token from https://sansfiction.com/docs/agents).

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoExplicit range end (ISO 8601 date). Must be paired with `from`.
dateNoAnchor date (ISO 8601 YYYY-MM-DD) selecting which week/month/year `scope` refers to. Default: today. Ignored when both `from` and `to` are supplied.
fromNoExplicit range start (ISO 8601 date). Must be paired with `to`; together they override `scope`/`date`.
scopeNoGranularity of the range relative to `date`. Default 'monthly'. Ignored when both `from` and `to` are supplied.
include_logsNoWhen true, include the raw reading-log entries (`logs[]`) in the response. Default false.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true (safe read) and openWorldHint=true (dynamic input). The description adds valuable behavior beyond annotations: it specifies that 'dailyAverage is computed only for monthly/yearly scopes (null for weekly and for explicit from/to ranges)', and that from+to overrides scope/date. It also mentions the auth requirement (SANSFICTION_TOKEN). However, it doesn't mention pagination or rate limits—minor gaps for a read-only stats tool with no output schema.

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 three sentences long without fluff, front-loading the primary purpose and delving into parameter interaction. It's slightly longer than necessary but each sentence adds value. The structure is logical: purpose → parameter usage → sibling differentiation → auth note.

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?

Given the tool's moderate complexity (5 params, 2 usage modes, enum scope), and the fact that annotations already cover readOnlyHint and openWorldHint, the description provides clear guidance on when and how to use the tool, what outputs to expect, and where to find alternative tools. No output schema exists, but the description describes the return shape in enough detail. The auth requirement is also noted. This is fully sufficient for an agent to invoke 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%—every parameter has a schema description. The description adds meaning by explaining the two usage patterns (scope+date vs from+to) and the interaction rules (overriding behavior). It also clarifies that 'dailyAverage' is null in certain scopes, which enriches the return semantics. However, it does not elaborate on default values or formatting details beyond what the schema states, keeping it at baseline 3.

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 clearly specifies the tool returns 'Reading statistics for a time range, matching the app's Stats page', giving both a verb ('get') and a specific resource (reading stats over a time range). It distinguishes itself from siblings like 'list_my_books' by noting that this is for aggregate metrics instead of listing individual books.

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?

The description explicitly states when to use this tool ('aggregate metrics') and when to use alternatives ('To list the underlying books use list_my_books; to record progress that feeds these numbers use update_library_book'). It also explains the two mutually exclusive ways to choose the range, which is a subtle usage constraint.

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

get_seriesA
Read-only

Get a book series and its ordered volumes by series UUID. Returns { series } including the volume list with positions. Returns a 404 error if the series is unknown. When to use: to enumerate every volume in a series and their reading order. Obtain series_id from a book's series metadata via get_book or search_books — this tool does not accept a name.

ParametersJSON Schema
NameRequiredDescriptionDefault
series_idYesSeries UUID, found in a book's `series` metadata from get_book/search_books.

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, so the bar is lower. The description adds useful behavioral context: it returns a nested object '{ series }' with a volume list and positions, and specifies a 404 error for unknown series. This goes beyond what annotations provide, though it does not detail side effects or rate limits, which are unnecessary for a read-only tool.

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 three sentences, each serving a distinct purpose: first states the core function and output structure, second mentions error behavior, third gives usage context and a constraint. It is front-loaded with the most critical information and contains no superfluous words.

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 the tool's simplicity (1 required parameter, no output schema, no nested objects), the description is nearly complete. It covers purpose, input source, output structure, and error handling. The only minor gap is that it doesn't explicitly state the output format when successful, but the 'Returns { series }' phrasing is sufficient.

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?

The input schema has 100% description coverage, meaning the schema already fully documents the parameter series_id with a description. The description adds value by clarifying that the series_id is a UUID from a book's `series` metadata, and confirms it does not accept names. With full schema coverage, baseline is 3, and this extra context raises it to 4.

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 clearly states the tool retrieves a book series and its ordered volumes by series UUID, with a specific verb ('Get'), resource ('series'), and unique identifier type ('series UUID'). It distinguishes itself from siblings by specifying that it returns the volume list with positions, which is a distinct function from other tools like get_book or search_books.

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?

The description provides explicit guidance on when to use this tool ('to enumerate every volume in a series and their reading order') and how to obtain the required identifier ('series_id from a book's `series` metadata via get_book or search_books'). It also states what the tool does not accept ('a name'), preventing misuse.

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

list_my_booksA
Read-only

List books on the authenticated user's shelves, most-recently-updated first. Returns { count, books[] } where each entry has status, current_page, percent, rating, and book metadata. When to use: browse or enumerate the user's library, optionally filtered by shelf. To find a specific title within the library use search_my_library; for the public catalog use search_books. Requires SANSFICTION_TOKEN (a bearer token from https://sansfiction.com/docs/agents).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum books to return. Default 20.
statusNoShelf filter: 'reading' = in progress, 'want' = to-read, 'read' = finished, 'dnf' = did not finish, 'all' = every shelf. Default 'all'.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, so the bar for transparency is lower. The description adds value by specifying the ordering (most-recently-updated first) and the exact return format ({ count, books[] } with fields). It also discloses a required authentication token and its source. The only gap is no mention of pagination behavior beyond the limit parameter, but given the richness otherwise, 4 is warranted.

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 concise at roughly 3 sentences (slightly more with the auth note). It front-loads the purpose and ordering, then return format, then usage guidelines, then auth notes. Every sentence earns its place. There is no redundancy or 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 the low complexity (2 optional params, no output schema), good annotations, and rich description, the tool is well-covered. The description explains the return format, usage context, auth requirements, and ordering. A minor gap is the lack of mention of pagination continuation (e.g., how to get next page beyond limit). But overall it is very complete for this tool's simplicity.

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 is 3. The description does not add additional parameter details beyond what the schema provides (the schema already documents limit and status including enumerated values and defaults). The description mentions optional filtering by shelf in passing, but that maps to the already-documented status parameter. The description adds no new semantic value for the parameters.

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 the tool lists books on the authenticated user's shelves with a clear ordering (most-recently-updated first). The title annotation 'List my library' reinforces the purpose. The verb 'list' combined with the resource 'books on the authenticated user's shelves' is specific and distinguishes it from siblings like search_books which targets the public catalog.

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?

The description provides an explicit 'When to use' section that indicates when to use this tool (browse or enumerate the user's library, optionally filtered by shelf). It also names two clear alternatives: search_my_library for finding a specific title within the library, and search_books for the public catalog. This directly addresses usage context and sibling differentiation.

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

list_my_collectionsA
Read-only

List the user's own collections. Returns { count, collections[] } (id, name, description, visibility). When to use: the signed-in user's OWN collections. For editorially curated public collections available to everyone, use list_public_collections instead. Requires SANSFICTION_TOKEN (a bearer token from https://sansfiction.com/docs/agents).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum collections to return. Default 20.
queryNoOptional case-insensitive filter on collection name.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, so the agent knows this is a safe, read-only operation returning a dynamic set. The description adds value by explicitly stating the return shape ({ count, collections[] } with fields id, name, description, visibility) and the authentication requirement (SANSFICTION_TOKEN). There is no contradiction with annotations.

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 three sentences, zero waste. It front-loads the core purpose, then immediately gives return shape and usage guidance, and ends with authentication context. Every sentence earns its place.

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?

Given the low complexity (2 optional params, no nested objects, no output schema, no enums), the description completely covers purpose, return format, usage context, alternatives, and authentication. There are no missing pieces for an agent to use this tool effectively.

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 with baseline 3, the description does not need to add parameter details. It adds no extra meaning beyond the schema for either parameter, which is appropriate given the schema already documents them with clear descriptions.

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 clearly states the verb 'List' and the resource 'the user's own collections', with an explicit distinction from a sibling tool 'list_public_collections'. This leaves no doubt about what the tool does and how it differs from an alternative tool.

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?

The description provides explicit guidance on when to use ('signed-in user's OWN collections') and when not to use ('For editorially curated public collections available to everyone, use list_public_collections instead'), naming the exact alternative tool. It also includes authentication requirements, giving a complete usage context.

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

list_public_collectionsA
Read-only

List public, curated collections (no auth). Returns { count, collections[] } with id, name, and description. Page through results with limit + offset. When to use: browse editorially curated public collections available to everyone. For the signed-in user's OWN collections, use list_my_collections instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum collections to return. Default 20.
offsetNoNumber of collections to skip, for pagination. Default 0.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint (safe read) and openWorldHint (results may vary). The description adds value by stating no authentication is required, describing the return object structure ({ count, collections[] }), and confirming pagination behavior. No contradictions or hidden side effects.

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 extremely concise: two sentences for core purpose and behavior, plus a targeted usage guideline. Every sentence adds value with no redundancy or fluff.

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?

Given the tool's simplicity (two optional pagination parameters), the description covers the purpose, return shape, auth requirements, pagination, and distinguishes from the only close sibling. No output schema exists, but the return format is described plainly.

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 both limit and offset fully described. The description only adds 'Page through results with limit + offset,' which reiterates the schema rather than providing new meaning. Baseline score of 3 is appropriate.

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 clearly states the tool lists public, curated collections, specifies no auth required, and distinguishes from sibling tool list_my_collections. It provides the return shape and pagination detail, making the purpose unmistakable.

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?

The description explicitly says 'When to use: browse editorially curated public collections available to everyone' and directs users to list_my_collections for own collections, giving clear when-to-use and when-not-to-use guidance with a named alternative.

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

remove_book_from_libraryA
DestructiveIdempotent

Remove a book from the user's library entirely (all shelves). Idempotent — removing a book that is not present is a no-op. When to use: permanently take a book out of the library. If you only want to change its shelf (e.g. mark 'dnf' or 'read'), use update_library_book instead — do not remove and re-add. Requires SANSFICTION_TOKEN (a bearer token from https://sansfiction.com/docs/agents).

ParametersJSON Schema
NameRequiredDescriptionDefault
book_idYesCatalog book UUID to remove from your library.

TDQS

A4.7/5.0
Behavior5/5

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

Despite annotations already declaring destructive and idempotent hints, the description adds critical context: 'all shelves', no-op behavior, permanent removal, and required SANSFICTION_TOKEN. This exceeds annotation coverage.

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?

Three focused sentences: action, idempotency, when-to-use, alternative, and auth. No fluff or repetition of schema details.

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 single-parameter destructive tool with no output schema, the description provides complete context: effect, idempotency, usage boundary, and authentication requirement. Nothing critical 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 coverage is 100% and the single parameter book_id is fully described in the schema. The description adds no additional parameter-level meaning beyond the schema, which is the baseline for full 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?

Description uses specific verb 'Remove' with resource 'book from the user's library' and clarifies scope 'entirely (all shelves)'. It clearly distinguishes from sibling update_library_book by contrasting removal vs. shelf change.

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?

Explicit 'When to use' clause and direct alternative guidance: 'If you only want to change its shelf... use update_library_book instead'. Also warns against remove-and-re-add anti-pattern.

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

search_booksA
Read-only

Search the public SansFiction catalog (no auth). Returns JSON { query, searchType, count, books[] }; each book includes id (the catalog UUID used as book_id by every other tool), slug, title, and authors. When to use: your entry point for discovery — resolve a title/author/ISBN into a book_id. Use search_my_library instead to search only the signed-in user's own shelves; use get_book once you already have an id/slug and want full details.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of books to return. Range 1–50. Default 20.
queryYesSearch text. With searchType 'isbn' (or an 'isbn:' prefix) pass a 10- or 13-digit ISBN.
searchTypeNoWhat `query` matches against. 'all' (default) = title/general full-text; 'author' = contributor name; 'series' = series name; 'mood' = a mood term such as cozy or dark; 'isbn' = exact ISBN-10/13 lookup.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint. The description adds valuable behavioral context: 'no auth', the exact return JSON structure (query, searchType, count, books[]), and crucially explains that the returned 'id' is the catalog UUID used as 'book_id' by every other tool. This connects the tool's output to the broader API. No contradictions with annotations.

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?

Three sentences accomplish everything: (1) purpose + return shape, (2) primary use case, (3) sibling differentiation. Every sentence delivers unique, actionable information. No 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 the tool's complexity (3 params, rich schema, no output schema), the description covers the key gaps: return format, the critical linking of 'id' to other tools, and sibling distinction. It does not mention pagination beyond the limit parameter, but the schema already covers that. The 'openWorldHint' annotation handles result variability. Overall, very complete for a search tool.

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% – all three parameters have clear descriptions including constraints and defaults. The description does not repeat param details, which is appropriate. It adds mild value by noting the relationship between searchType and query (e.g., ISBN prefix), but this is already implied by the schema. Baseline 3 is correct.

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 'Search the public SansFiction catalog (no auth)', clearly stating the verb (search), resource (catalog), and scope (public). It uniquely identifies the tool's purpose and distinguishes it from siblings by referencing 'search_my_library' and 'get_book'.

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?

Explicitly states the primary use case: 'your entry point for discovery — resolve a title/author/ISBN into a book_id'. It then provides clear when-not-to-use guidance by naming 'search_my_library' for signed-in user shelves and 'get_book' for full details after having an id/slug.

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

search_my_libraryA
Read-only

Full-text search restricted to the user's own library (matches book title and subtitle). Returns { count, books[] } with status and rating. When to use: find a specific book the user already owns. For catalog-wide discovery use search_books; to list everything on the shelves (optionally by status) use list_my_books. Requires SANSFICTION_TOKEN (a bearer token from https://sansfiction.com/docs/agents).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum results to return. Default 10.
queryYesText matched (case-insensitive) against titles/subtitles of books you own.
statusNoRestrict to one shelf. Default 'all'.

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=true, which lower the bar. The description adds useful behavioral context: return format as '{ count, books[] } with status and rating', and the authentication requirement (SANSFICTION_TOKEN and documentation link). While it does not describe edge cases like empty results or rate limits, it adequately supplements the annotations for a read-only search tool.

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 four sentences, each adding distinct value: action/scope, return format, usage guidance, and authentication. It is front-loaded with the core purpose. While efficient, it could be compressed slightly (e.g., merging the usage sentence with the alternative tools). Still, it avoids redundancy and earns a 4.

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 the tool has 3 parameters, no output schema, and low complexity, the description covers the essential aspects: scope, return shape, usage guidelines, and auth. It does not mention pagination or sorting, but those are documented in the schema (limit parameter). Overall, it is complete for a focused search tool.

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 is 3. The description does not add any parameter-specific meaning beyond what the schema already provides (e.g., query matches titles/subtitles is already in schema). The schema's descriptions for 'limit', 'query', and 'status' are sufficient, and the tool description offers no extra semantics for individual parameters.

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 description clearly states it is a 'full-text search restricted to the user's own library' targeting book titles and subtitles, which distinguishes it from sibling tools like 'search_books' (catalog-wide) and 'list_my_books' (listing all). However, the phrase 'full-text search' is slightly misleading because it only matches title and subtitle, not the full content. This minor imprecision prevents a perfect score.

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?

The description explicitly states 'When to use: find a specific book the user already owns' and contrasts with 'search_books' for catalog-wide discovery and 'list_my_books' for listing all shelves. It also mentions the required authentication token, providing clear when-to-use, when-not-to-use, and alternative tools. Excellent guidance.

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

update_library_bookA

Update one or more fields of a book already in the library. Supply any subset — only the fields you pass change. Special behavior: current_page records a reading-progress log entry (this is what feeds get_reading_stats), and setting rating or review publishes that entry publicly. Returns the updated row; errors with 404 if the book is not in the library (add it first). When to use: change fields or log progress for a book ALREADY on a shelf. Add it first with add_book_to_library; remove it with remove_book_from_library. Requires SANSFICTION_TOKEN (a bearer token from https://sansfiction.com/docs/agents).

ParametersJSON Schema
NameRequiredDescriptionDefault
ratingNoYour rating on a 0–5 scale. Setting it publishes the entry.
reviewNoFree-text review. Setting it publishes the entry.
statusNoMove the book to this shelf.
book_idYesCatalog book UUID of a book already on one of your shelves.
started_atNoDate you started reading, ISO 8601 date (YYYY-MM-DD).
finished_atNoDate you finished reading, ISO 8601 date (YYYY-MM-DD).
current_pageNoCurrent page number. Passing this appends a reading-progress log entry used by get_reading_stats; it does not merely overwrite a field.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations declare readOnlyHint=false and destructiveHint=false, but the description adds critical behavioral context: partial update semantics ('only the fields you pass change'), special side effects (current_page creates a log entry for get_reading_stats, rating/review publish publicly), error behavior (404 if not found), and return value (updated row). This far exceeds annotation coverage.

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 a single, well-structured paragraph of 4-5 sentences. It front-loads the core purpose, then layers special behavior, return value, error condition, usage guidance, and auth requirement. Every sentence adds distinct value with no redundancy.

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?

Despite no output schema, the description covers: partial update semantics, special behaviors for specific fields, return value ('Returns the updated row'), error condition (404), prerequisites (book must exist), usage guidance with sibling references, and authentication requirement (SANSFICTION_TOKEN). For a tool with 7 parameters and complex side effects, this is complete.

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 description coverage is 100% so baseline is 3. The description adds value by stating 'Supply any subset — only the fields you pass change,' which clarifies the partial update model. It also explains the special semantics of current_page, rating, and review beyond their schema descriptions. One point above baseline for this added clarity.

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: 'Update one or more fields of a book already in the library.' It distinguishes from sibling tools by naming add_book_to_library and remove_book_from_library, and mentions that current_page feeds get_reading_stats, making its role clear against other library tools.

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?

Explicit guidance: 'When to use: change fields or log progress for a book ALREADY on a shelf. Add it first with add_book_to_library; remove it with remove_book_from_library.' Also notes error 404 if book not in library, reinforcing prerequisite. No ambiguity.

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. 11 tool updatesv1.0.2
    • Changedadd_book_to_library4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / book_id / description
        Added value: +"Catalog book UUID (the `id` from search_books)."
      • addedInput schema / properties / edition_id / description
        Added value: +"Optional specific edition UUID to associate with this library entry."
      • addedInput schema / properties / status / description
        Added value: +"Shelf to place the book on. Default 'want' (to-read)."
    • Changedget_book3 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / book_id / description
        Added value: +"Catalog book UUID or slug, as returned in `id`/`slug` by search_books."
      • addedInput schema / properties / edition_id / description
        Added value: +"Optional edition UUID to resolve a specific edition (language, cover, ISBN) instead of the default/primary edition."
    • Changedget_reading_stats6 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / date / description
        Added value: +"Anchor date (ISO 8601 YYYY-MM-DD) selecting which week/month/year `scope` refers to. Default: today. Ignored when both `from` and `to` are supplied."
      • addedInput schema / properties / from / description
        Added value: +"Explicit range start (ISO 8601 date). Must be paired with `to`; together they override `scope`/`date`."
      • addedInput schema / properties / include_logs / description
        Added value: +"When true, include the raw reading-log entries (`logs[]`) in the response. Default false."
      • addedInput schema / properties / scope / description
        Added value: +"Granularity of the range relative to `date`. Default 'monthly'. Ignored when both `from` and `to` are supplied."
      • addedInput schema / properties / to / description
        Added value: +"Explicit range end (ISO 8601 date). Must be paired with `from`."
    • Changedget_series2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / series_id / description
        Added value: +"Series UUID, found in a book's `series` metadata from get_book/search_books."
    • Changedlist_my_books5 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / description
        Added value: +"Maximum books to return. Default 20."
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • changedInput schema / properties / limit / type
        Previous value: -"number"New value: +"integer"
      • addedInput schema / properties / status / description
        Added value: +"Shelf filter: 'reading' = in progress, 'want' = to-read, 'read' = finished, 'dnf' = did not finish, 'all' = every shelf. Default 'all'."
    • Changedlist_my_collections5 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / description
        Added value: +"Maximum collections to return. Default 20."
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • changedInput schema / properties / limit / type
        Previous value: -"number"New value: +"integer"
      • addedInput schema / properties / query / description
        Added value: +"Optional case-insensitive filter on collection name."
    • Changedlist_public_collections7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / description
        Added value: +"Maximum collections to return. Default 20."
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • changedInput schema / properties / limit / type
        Previous value: -"number"New value: +"integer"
      • addedInput schema / properties / offset / description
        Added value: +"Number of collections to skip, for pagination. Default 0."
      • addedInput schema / properties / offset / minimum
        Added value: +0
      • changedInput schema / properties / offset / type
        Previous value: -"number"New value: +"integer"
    • Changedremove_book_from_library2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / book_id / description
        Added value: +"Catalog book UUID to remove from your library."
    • Changedsearch_books7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / description
        Added value: +"Maximum number of books to return. Range 1–50. Default 20."
      • addedInput schema / properties / limit / maximum
        Added value: +50
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • changedInput schema / properties / limit / type
        Previous value: -"number"New value: +"integer"
      • addedInput schema / properties / query / description
        Added value: +"Search text. With searchType 'isbn' (or an 'isbn:' prefix) pass a 10- or 13-digit ISBN."
      • addedInput schema / properties / searchType / description
        Added value: +"What `query` matches against. 'all' (default) = title/general full-text; 'author' = contributor name; 'series' = series name; 'mood' = a mood term such as cozy or dark; 'isbn' = exact ISBN-10/13 lookup."
    • Changedsearch_my_library6 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / description
        Added value: +"Maximum results to return. Default 10."
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • changedInput schema / properties / limit / type
        Previous value: -"number"New value: +"integer"
      • addedInput schema / properties / query / description
        Added value: +"Text matched (case-insensitive) against titles/subtitles of books you own."
      • addedInput schema / properties / status / description
        Added value: +"Restrict to one shelf. Default 'all'."
    • Changedupdate_library_book12 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / book_id / description
        Added value: +"Catalog book UUID of a book already on one of your shelves."
      • addedInput schema / properties / current_page / description
        Added value: +"Current page number. Passing this appends a reading-progress log entry used by get_reading_stats; it does not merely overwrite a field."
      • addedInput schema / properties / current_page / minimum
        Added value: +0
      • changedInput schema / properties / current_page / type
        Previous value: -"number"New value: +"integer"
      • addedInput schema / properties / finished_at / description
        Added value: +"Date you finished reading, ISO 8601 date (YYYY-MM-DD)."
      • addedInput schema / properties / rating / description
        Added value: +"Your rating on a 0–5 scale. Setting it publishes the entry."
      • addedInput schema / properties / rating / maximum
        Added value: +5
      • addedInput schema / properties / rating / minimum
        Added value: +0
      • addedInput schema / properties / review / description
        Added value: +"Free-text review. Setting it publishes the entry."
      • addedInput schema / properties / started_at / description
        Added value: +"Date you started reading, ISO 8601 date (YYYY-MM-DD)."
      • addedInput schema / properties / status / description
        Added value: +"Move the book to this shelf."
  2. 11 tool updatesv1.0.0
    • First observedadd_book_to_library
    • First observedget_book
    • First observedget_reading_stats
    • First observedget_series
    • First observedlist_my_books
    • First observedlist_my_collections
    • First observedlist_public_collections
    • First observedremove_book_from_library
    • First observedsearch_books
    • First observedsearch_my_library
    • First observedupdate_library_book

TDQS

A4.4/5.0
Disambiguation5/5

Every tool has a clear, distinct purpose. Public vs. user-specific tools are explicitly differentiated (e.g., search_books vs. search_my_library, list_public_collections vs. list_my_collections). Tool descriptions include 'When to use' guidance that clarifies boundaries, leaving no ambiguity.

Naming Consistency4/5

All tool names follow a consistent verb_noun pattern (e.g., search_books, get_book, add_book_to_library, update_library_book). Minor inconsistency: list_public_collections vs. list_my_collections use 'public' and 'my' as differentiators, while other 'my' tools don't prefix with 'list' (e.g., search_my_library uses 'search'). Overall, the pattern is predictable and readable.

Tool Count5/5

With 11 tools, the set is well-scoped for a book/library management MCP server. It covers discovery (search_books, get_book, get_series, list_public_collections) and user library management (list_my_books, search_my_library, add/update/remove book, list_my_collections, get_reading_stats). Each tool serves a necessary function without redundancy.

Completeness4/5

The tool set covers the full lifecycle: discover books, get details, add to library, update status/progress, remove, and view stats. Minor gaps exist: there is no tool to create or manage collections beyond listing (e.g., add_book_to_collection or create_collection), and no user authentication or token management tool. However, core reading workflows are well-supported.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    Enables semantic search and contextual conversations with your Calibre ebook library using vector-based RAG technology. Supports project-based organization, multi-format book processing, and OCR capabilities for enhanced content extraction and retrieval.
    7
    2
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables semantic search and conversational querying across a personal research library of PDFs, DOCX, and other documents using a vector database. It provides tools for document summarization, finding related papers, and high-accuracy retrieval for AI clients like Claude Desktop.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables searching, reading, and managing a Calibre ebook library through natural language, with features like metadata search, full-text search, content extraction, and library management.
    221
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables read-only search, browsing, and metadata retrieval from a local Calibre e-book library using natural language queries.
    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/fgbytes/sansfiction-mcp'

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