Skip to main content
Glama
felixyoma4u

LibraryMCP

by felixyoma4u

Library Server

A small MCP server modeling a library, plus a client that drives it with the OpenAI Agents SDK. Uses uv for environment and dependency management.

Files

  • app.py — the MCP server (4 tools, 2 resources, 1 prompt)

  • client.py — connects to app.py over stdio using an Agents SDK agent

  • pyproject.toml — project + dependency definition (uv reads this)

  • uv.lock — locked dependency versions (commit this alongside pyproject.toml)

Related MCP server: book-recommender

1. Install uv (if you don't have it yet)

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Restart your terminal, then confirm it's on PATH:

uv --version

2. Set up the project in VS Code

Open this folder in VS Code, open a terminal (Ctrl+` / Cmd+`), and sync dependencies from the lockfile:

uv sync

This creates a .venv in the project folder and installs exactly what's pinned in uv.lock. Point VS Code at it: Command Palette (Ctrl+Shift+P) → Python: Select Interpreter → pick the one at .venv/bin/python (or .venv\Scripts\python.exe on Windows).

You don't need to manually activate the venv for the commands below — uv run does that for you automatically.

3. Verify the server structure

This is the check the assignment asks for — it should report 4 tools, 1 prompt, 1 resource, 1 template:

uv run fastmcp inspect app.py

Expected output:

Components
  Tools:        4
  Prompts:      1
  Resources:    1
  Templates:    1

You can also run the server directly to confirm it starts cleanly (it just sits there listening on stdio — Ctrl+C to stop):

uv run python app.py

4. Run the client

The client normally needs an LLM provider to decide which tools to invoke. This project defaults to using a local LLM (via Ollama) instead of the remote OpenAI API.

Option A — Use the local LLM (default)

  • Ensure an Ollama daemon is running and the model referenced in client.py is available (the client expects http://localhost:11434/v1 and model="gemma4:e4b" by default).

  • Then run:

uv run python client.py

Option B — Use OpenAI instead

  • Set your OpenAI API key in the environment:

# macOS / Linux
export OPENAI_API_KEY="sk-..."
  • Edit client.py to construct an OpenAI-backed model (or replace the local model block) so the client uses your OpenAI credentials, then run:

uv run python client.py

client.py spawns app.py as a subprocess automatically via MCPServerStdio, using uv run python app.py as the launch command — so it always runs inside this project's own uv-managed environment.

What should happen

The agent receives: "Find me books about space, then borrow one for member M001." It should:

  1. Call search_books("space") → finds 2001: A Space Odyssey (the only catalog entry with "space" in the title — matches per the assignment's title/author search spec).

  2. Call borrow_book("9780451457998", "M001") → decrements its stock and records the borrow in M001's history.

  3. Print a final natural-language summary confirming both steps.

If you want to see the raw tool-call trace (not just the final answer), add print(result.new_items) after result = await Runner.run(...) in client.py, or inspect result.raw_responses.

Adding more dependencies later

Don't pip install directly into the venv — use uv so pyproject.toml and uv.lock stay in sync:

uv add some-package

Notes on design choices

  • All four tools return plain strings for both success and error cases (e.g. no copies left, unknown ISBN) — never exceptions — so a calling LLM always gets something it can read and relay to the user.

  • search_books matches only title/author (per the assignment spec), case-insensitively, substring match.

  • The dynamic resource (member://{member_id}/history) returns JSON as a string; FastMCP resource functions need to return str/bytes/specific content types, not raw Python lists of dicts.

  • The mock catalog is 8 well-known sci-fi/fantasy titles; stock levels are deliberately mixed (some at 0) so you can test both the success and no-copies-left paths in borrow_book.

Available Tools

4 tools
borrow_bookA

Borrow a copy of a book on behalf on a library member.

Use this tool when the user wants to check out / borrow a specific book and you already know the ISBN and the member's ID. This reduces the book's availability count by one and records the borrow in the member's history. If there are no copies left or the ISBN/member_id is invalid, and error is returned as a string rather than raised an exception - check the return value before telling the user the borrow succeeded.

ParametersJSON Schema
NameRequiredDescriptionDefault
isbnYesThe ISBN of the book to borrow.
member_idYesThe library member's ID (e.g. "M001")

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

No annotations are provided, so the description carries full behavioral disclosure burden. It explicitly discloses the mutation (reduces availability count), the recording of history, and the error-handling behavior (returns string error rather than throwing exception, and instructs to check return value). This is strong disclosure given zero annotations.

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

Conciseness4/5

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

Description is appropriately sized - two paragraphs that front-load the core purpose, then add behavioral context. It's efficient and every sentence adds information. Slightly verbose with 'on behalf on' typo and could be tighter, but no wasted sentences.

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?

Output schema exists so return format needn't be explained. The description covers purpose, prerequisites, side effects, error handling, and distinguishing context. For a 2-param tool with full schema coverage, this is quite complete. Slightly less than perfect due to lack of alias/other ISBN format details.

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 schema already documents both parameters adequately. The description adds the contextual meaning of ISBN and member_id (that they need to be known beforehand), but the schema descriptions are already clear. Baseline 3 is appropriate when schema fully documents 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?

Description clearly states it borrows a book for a library member, with specific verb+resource+action. It also notes it reduces availability count and records in member history, distinguishing this from siblings like return_book and check_availability.

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?

Description explicitly states when to use this tool (when user wants to check out/borrow and you already know ISBN and member ID). It differentiates from alternatives by noting the prerequisite of knowing the ID/ISBN in advance, which is useful given sibling tools like search_books exist.

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

check_availabilityA

Check how many copies of a specific book are available to borrow.

Use this tool when the user (or another tool call) already has an ISBN and wants to know stock levels before attempting to borrow, or just want a quick status check on a book.

ParametersJSON Schema
NameRequiredDescriptionDefault
isbnYesThe ISBN of the book to check

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

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

No annotations are provided, so the description carries the burden. It clarifies this is a read/status operation and implies it does NOT mutate state, which is helpful given no readOnlyHint annotation exists. However, it doesn't describe the output format or whether the tool errors on unknown ISBNs. For a simple read tool with a clearly implied non-destructive nature, this is acceptable though not rich.

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 compact—two sentences total—with the purpose front-loaded in the first sentence and usage guidance in the second. Every sentence earns its place with zero filler or redundancy.

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?

The description is complete for a simple single-parameter read tool. It provides purpose, usage context, and preconditions. The presence of an output schema (presumably with availability counts) means return value explanation isn't necessary. Sibling context makes the differentiation clear. Only minor optional enrichment (e.g., whether 'available copies' includes held items) would push it higher.

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% for the single 'isbn' parameter, so the schema already documents it fully as 'The ISBN of the book to check.' The description reinforces that ISBN is a prerequisite ('already has an ISBN') but adds little beyond the schema. Baseline 3 is appropriate since the schema does the heavy lifting.

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 uses a specific verb+resource ('Check how many copies... are available to borrow') and clearly identifies the scope (stock availability for a specific book). It distinguishes itself from siblings by focusing on availability checking versus borrowing (borrow_book) or searching (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?

Explicitly states when to use: 'when the user already has an ISBN and wants to know stock levels before attempting to borrow, or just want a quick status check.' This provides clear context and helps the agent distinguish from when to use borrow_book or search_books.

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

return_bookA

Return a previously borrowed book on behalf of a library member.

Use this tool when the user wants to return / check in a book they have borrowed. This increases the book's available copy count by one and records the return in the member's history. Errors (unknown ISBN or empty member_id) are returned as strings, never raised.

ParametersJSON Schema
NameRequiredDescriptionDefault
isbnYesThe ISBN of the book being returned.
member_idYesThe library member's ID (e.g. "M001").

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden and does well: it states the side effect ('increases the book's available copy count by one'), records the return in member history, and discloses the error-handling behavior (errors returned as strings, never raised). This is rich behavioral disclosure for a mutation tool with zero 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.

Conciseness4/5

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

The description is appropriately sized at two sentences, front-loading the core action and then adding behavioral details. Every sentence earns its place. A minor improvement could be trimming, but it's tight and readable.

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?

The description covers side effects, error handling, and usage context. Since an output schema exists, the description needn't explain return values. It's complete for a two-parameter mutation tool given full schema coverage, though it could optionally clarify what happens on successful return (the output schema covers this).

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 both parameters (isbn, member_id) are already well documented in the schema itself. The description adds the error-returns-as-strings nuance and the 'M001' example format, providing marginal value beyond the schema but not requiring more given full schema 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?

The description uses a specific verb+resource ('Return a previously borrowed book') and clearly states the scope ('on behalf of a library member'). It distinguishes itself from siblings by being the check-in counterpart to borrow_book, and the borrowing context is clearly established.

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 the tool ('when the user wants to return / check in a book they have borrowed'), establishes clear context, and the sibling tools (borrow_book, search_books, check_availability) make the differentiation evident. It also clarifies behavior around required inputs.

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

search_booksA

Search the library catalog by title or author (case-insensitive, partial matches allowed).

Use this tool whenever the user wants to find books, browse what's available on a topic, or look up a specific author/title but doesn't already know the ISBN. Return a list of matching book records (title, author, isbn, available_copies), or a plain string message if nothing matches.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesA search string matched against each book's title and author fields.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It discloses the return format (list of matching records with title, author, isbn, available_copies), the empty-result behavior (plain string message), and the match semantics (case-insensitive, partial). This is thorough 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.

Conciseness5/5

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

Three well-organized sentences, zero filler. Opening sentence states the core purpose, second sentence covers usage guidance, third sentence covers return behavior. Each line earns its place and front-loads the most important information.

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

Completeness5/5

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

The tool has a single simple parameter, an output schema that documents the return structure, and the description covers behavioral details like empty results and matching rules. For a search tool of this complexity, the description is complete and there are no gaps.

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

Parameters3/5

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

Schema description coverage is 100%, so the single 'query' parameter is already documented in the schema ('matched against each book's title and author fields'). The description adds marginal behavioral context (case-insensitive, partial) but doesn't add significant new semantic detail beyond what the schema covers.

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?

Clear specific verb+resource: 'Search the library catalog by title or author'. Clearly states case-insensitive and partial-match behavior, and specifically enumerates what fields are searched. Distinguishes itself from siblings (return_book, borrow_book, check_availability) by being the search/discovery 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?

Explicitly states when to use: 'whenever the user wants to find books, browse what's available on a topic, or look up a specific author/title but doesn't already know the ISBN.' The ISBN exclusion phrase clearly draws the boundary against catalog-lookup alternatives, which is helpful guidance.

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. 4 tool updatesv0.1.0
    • First observedborrow_book
    • First observedcheck_availability
    • First observedreturn_book
    • First observedsearch_books

TDQS

A4.1/5.0
Disambiguation5/5

Each tool targets a distinct operation: search, availability check, borrow, and return. The descriptions clearly delineate when each should be used (search when ISBN unknown, check_availability when ISBN known, borrow/return with ISBN + member). No two tools have overlapping purposes.

Naming Consistency4/5

Three tools follow a consistent verb_noun pattern (search_books, check_availability, borrow_book, return_book). The pair borrow_book/return_book is perfectly symmetric. Only check_availability deviates slightly by using a gerund-ish structure instead of an imperative verb, though it remains readable and predictable.

Tool Count3/5

Four tools is within a reasonable range for a library catalog server, but it's on the thinner side. The core borrow/return/search/check lifecycle is covered, yet one might expect more tools for a fuller library domain (e.g., catalog a new book, list member history, list popular books). Still, the stated purpose is narrow enough that 4 is defensible.

Completeness3/5

The core borrowing lifecycle is covered: search to find a book, check availability, borrow, and return. However, there are notable gaps such as no way to list a member's borrowing history, no add_book/register member operations, and no reservation/hold feature. A member could not get a full picture of their loans without an additional tool, creating potential dead ends.

Maintenance

ActivitySlowing
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    An MCP server for managing local Calibre libraries using the calibredb CLI. It allows users to search books, manage metadata, and retrieve EPUB file paths through natural language commands.
    7
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server that provides book recommendation tools, allowing an AI agent to search and filter books by genre, page count, and ratings using the Goodreads dataset.
    1
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that exposes tools for querying a bookstore inventory, allowing AI agents to search and retrieve book information via the Model Context Protocol.
    225
    1
    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/felixyoma4u/LibraryMCP'

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