Skip to main content
Glama
BrianVia

fcpl-mcp

fcpl-mcp

A remote Model Context Protocol server for one Fairfax County Public Library patron account, hosted on Cloudflare Workers. It searches the Polaris catalog, reads account activity, and manages physical-item holds.

One Worker serves a bearer-protected, stateless /mcp endpoint. A Durable Object owns the Polaris cookies and serializes requests because catalog searches store state in the server session.

Setup

npm install
npx wrangler login
cp wrangler.jsonc wrangler.local.jsonc

In wrangler.local.jsonc, replace fcpl.example.com with a hostname on a Cloudflare zone you manage. Deploy using that local config:

WRANGLER_CONFIG=wrangler.local.jsonc npm run deploy
npx wrangler secret put FCPL_USERNAME --config wrangler.local.jsonc
npx wrangler secret put FCPL_PASSWORD --config wrangler.local.jsonc
openssl rand -hex 32 | tee /dev/stderr | npx wrangler secret put MCP_BEARER --config wrangler.local.jsonc

The custom-domain route creates its DNS record on first deploy.

Related MCP server: adisweb

Tools

Tool

Description

search_catalog

Search by keyword, title, author, subject, or ISBN

get_title

Get title details and availability by branch

get_checkouts

List checkouts sorted by due date

get_holds

List account holds

get_account

Get patron record fields and the fines total

place_hold

Place a physical-item hold at the saved default pickup library

cancel_hold

Cancel a physical-item hold

place_hold and cancel_hold change the real account. Confirm those actions with the user first.

Raw HTTP

The endpoint uses stateless Streamable HTTP and returns SSE-framed MCP responses.

curl -s https://fcpl.example.com/mcp -X POST \
  -H 'Authorization: Bearer <MCP_BEARER>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

GET / identifies the MCP endpoint. GET /health is public and reports whether the Durable Object currently has session cookies without making a network request.

Local development

cp .dev.vars.example .dev.vars
npm run check
npx wrangler dev

Notes

  • Built against Fairfax County's Polaris PowerPAC 7.8 catalog at fcplcat.fairfaxcounty.gov. Other Polaris libraries likely work by changing BASE in src/polaris.ts, but that is untested.

  • Polaris sessions expire after a few idle minutes; the server logs in again automatically.

  • No renew tool on purpose: FCPL auto-renews items. Check renewalsLeft from get_checkouts if you care.

  • Holds use the patron account's saved default pickup library.

  • eContent holds are visible but must be cancelled in Libby or OverDrive.

  • This is an unofficial scraper and may break when Polaris changes its HTML or request flow.

  • Credentials are Worker secrets and are sent only to the library catalog login endpoint.

  • /mcp requires MCP_BEARER; / and /health are public.

License

MIT. See LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables searching for lawful, free-to-read books across multiple open catalogues and resolving access routes (download, read, borrow, preview) via MCP tools like search_books and resolve_access.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables searching library catalogs, checking availability, and managing patron accounts (loans, renewals, reservations, orders) in aDISWeb-based OPACs through any MCP client.
    GPL 3.0