Content
# Tool List
Shopby-mcp is a tool for searching Shopby API documentation.
Shopby official documentation does not have a search function, so you have to find what you need manually. This tool indexes the entire Shopby OpenAPI (YAML) specification, allowing you to search for APIs using natural language with Claude.
- **The search function is not available, but the data is perfectly structured** (OpenAPI 3.0). You don't need to create a new LLM; just parse and index the specification.
- Two ways to use it: ① **MCP Server** with Claude (Code/Desktop), ② Terminal CLI.
- It automatically updates with remote index (`config.json`) and yml conditional checks. However, the specification changes monthly, so it checks **only once a day**.
> ⚠️ **Unofficial tool.** Not an official NHN Commerce/Shopby product.
> The official client SDK is [`@shopby/shop-sdk`](https://www.npmjs.com/package/@shopby/shop-sdk) (for API **calls**), and this package is for **document search/exploration** — they have different roles and work well together.
## Composition
```
shopby-mcp/
├─ cache-paths.mjs # Cache path/host mapping (shared)
├─ specs-index.json # Fallback index (file list) included. Used only when remote config.json is not available
├─ download-specs.mjs # Index + yml conditional update (refreshAll) + CLI entry point
├─ shopby-index.mjs # Core: yml load + flattening + search + $ref interpretation
├─ shopby-cli.mjs # Terminal search/detail inquiry
├─ shopby-mcp.mjs # MCP Server (Claude connection, automatic update on start)
├─ spec/ # (gitignore·not distributed) Locally received yml temporary copy. Actual runtime reads from cache below
└─ (runtime) ~/.cache/shopby-mcp/{spec/*.yml, specs-index.json, .etags.json} ← yml is received here on first execution (network required)
```
> ⚠️ **yml specification is not included in the npm package.** It's received from remote on first execution (=network required).
> The included file is `specs-index.json` (file list) — a fallback index when remote `config.json` is not available.
## Installation — Claude Code (Recommended: npx, no clone needed)
```bash
claude mcp add shopby-docs -- npx -y shopby-mcp
```
That's it. `npx` downloads and executes the package, and the server **automatically downloads the specification to `~/.cache/shopby-mcp/` on first execution**. Then, you can just ask Claude:
- "Find the Shopby cart list API"
- "What filters are available for the brand list API?"
- "Show me all APIs related to order cancellation"
Claude will automatically call the `search_apis` → `get_api_detail` tool to answer.
> Team sharing: place `.mcp.json` in the repository root, and team members can use the same settings by cloning only.
> ```json
> { "mcpServers": { "shopby-docs": { "command": "npx", "args": ["-y", "shopby-mcp"] } } }
> ```
## Installation — Claude Desktop
Add to `claude_desktop_config.json`'s `mcpServers`:
```json
{
"mcpServers": {
"shopby-docs": { "command": "npx", "args": ["-y", "shopby-mcp"] }
}
}
```
## Usage via CLI (without Claude, in terminal)
```bash
npx -p shopby-mcp shopby-cli "cart list" # API search
npx -p shopby-mcp shopby-cli --detail get-cart # Specific API details
# Frequent usage: global installation
npm i -g shopby-mcp
shopby-cli "brand list filters"
```
Detail inquiry (`--detail <operationId>`) shows **filter names, types, required, enum, and descriptions**.
## Local Development (from source)
```bash
npm install
node shopby-cli.mjs "cart list"
claude mcp add shopby-docs-dev -- node "$(pwd)/shopby-mcp.mjs"
```
### Claude Desktop Connection
Add the same JSON as above to `claude_desktop_config.json`'s `mcpServers`.
## Exposed MCP Tools
| Tool | Description |
|----|------|
| `search_apis(query, category?, limit?)` | Natural language API search. Searches explanations, tags, paths, parameters, **response/request body field names**. Can narrow down by category (shop/server) |
| `list_apis(tag?, category?, limit?)` | **Domain browsing.** Without arguments, shows tag list (+count); with tag, lists endpoints. Useful for browsing when you don't know keywords |
| `get_api_detail(operationId, source?, section?)` | Specific API details: filters, request body (media type), response schema. `section` for scope selection (`filters`=parameters only, minimal / `request` / `response` / `all`). Distinguishes between sources with `source` |
| `index_stats()` | Loaded specification count / total API count |
> **Search vs Browsing**: If you have a keyword, use `search_apis`; if you want to browse, use `list_apis`. Both provide light lists, and detailed schema is available with `get_api_detail` when needed.
### Field-based Search
Indexed **response/request body field names and descriptions**, allowing **"find APIs containing specific fields"**:
- "Find APIs with member grade (couponAutoSupplying/accumulation rate) info" → finds member grade API
- "Where is the slug field used in the response?" → narrows down candidates by field name
Precise searches can be done using actual field names (camelCase); vague searches can use Korean field descriptions.
Search results include **"rationale"** (summary/field name/path, etc., where matched), so you can see **why a specific API was returned**.
## Operation Principle (Summary)
1. Parse all `spec/*.yml` → flatten each operation into one record.
Each record includes method, path, operationId, tags, summary, description, **parameters**, and **response/request field names**.
2. Search uses weighted keyword matching on Korean summary/tag descriptions/operationId/path/parameters/**schema field names**.
Shopby specification summaries/descriptions are in Korean, so Korean queries work directly.
(Weight: summary/tag descriptions 5 > operationId 4 > path/tag 3 > description/**field names** 2 > parameters 1)
**Recall reinforcement**: Korean-English domain synonyms (e.g., reserve↔적립금, grade↔등급) and camelCase decomposition (brandNo→brand/no) help Korean queries reach English field names/paths.
3. Search/detail inquiries recursively interpret `$ref` (`#/components/schemas/...`).
## Automatic Update (Specification Changes)
Shopby updates APIs monthly/regularly. The index (`config.json`) and yml URLs are **always up-to-date**, and servers provide ETag/Last-Modified headers, so MCP servers **automatically check for updates on start**.
Startup sequence:
1. **Index update** — conditionally receive `https://docs.shopby.co.kr/config.json` for the latest file list.
2. **yml update** — conditionally check each yml based on the latest index → receive **only changed files**.
3. Build search index with cached yml → start MCP server.
- MCP restarts with each new Claude session, so **new sessions automatically reflect updates** (no changes during a session).
- **New module (new yml file) additions are automatically discovered** — the index is updated, so new file names are automatically received.
- Most cases return 304, so it's fast. Change/new/failed logs are output to stderr.
- In case of offline/outages, **cached data is quietly used as a fallback**. The index (`config.json`) falls back to the included `specs-index.json`.
**Check cycle (TTL):** Shopby specifications usually change **every few weeks to a month**, so daily network checks are unnecessary.
Default TTL is **24 hours** — if the last check was within 24h, **no network check is performed**, and if 24h have passed, a conditional check is done.
Flags/Environment Variables:
| Flag/Variable | Default | Description |
|------|--------|------|
| `--refresh` | — | Force re-download of index+yml (ignore ETag) |
| `SHOPBY_MCP_NO_REFRESH` | `0` | If `1`, skip startup checks (use cache only) |
| `SHOPBY_MCP_MAX_AGE` | `86400` (24h) | Seconds. If the last check was within this time, skip network checks. `0` for always checking |
| `SHOPBY_MCP_CACHE_DIR` | `~/.cache/shopby-mcp` | Cache directory location |
| `SHOPBY_MCP_INDEX_URL` | `docs.shopby.co.kr/config.json` | Index URL (if Shopby domain changes) |
| `SHOPBY_REQUEST_TIMEOUT_MS` | `8000` | Request timeout per file (practically, the total time is also within this limit) |
Manual updates are possible: `npm run download` (conditional index+yml checks).
> ℹ️ **admin/internal areas are intentionally excluded** (not for bot usage).
> Although they are in the index, they are not received due to no host in `cache-paths.mjs`'s `HOST_BY_CATEGORY`. Only shop+server are indexed.
## Extension Ideas
- **Semantic search**: If keywords are insufficient, add vector search by embedding operation summaries (small corpus works well without it).
- **In-house Slack bot**: Import `search`/`getApi` from `shopby-index.mjs` and expose it as Slack slash commands.