Find personalized puzzle books by first name from a 100,000+ title Shopify catalog.
on-demand-books MCP Server
An MCP (Model Context Protocol) server that helps AI agents find personalized puzzle books by first name from a 100,000+ title Shopify catalog. It supports searching the On-Demand-Books Shopify catalog and returning a direct Shopify purchase link for the matched book.
π οΈ Key Features
Personalized puzzle book search by the recipientβs first name
Uses a catalog of 100,853 customized books on the On-Demand-Books Shopify store
Exposes 3 tools to agents
π Use Cases
Matching a puzzle book to a gift recipient based on their first name
Providing a direct Shopify purchase link after selecting a personalized book
β‘ Developer Benefits
Works with any MCP-compatible AI agent (e.g., Claude Desktop, opencode)
Designed to let agents search and route users to Shopify for checkout
β οΈ Limitations
The described search scope is personalized puzzle books from the On-Demand-Books Shopify catalog
Captured live from the server via tools/list.
search_books
Search for personalized puzzle books by first name. Returns matching books with direct Shopify purchase links, cover images, and ISBNs. A typical exact match returns 9 books across 3 puzzle types (mazes, name-sudokus, word searches) and 3 difficulty levels. When no exact match exists, returns similarly-named books. Use this whenever a user is shopping for a personalized gift and knows the recipient's first name.
Parameters2
name
string
required
First name to search for personalized puzzle books (e.g. 'Susan', 'Bob'). Case-insensitive; non-letters are stripped.
utm_source
string
optional
Optional UTM source tag for marketing attribution (e.g. 'mcp.so', 'claude', 'hn'). Appended as ?utm_source=<value> to all Shopify product URLs so the seller can track which channel drove the sale. Defaults to 'mcp'.
Raw schema
{
"type": "object",
"properties": {
"name": {
"description": "First name to search for personalized puzzle books (e.g. 'Susan', 'Bob'). Case-insensitive; non-letters are stripped.",
"type": "string"
},
"utm_source": {
"description": "Optional UTM source tag for marketing attribution (e.g. 'mcp.so', 'claude', 'hn'). Appended as ?utm_source=<value> to all Shopify product URLs so the seller can track which channel drove the sale. Defaults to 'mcp'.",
"type": "string"
}
},
"required": [
"name"
]
}
suggest_names
Suggest first names for which personalized puzzle books are likely available. Use this when a user is unsure of a spelling, wants gift-recipient ideas, or only has part of a name. Returns popular available names, optionally filtered by a case-insensitive prefix. To confirm a specific name has matching books, follow up with `search_books`.
Parameters2
limit
integer
optional
Maximum number of suggestions to return (default 20, max 100).
prefix
string
optional
Optional name prefix to complete (e.g. 'su' -> 'Susan', 'Susie', 'Suzanne'). If omitted, returns a curated list of popular names.
Raw schema
{
"type": "object",
"properties": {
"limit": {
"description": "Maximum number of suggestions to return (default 20, max 100).",
"type": "integer"
},
"prefix": {
"description": "Optional name prefix to complete (e.g. 'su' -> 'Susan', 'Susie', 'Suzanne'). If omitted, returns a curated list of popular names.",
"type": "string"
}
}
}
get_book
Re-resolve a single book's purchase URL, cover image, and ISBN from its Shopify product handle. Use this to refresh or re-reference a book across turns without re-running the full name search.
Parameters2
handle
string
required
Shopify product handle (as returned in the `shopify_handle` field of a `search_books` result).
utm_source
string
optional
Optional UTM source tag for marketing attribution (e.g. 'mcp.so', 'claude', 'hn'). Appended as ?utm_source=<value> to the Shopify product URL. Defaults to 'mcp'.
Raw schema
{
"type": "object",
"properties": {
"handle": {
"description": "Shopify product handle (as returned in the `shopify_handle` field of a `search_books` result).",
"type": "string"
},
"utm_source": {
"description": "Optional UTM source tag for marketing attribution (e.g. 'mcp.so', 'claude', 'hn'). Appended as ?utm_source=<value> to the Shopify product URL. Defaults to 'mcp'.",
"type": "string"
}
},
"required": [
"handle"
]
}
Add this server to any MCP-compatible AI agent (Claude Desktop, opencode, etc.)
and your agent will be able to search for books by the recipient's first name
and hand the buyer a direct Shopify purchase link.
Demo
on-demand-books MCP demo
Tools provided
Tool
Purpose
search_books
Search the 100k+ personalized catalog by first name. Returns up to 9 matching books (mazes, name-sudokus, word searches across 3 difficulty levels) with direct Shopify purchase URLs, cover images, and ISBNs. Distinguishes exact matches from similar-name matches.
suggest_names
Suggest popular first names for which books are available, optionally filtered by a prefix. Use when a buyer is unsure of a spelling or wants gift-recipient ideas.
get_book
Re-resolve a single book's Shopify purchase URL from its product handle (as returned by search_books).
Live endpoint
code
https://on-demand-books-dq2yvpdh.fermyon.app/
Hosted on Fermyon Cloud as a Spin + WebAssembly
component built with the wasmcp toolkit.
Add to your MCP client
Claude Desktop / Claude Code (claude_desktop_config.json)
Point any MCP client that supports the Streamable HTTP transport at the
live endpoint above. The server follows the MCP 2025-11-25 spec.
Example agent usage
User: I need a birthday gift for my niece Susan. She likes puzzles.
Agent calls search_books({ "name": "Susan" }) and replies:
Great news β there are 9 personalized puzzle books for Susan, including
"Fun Mazes for Susan β Easy to Medium" and "Fun Name Sudokus for Susan β
Hard to Insane". Here's a direct link to the first one:
https://on-demand-books.com/products/vz5ygw β add it to your cart and
check out on Shopify.
Build & run locally
bash
make setup # Install wasm32-wasip2 target
make build # Output: target/wasm32-wasip2/release/on_demand_books.wasm
wasmcp compose server target/wasm32-wasip2/release/on_demand_books.wasm -o server.wasm --force
spin up --listen 127.0.0.1:8765 # http://127.0.0.1:8765/
Smoke test with curl:
bash
curl -X POST http://127.0.0.1:8765 -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'
curl -X POST http://127.0.0.1:8765 -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
curl -X POST http://127.0.0.1:8765 -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_books","arguments":{"name":"susan"}}}'
Deploy
bash
spin deploy
Implementation
This component uses the capability pattern from wasmcp, implementing just
two methods from the tools-capability interface:
list_tools() β declares the three tools above.
call_tool() β dispatches to the right tool handler and returns the result.
The wasmcp compose CLI wraps the component with the tools-middleware that
handles MCP protocol translation, request delegation, and response formatting.
Outbound HTTP to the search API uses the WASI HTTP outgoing-handler interface
(not raw sockets) so the component runs correctly on Fermyon Cloud.