sansfiction-mcp
SansFiction MCP & Agent Skill
Подключайте AI-агентов к SansFiction — цифровой библиотеке для книг, подборок, читательских дневников и открытий.
Одни и те же возможности представлены двумя способами, оба аутентифицируются одним и тем же токеном-носителем:
MCP-сервер (Streamable HTTP):
https://sansfiction.com/api/mcpREST API (v1):
https://sansfiction.com/api/v1
Быстрый старт (MCP)
claude mcp add --transport http sansfiction https://sansfiction.com/api/mcpИли укажите любой MCP-клиент на конечную точку streamable-HTTP выше. Инструменты публичного каталога не требуют аутентификации; инструменты личной библиотеки требуют токен-носитель (создайте его на sansfiction.com/docs/agents).
Related MCP server: Personal Research Assistant MCP
Быстрый старт (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"Возможности
Публичный каталог (без аутентификации)
GET /api/v1/catalog/search?q=…&searchType=all|author|series|mood|isbnGET /api/v1/catalog/books/{bookId}GET /api/v1/catalog/series/{seriesId}GET /api/v1/catalog/collections
Личная библиотека (токен-носитель)
GET/POST /api/v1/library/books·PATCH/DELETE /api/v1/library/books/{bookId}GET /api/v1/library/searchGET /api/v1/library/collections·GET /api/v1/library/collections/{id}·POST …/itemsGET /api/v1/library/stats
Обнаружение
Agent Skill:
SKILL.md— также доступен по адресуhttps://sansfiction.com/.well-known/agent-skills/sansfiction-catalog/SKILL.mdМанифест MCP Registry:
server.jsonOpenAPI:
https://sansfiction.com/openapi.jsonКарточка MCP-сервера:
https://sansfiction.com/.well-known/mcp/server-card.json
Аутентификация
Создайте персональный токен доступа (sf_mcp_…) в процессе входа на
sansfiction.com/docs/agents. Один и тот же токен
аутентифицирует и MCP-сервер, и REST API. Ограничения скорости: 60 запросов/мин
анонимно, 180 запросов/мин для аутентифицированных.
Лицензия
Сервис SansFiction является проприетарным. Этот репозиторий документирует его публичный интерфейс агента для обнаружения и интеграции.
Локальный запуск в качестве MCP-сервера (stdio)
Этот репозиторий также включает небольшой stdio MCP-сервер, который проксирует запросы к размещенному REST API, что позволяет запускать его везде, где MCP-клиент ожидает локальную команду:
npx sansfiction-mcp
# or
npm install && node index.jsПеременные окружения:
SANSFICTION_TOKEN— токен-носитель (sf_mcp_…) для инструментов личной библиотеки (создаётся на https://sansfiction.com/docs/agents). Инструменты публичного каталога не требуют токена.SANSFICTION_BASE_URL— переопределить базовый URL API (по умолчаниюhttps://sansfiction.com).
Инструменты: 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
Шаги сборки:
["npm install"]Аргументы CMD:
["mcp-proxy","--","node","index.js"]
tools/list не требует сети или учетных данных, поэтому проверка интроспекции проходит
без токена.
Available Tools
11 toolsadd_book_to_libraryAIdempotent
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).
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | Shelf to place the book on. Default 'want' (to-read). | |
| book_id | Yes | Catalog book UUID (the `id` from search_books). | |
| edition_id | No | Optional specific edition UUID to associate with this library entry. |
TDQS
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.
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.
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.
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.
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.
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_bookARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| book_id | Yes | Catalog book UUID or slug, as returned in `id`/`slug` by search_books. | |
| edition_id | No | Optional edition UUID to resolve a specific edition (language, cover, ISBN) instead of the default/primary edition. |
TDQS
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.
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.
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.
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.
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.
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_statsARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Explicit range end (ISO 8601 date). Must be paired with `from`. | |
| date | No | 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. | |
| from | No | Explicit range start (ISO 8601 date). Must be paired with `to`; together they override `scope`/`date`. | |
| scope | No | Granularity of the range relative to `date`. Default 'monthly'. Ignored when both `from` and `to` are supplied. | |
| include_logs | No | When true, include the raw reading-log entries (`logs[]`) in the response. Default false. |
TDQS
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.
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.
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.
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.
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.
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_seriesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| series_id | Yes | Series UUID, found in a book's `series` metadata from get_book/search_books. |
TDQS
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.
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.
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.
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.
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.
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_booksARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum books to return. Default 20. | |
| status | No | Shelf filter: 'reading' = in progress, 'want' = to-read, 'read' = finished, 'dnf' = did not finish, 'all' = every shelf. Default 'all'. |
TDQS
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.
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.
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.
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.
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.
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_collectionsARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum collections to return. Default 20. | |
| query | No | Optional case-insensitive filter on collection name. |
TDQS
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.
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.
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.
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.
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.
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_collectionsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum collections to return. Default 20. | |
| offset | No | Number of collections to skip, for pagination. Default 0. |
TDQS
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.
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.
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.
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.
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.
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_libraryADestructiveIdempotent
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).
| Name | Required | Description | Default |
|---|---|---|---|
| book_id | Yes | Catalog book UUID to remove from your library. |
TDQS
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.
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.
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.
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.
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.
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_booksARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of books to return. Range 1–50. Default 20. | |
| query | Yes | Search text. With searchType 'isbn' (or an 'isbn:' prefix) pass a 10- or 13-digit ISBN. | |
| searchType | No | 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. |
TDQS
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.
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.
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.
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.
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.
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_libraryARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum results to return. Default 10. | |
| query | Yes | Text matched (case-insensitive) against titles/subtitles of books you own. | |
| status | No | Restrict to one shelf. Default 'all'. |
TDQS
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.
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.
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.
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.
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.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| rating | No | Your rating on a 0–5 scale. Setting it publishes the entry. | |
| review | No | Free-text review. Setting it publishes the entry. | |
| status | No | Move the book to this shelf. | |
| book_id | Yes | Catalog book UUID of a book already on one of your shelves. | |
| started_at | No | Date you started reading, ISO 8601 date (YYYY-MM-DD). | |
| finished_at | No | Date you finished reading, ISO 8601 date (YYYY-MM-DD). | |
| current_page | No | Current page number. Passing this appends a reading-progress log entry used by get_reading_stats; it does not merely overwrite a field. |
TDQS
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.
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.
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.
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.
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.
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.
11 tool updates
v1.0.2- Changed
add_book_to_library4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / book_id / descriptionAdded value: +"Catalog book UUID (the `id` from search_books)." - added
Input schema / properties / edition_id / descriptionAdded value: +"Optional specific edition UUID to associate with this library entry." - added
Input schema / properties / status / descriptionAdded value: +"Shelf to place the book on. Default 'want' (to-read)."
- Changed
get_book3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / book_id / descriptionAdded value: +"Catalog book UUID or slug, as returned in `id`/`slug` by search_books." - added
Input schema / properties / edition_id / descriptionAdded value: +"Optional edition UUID to resolve a specific edition (language, cover, ISBN) instead of the default/primary edition."
- Changed
get_reading_stats6 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / date / descriptionAdded 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." - added
Input schema / properties / from / descriptionAdded value: +"Explicit range start (ISO 8601 date). Must be paired with `to`; together they override `scope`/`date`." - added
Input schema / properties / include_logs / descriptionAdded value: +"When true, include the raw reading-log entries (`logs[]`) in the response. Default false." - added
Input schema / properties / scope / descriptionAdded value: +"Granularity of the range relative to `date`. Default 'monthly'. Ignored when both `from` and `to` are supplied." - added
Input schema / properties / to / descriptionAdded value: +"Explicit range end (ISO 8601 date). Must be paired with `from`."
- Changed
get_series2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / series_id / descriptionAdded value: +"Series UUID, found in a book's `series` metadata from get_book/search_books."
- Changed
list_my_books5 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limit / descriptionAdded value: +"Maximum books to return. Default 20." - added
Input schema / properties / limit / minimumAdded value: +1 - changed
Input schema / properties / limit / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / status / descriptionAdded value: +"Shelf filter: 'reading' = in progress, 'want' = to-read, 'read' = finished, 'dnf' = did not finish, 'all' = every shelf. Default 'all'."
- Changed
list_my_collections5 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limit / descriptionAdded value: +"Maximum collections to return. Default 20." - added
Input schema / properties / limit / minimumAdded value: +1 - changed
Input schema / properties / limit / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / query / descriptionAdded value: +"Optional case-insensitive filter on collection name."
- Changed
list_public_collections7 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limit / descriptionAdded value: +"Maximum collections to return. Default 20." - added
Input schema / properties / limit / minimumAdded value: +1 - changed
Input schema / properties / limit / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / offset / descriptionAdded value: +"Number of collections to skip, for pagination. Default 0." - added
Input schema / properties / offset / minimumAdded value: +0 - changed
Input schema / properties / offset / typePrevious value: -"number"New value: +"integer"
- Changed
remove_book_from_library2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / book_id / descriptionAdded value: +"Catalog book UUID to remove from your library."
- Changed
search_books7 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limit / descriptionAdded value: +"Maximum number of books to return. Range 1–50. Default 20." - added
Input schema / properties / limit / maximumAdded value: +50 - added
Input schema / properties / limit / minimumAdded value: +1 - changed
Input schema / properties / limit / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / query / descriptionAdded value: +"Search text. With searchType 'isbn' (or an 'isbn:' prefix) pass a 10- or 13-digit ISBN." - added
Input schema / properties / searchType / descriptionAdded 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."
- Changed
search_my_library6 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limit / descriptionAdded value: +"Maximum results to return. Default 10." - added
Input schema / properties / limit / minimumAdded value: +1 - changed
Input schema / properties / limit / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / query / descriptionAdded value: +"Text matched (case-insensitive) against titles/subtitles of books you own." - added
Input schema / properties / status / descriptionAdded value: +"Restrict to one shelf. Default 'all'."
- Changed
update_library_book12 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / book_id / descriptionAdded value: +"Catalog book UUID of a book already on one of your shelves." - added
Input schema / properties / current_page / descriptionAdded value: +"Current page number. Passing this appends a reading-progress log entry used by get_reading_stats; it does not merely overwrite a field." - added
Input schema / properties / current_page / minimumAdded value: +0 - changed
Input schema / properties / current_page / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / finished_at / descriptionAdded value: +"Date you finished reading, ISO 8601 date (YYYY-MM-DD)." - added
Input schema / properties / rating / descriptionAdded value: +"Your rating on a 0–5 scale. Setting it publishes the entry." - added
Input schema / properties / rating / maximumAdded value: +5 - added
Input schema / properties / rating / minimumAdded value: +0 - added
Input schema / properties / review / descriptionAdded value: +"Free-text review. Setting it publishes the entry." - added
Input schema / properties / started_at / descriptionAdded value: +"Date you started reading, ISO 8601 date (YYYY-MM-DD)." - added
Input schema / properties / status / descriptionAdded value: +"Move the book to this shelf."
11 tool updates
v1.0.0- First observed
add_book_to_library - First observed
get_book - First observed
get_reading_stats - First observed
get_series - First observed
list_my_books - First observed
list_my_collections - First observed
list_public_collections - First observed
remove_book_from_library - First observed
search_books - First observed
search_my_library - First observed
update_library_book
TDQS
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.
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.
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.
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
Related MCP Connectors
Federated search of books and papers, BibTeX/RIS citations, open-access retrieval and reading.
Academic literature search, retrieval, and private library management on top of OpenAlex.
- LeafleOAuthnet.nanosheep
Personalised book recommendations, filtered to what's on your public library's shelf right now.
Search arXiv/Semantic Scholar/OpenAlex + medical evidence (PubMed/Europe PMC) + LaTeX/PDF tools.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables 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.72-
- FlicenseNot gradedqualityDmaintenanceEnables 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.-
- AlicenseNot gradedqualityDmaintenanceEnables searching, reading, and managing a Calibre ebook library through natural language, with features like metadata search, full-text search, content extraction, and library management.221Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables read-only search, browsing, and metadata retrieval from a local Calibre e-book library using natural language queries.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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