libapps-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@libapps-mcpfind the psychology research guide and summarize its main page"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
libapps-mcp
Read-only MCP server for LibGuides sites, built on the Springshare LibApps API v1.2. It lets an AI assistant browse published research guides (including every page and sub-page as clean markdown), guide subjects, the A-Z database list, and public subject-librarian profiles. Runs over stdio.
Nothing institution-specific is built in: the API region host, public site URL,
and credentials are all configuration. Without credentials the server still
starts, and every tool returns config_missing.
What this does not do
Write anything (no create/update tools; the app needs GET scopes only)
Show unpublished guides, Internal or Template guides, or draft content
Index content or keep its own search index
Other Springshare products (LibCal, LibAnswers, LibWizard)
Hosted / remote access (see Phase 2)
Related MCP server: superFetch MCP Server
Requirements
A LibGuides CMS site
A read-only LibApps v1.2 application with GET scopes for Guides, Subjects, A-Z, Accounts, and Assets
uv and Python 3.11+
Credentials
In LibApps, go to Tools > API > Applications and create (or reuse) an
application with only the GET scopes above. That page also shows your
region's API host (for example lgapi-us.libapps.com); use it for
LIBAPPS_API_BASE.
Keep the client secret out of git, tickets, and chat. Put it in your MCP host
config or a local, git-ignored env file. .env.example lists the variables
with placeholder values. Rotate the secret if it is ever exposed.
Install
cd /path/to/libapps-mcp
uv sync --extra devClaude / MCP host config
Point Claude Desktop (or another stdio MCP host) at the checkout with
uv run --directory. Replace /path/to/libapps-mcp with your clone path
and the placeholder values with your own:
{
"mcpServers": {
"libapps": {
"command": "uv",
"args": [
"run",
"--directory",
"/path/to/libapps-mcp",
"python",
"-m",
"libapps_mcp"
],
"env": {
"LIBAPPS_API_BASE": "https://lgapi-us.libapps.com",
"LIBAPPS_CLIENT_ID": "your-client-id",
"LIBAPPS_CLIENT_SECRET": "your-client-secret",
"LIBGUIDES_SITE_URL": "https://guides.lib.uchicago.edu"
}
}
}
}You can also run the console script uv run libapps-mcp from a shell for a
quick smoke check.
Configuration
All settings are environment variables. They are read at the first tool call.
Variable | Default | Purpose |
| (required) | OAuth client credentials for the v1.2 app |
|
| Region host: |
| derived from guide URLs | Public site origin, used for page fetches |
| (none) | Extra comma-separated hosts the page fetcher may use |
|
| Read page content from public guide pages. |
|
| Include Private guides and hidden pages/boxes |
|
| Include the public-profile contact email for librarians |
|
| Cache lifetimes (seconds) for the guide list; subjects, accounts, and A-Z; and guide outlines, pages, and searches |
|
| HTTP timeout (seconds) |
|
| Maximum concurrent upstream requests |
|
| Default markdown budget per |
|
| User agent for all requests |
|
| Log level; logs go to stderr only |
Tools
Every tool returns {"ok": true, ...} or
{"ok": false, "error": "...", "code": "..."}. Codes: config_missing,
config_invalid, auth_failed, scope_missing, not_found, not_public,
upstream_error, rate_limited, fetch_blocked, invalid_input. List tools
take limit (max 50) and offset and return total and next_offset
(null when done).
Reading guides: get_guide then get_guide_content
search_guidesfinds a guide.get_guide(guide_id)returns its metadata and the page tree: every visible page and sub-page withpage_id,name,url, and box names.get_guide_content(guide_id, page_id, include_subpages)returns that page as markdown, one entry per content box in display order. Withinclude_subpages=trueit adds the page's sub-pages. Each response also includes the fulloutline, so the assistant can move to any other page.
search_guides
Argument | Notes |
| Uses the site's relevance-ranked guide search ( |
| Subject name (substring) or id |
| Owner name; only owners with a public profile can match |
|
|
| Default 10 / 0 |
Returns id, name, url, description, type, subjects, updated,
rank, and owner (name and profile link) when the owner has a public profile.
get_guide
Argument | Notes |
| Numeric guide id |
Pages have page_id, name, url, parent_id, box_count, boxes
(box_id, name, column, position), and subpages. Link pages carry
redirect_url and are never followed.
get_guide_content
Argument | Notes |
| Numeric guide id |
| Defaults to the guide's first page |
| Add the page's sub-pages (default |
|
|
| Markdown budget (default |
| Box index to resume from (use |
Boxes that are in the outline but not on the page are marked missing. A box
cut to fit the budget is marked truncated. Embedded widgets become
[embedded: ...] placeholders.
list_subjects
with_published_guides (default true) limits the list to subjects that have
published guides. Returns id, name, slug, and parent_id.
search_databases
Argument | Notes |
| Matches name, alternate names, vendor, and description |
| Name (substring) or id |
| Default 20 / 0 |
Returns id, name, url, proxied, vendor, a short description,
subjects, types, and alt_names / new / trial / popular when available.
get_database
database_id: the same fields with the full description and more_info.
find_subject_librarians
subject: name or id. Returns librarians with a public profile for that
subject: name, title, pronouns, profile_url, image_url, subjects,
and the contact details (phone, address, website) they chose to show
publicly.
Privacy and safety
Published only. Unpublished, Internal, and Template guides are never returned. Private guides and hidden pages/boxes need
LIBAPPS_INCLUDE_PRIVATE=1.Allowlisted output. Every result is built field by field. Login emails, account ids, widget code, and A-Z internal notes and reviews are never returned. Librarians without a public profile are excluded. Contact details appear only when the profile shows them, and the profile email only with
LIBAPPS_EXPOSE_EMAIL=1.No email addresses by default. Unless
LIBAPPS_EXPOSE_EMAIL=1, email addresses in page text and descriptions are replaced with[email removed].Secrets stay private. The client secret and access token are never logged or returned; settings
repr()hides the credentials.Safe page fetches. Only
httpsURLs from API data, on the site host orLIBGUIDES_ALLOWED_HOSTS. Redirects are re-checked (max 3), pages are capped at 2 MB and must betext/html, and no cookies or auth headers are sent.Polite client. Cached responses, a concurrency cap,
gzip, and backoff on 429/5xx.
Development
uv run pytestUnit tests mock all HTTP with synthetic fixtures. An opt-in live smoke test reads credentials from the environment and asserts only on shapes and counts:
LIBAPPS_LIVE_TESTS=1 uv run pytest -m liveNotes on the API behaviors this server relies on are in
docs/api-notes.md.
To verify a running server end to end against the live API (stdio startup,
every tool, privacy and status filters, error shapes), follow
.claude/skills/verify-libapps-mcp/SKILL.md.
Its driver reads credentials from ~/.config/libapps-mcp/env. If only
~/.config/uc-libapps-mcp/env exists (the path used before this project was
renamed from uc-libapps-mcp), it reads that instead.
Phase 2: hosted (later)
A later phase adds a streamable HTTP transport served at /mcp behind TLS and
an authenticating proxy, with per-deployment LibApps credentials kept
server-side.
License
MIT
Available Tools
7 toolsfind_subject_librariansARead-only
Find librarians with a public profile for a subject (name or id). Returns names, titles, profile links, and contact details they chose to show publicly.
| Name | Required | Description | Default |
|---|---|---|---|
| subject | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds meaningful context that only public profiles are returned and that contact details are self-disclosed, which helps the agent set expectations, but it says nothing about result counts, pagination, or auth needs.
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?
Two tight sentences with the purpose front-loaded and the return contents following. No filler, no repetition of the tool name beyond what is needed.
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 lookup with an output schema present, the description covers purpose and input format adequately. Its description of return fields is mildly redundant given the output schema, but nothing an agent needs in order to call it correctly 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 description coverage is 0% for the single 'subject' parameter, so the description must compensate — and it does, clarifying that subject accepts a 'name or id'. That is the key ambiguity an agent would otherwise have to guess.
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?
States a specific verb and resource ('Find librarians') with a scoping qualifier ('with a public profile for a subject'). It is clearly distinguishable from siblings like list_subjects or search_guides, though it does not name a sibling or contrast with one.
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 'for a subject' framing implies when the tool applies, but there is no explicit when-to-use guidance, no prerequisites, and no mention of the alternatives (list_subjects, search_guides) that could confuse an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_databaseARead-only
Get one A-Z database by id, with its full description and access URL.
| Name | Required | Description | Default |
|---|---|---|---|
| database_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety and reach profile is covered. The description adds that the full description and access URL are returned, which is modest extra context, but says nothing about failure behavior when the id is unknown.
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?
One compact sentence with the verb, scope, and return payload front-loaded; no filler whatsoever.
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?
An output schema exists, so return values need no further explanation, and the read-only annotation covers safety. What remains missing is any note on the id format or behavior for a non-existent id, minor gaps for a simple 1-param lookup.
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?
There is a single parameter with 0% schema description coverage, so the schema gives no guidance on the id's format. The description only confirms it is an id-based lookup, adding marginal meaning beyond the schema.
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?
States a specific verb and resource ('Get one A-Z database by id') and what the response contains ('full description and access URL'). It is clearly a single-item retrieval tool, though it never names search_databases as the contrasting alternative, so sibling differentiation is only implicit.
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?
Usage is implied by 'by id' — the agent infers it needs an id and should use this rather than search_databases — but there is no explicit statement of when to use this versus the search or list siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_guideARead-only
Get a guide's metadata and its full page outline: a tree of pages and sub-pages with page_id, name, url, and box names. Use get_guide_content with a page_id to read a page.
| Name | Required | Description | Default |
|---|---|---|---|
| guide_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds useful shape information about the returned tree (page_id, name, url, box names), but says nothing about authentication, rate limits, or failure modes for an unknown guide_id. It adds some value beyond annotations without being rich.
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?
Two sentences, no filler. The output shape is stated first and the routing hint is appended last where it is most useful, so 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?
An output schema exists, so the description need not restate return values, and it still sketches the outline structure helpfully. Combined with annotations covering the read-only nature, the definition is nearly complete; only the provenance of guide_id remains unaddressed.
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 0%, so the schema supplies no meaning for guide_id and the description does not explain its format or where to obtain it (e.g., via search_guides). The single identifier is largely self-explanatory in context, which keeps this from being a real failure, but the description does not compensate for the coverage gap.
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?
States a specific verb and resource ('Get a guide's metadata and its full page outline') and then enumerates exactly what the outline contains: a tree of pages with page_id, name, url, and box names. This is concrete enough to distinguish it from siblings like get_guide_content and search_guides without opening any schema.
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 routes the agent to the closest alternative: 'Use get_guide_content with a page_id to read a page.' That resolves the most likely confusion (metadata/outline vs. page body). It does not, however, say when to prefer this over search_guides or list_subjects, so guidance is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_guide_contentARead-only
Read a guide page as markdown, one entry per content box in display order. Defaults to the guide's first page; pass page_id (from get_guide or the returned outline) for another page, and include_subpages=true to add its sub-pages. source: auto (default), html (public page), or api (unplaced text blocks for the whole guide). Output is capped at max_chars; continue with offset=next_offset.
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | ||
| source | No | auto | |
| page_id | No | ||
| guide_id | Yes | ||
| max_chars | No | ||
| include_subpages | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint; the description adds substantive behavior beyond them, namely the default-to-first-page semantics, the output cap via max_chars, and the offset=next_offset continuation pattern. It does not describe error cases or what happens when source=auto falls back, but the added context is solid.
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?
Four dense sentences, front-loaded with the primary action and return format, followed by parameter behavior in priority order (defaults, page selection, pagination). No filler and every clause carries usable information.
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 6-parameter read tool with annotations and an output schema, the description covers defaults, source modes, and pagination adequately, and return-value detail is rightly delegated to the output schema. The only gap is that it never tells the agent where guide_id comes from (search_guides/get_guide).
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 0%, so the description must carry the load, and it does: source is enumerated and explained (auto/html/api), page_id, include_subpages, max_chars and offset are all given meaning, and offset's value is tied to the returned next_offset. Only guide_id is left unexplained, though it is the obvious required identifier.
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?
States a specific verb and resource ('Read a guide page as markdown') plus the return shape ('one entry per content box in display order'), which is far more than a restatement of the name. By naming get_guide as the source of page_id, it implicitly distinguishes content retrieval from guide metadata lookup among its siblings.
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?
Gives concrete selection rules for the optional parameters: page_id for a non-first page, include_subpages=true to expand sub-pages, and source modes auto/html/api. It lacks an explicit 'when not to use this' or a direct comparison against get_guide, which keeps it short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_subjectsARead-only
List the site's guide subjects (id, name, slug). By default only subjects that have published guides.
| Name | Required | Description | Default |
|---|---|---|---|
| with_published_guides | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds the useful default-scoping behavior, but says nothing about pagination, ordering, or result size for a list operation.
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?
Two short sentences, zero waste, with the resource and scope front-loaded ahead of the default-behavior caveat.
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?
An output schema exists, so return-value detail is not required, and the description already names the key fields. The only gap is the unexplained non-default branch of the single parameter, which is minor for a simple read-only lister.
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 0% for the single boolean parameter, so the description must compensate. It explains the default state (with_published_guides effectively true) but never states what the non-default value returns, leaving half the semantics implied.
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?
States a specific verb (List) and resource (the site's guide subjects) and names the returned fields (id, name, slug). It is distinguishable from siblings like search_guides and get_database, though it never explicitly contrasts itself with them.
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 default filtering behavior ('By default only subjects that have published guides') implies when the tool is useful, but there is no explicit when-to-use/when-not guidance or named alternative among the sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_databasesARead-only
Search the A-Z database list by name, alternate names, vendor, and description. Optional filters: subject and az_type (name or id). Without a query, lists databases alphabetically. Paginate with limit (max 50) and offset.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | No | ||
| offset | No | ||
| az_type | No | ||
| subject | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds real behavioral detail beyond that: the no-query fallback returns an alphabetical listing, and limit is capped at 50, which the agent cannot infer from the schema alone.
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 dense sentences, front-loaded with the primary purpose followed by filters, fallback behavior, and pagination. No filler; only the offset clause is slightly under-developed.
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?
An output schema exists, so return values need not be described. Combined with the parameter explanations, the bounded pagination, and the empty-query behavior, the definition covers what an agent needs to call it correctly; only offset semantics remain thin.
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 0%, so the description must carry the load, and it mostly does: it defines what query searches, names subject and az_type (accepting name or id), and supplies the max-50 limit constraint that the schema's default-20 lacks. offset is mentioned but not explained, leaving a small gap.
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?
States a specific verb (Search) and resource (the A-Z database list) plus the fields searched (name, alternate names, vendor, description). This clearly separates it from search_guides or list_subjects, though it never explicitly names a sibling.
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?
It implies usage by noting that omitting a query lists databases alphabetically and that subject/az_type are the optional filters, which tells the agent how to get a browse-style result. However, it gives no guidance on when to prefer this over get_database for a single record or list_subjects for discovering filter values.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_guidesARead-only
Search published research guides. With a query, uses the site's relevance-ranked full-text guide search (source 'server'); without one, or if that search fails, matches guide names, subjects, descriptions, and owner names locally (source 'local'). Optional filters: subject (name or id), owner (public profile name), guide_type (e.g. subject, course, topic, general, or type id). Paginate with limit (max 50) and offset; next_offset is null when done.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| owner | No | ||
| query | No | ||
| offset | No | ||
| subject | No | ||
| guide_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true and openWorldHint=true, so safety is covered. The description adds genuine behavioral context beyond that: the dual server/local search path, the silent fallback on server failure, and the returned 'source' indicator. It does not mention rate limits or auth, which are minor gaps for a read search.
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 dense sentences front-loaded with the core action, followed by mechanics and filters; every clause carries information about behavior or parameters. It is slightly crowded but no sentence is wasted.
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?
An output schema exists, so return values need not be spelled out, yet the description still notes the 'source' field and that next_offset is null when done, which aids pagination loops. Combined with filter and search-path coverage, an agent has what it needs to call this 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 0%, so the description must carry parameter meaning, and it does: subject accepts name or id, owner is a public profile name, guide_type gives concrete examples, and limit is capped at max 50 with offset-based pagination. This fully compensates for the undocumented schema.
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?
States a specific verb and resource ('Search published research guides') with a scope qualifier ('published') that separates it from get_guide/get_guide_content. It does not explicitly name a sibling to contrast with, so the differentiation is inferred from the search-vs-retrieve naming rather than stated.
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 clearly explains the conditional behavior (query present → server relevance search; absent or failing → local match), which is useful invocation guidance. However, it never states when to prefer this tool over siblings like search_databases or get_guide, so usage is implied rather than directed.
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.
7 tool updates
v0.1.0- First observed
find_subject_librarians - First observed
get_database - First observed
get_guide - First observed
get_guide_content - First observed
list_subjects - First observed
search_databases - First observed
search_guides
TDQS
Scored across 7 tools
Most tools target clearly distinct resources and actions, with search_guides (find), get_guide (metadata+outline), and get_guide_content (page text) forming a coherent retrieval pipeline. The get_guide vs get_guide_content pair is the only mild overlap, but descriptions clearly delineate their roles.
All seven tools follow a consistent verb_noun pattern (list_subjects, search_guides, get_guide, get_guide_content, search_databases, get_database, find_subject_librarians). Verb variety (list/search/get/find) reflects genuinely different operations rather than inconsistency.
Seven tools is well-scoped for an A-Z database and research guide server, with each tool earning its place across the subjects, guides, databases, and librarians domains. No redundant or trivial tools.
The surface covers the core read workflows: subjects, guide discovery and content, databases, and subject librarians, with pagination handled throughout. As a read-only surface it lacks write operations and some minor browse helpers (e.g., listing guide types), but core research workflows are covered.
Maintenance
Related MCP Connectors
Read-only MCP server exposing a user ORANO library to their own AI agent.
Read any web page as clean Markdown for AI agents: fetch, search, metadata, links. SSRF-safe.
Read-only Bicycle Guide registry: published guides, homes, taxonomy, capability spine. No auth.
Read-only Bicycle Guide registry: published guides, homes, taxonomy, capability spine. No auth.
Related MCP Servers
- AlicenseAqualityAmaintenanceThis server enables LLMs to retrieve and process content from web pages, converting HTML to markdown for easier consumption.21156,058 PyPI91,067MIT
- AlicenseAqualityCmaintenanceAn MCP server that fetches web pages and extracts clean, AI-friendly Markdown content using Mozilla Readability. It provides secure web access for LLMs with built-in SSRF protection and automated content cleaning for improved context retrieval and summarization.190 npmMIT
- FlicenseNot gradedqualityDmaintenanceRead-only MCP server for browsing, searching, and exporting a Zotero library from AI assistants.-
- AlicenseNot gradedqualityCmaintenanceA lightweight MCP server that fetches URLs and returns clean, readable markdown, enabling AI assistants to read any webpage with article extraction, caching, and security features.3MIT