sunleaf
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., "@sunleafDo you have a caffeine-free tea under $15?"
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.
Sunleaf MCP Demo
An MCP server that lets AI assistants such as Claude Desktop and Cursor answer customer questions from a shop's own files: its product catalog, FAQs and policy pages.
Demo with fictional sample data. Not a client project.
What it shows
A business's own files, connected to an AI assistant. Sunleaf Tea Co. is a made-up tea shop. Its catalog, FAQs and policies are plain JSON and Markdown files in
data/.Read-only. The assistant can search and read. It cannot change anything.
Cited answers. Every passage comes with an id the assistant can cite, such as
[faq-006]or[policy:returns#opened-tins], and each policy's scope rules travel with any section of it that is returned.Honest when unsure. When nothing in the data matches, the server says so. When only part of a question matches, it returns the closest passages marked as partial, and the assistant is told to answer only from what they actually say.
No API keys, no network calls. The server runs locally over stdio and makes no network requests itself. Your AI client may send the data it returns to its model provider (see Security notes).
Related MCP server: Shopify MCP Server
Tools, resources and prompt
Name | Kind | What it does |
| tool | Keyword search over the catalog, with optional category and in-stock filters |
| tool | Full details for one product id |
| tool | The best-matching FAQ entries, with their ids |
| tool | The full shipping, returns, privacy or wholesale policy |
| tool | Searches FAQs and policies together. Returns cited passages marked as answers or partial matches, with each policy's scope rules, and says so when nothing matches |
| resource | All products (JSON) |
| resource | All FAQs (JSON) |
| resource template | One policy (Markdown) |
| prompt | Drafts a reply to a customer message using only these sources |
Quick start
You need Node.js 20 or later to run the server. The tests need Node.js 22.12 or later.
git clone https://github.com/panditfloki/sunleaf-mcp-demo.git
cd sunleaf-mcp-demo
npm install
npm run build
npm testConnect to Claude Desktop
Open the Claude Desktop config file (create it if it does not exist):
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%AppData%\Claude\claude_desktop_config.json
Add the server, using the absolute path to your copy of this repository:
{ "mcpServers": { "sunleaf": { "command": "node", "args": ["/ABSOLUTE/PATH/TO/sunleaf-mcp-demo/build/index.js"] } } }Quit Claude Desktop completely and open it again.
If the server does not show up, check the logs (
~/Library/Logs/Claude/mcp*.logon macOS). If Claude cannot findnode, which is common when Node.js was installed with nvm, replace"node"with the full path thatwhich nodeprints.
A ready-to-edit copy is in examples/claude_desktop_config.json.
Connect to Cursor
Add this to .cursor/mcp.json in this folder, then open the folder in Cursor:
{
"mcpServers": {
"sunleaf": {
"type": "stdio",
"command": "node",
"args": ["${workspaceFolder}/build/index.js"]
}
}
}To use it in every project, put the same entry in ~/.cursor/mcp.json with an absolute path instead of ${workspaceFolder}. In Cursor Settings, the MCP section should then show sunleaf as connected. A copy is in examples/cursor-mcp.json.
Test with MCP Inspector
MCP Inspector needs Node.js 22.19 or later.
npm run inspectThis opens the Inspector in your browser, where you can list the tools and call them. For a scripted check:
npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/listQuestions to try
"Do you have a caffeine-free tea under $15?"
"What is your return policy for opened tins?"
"How should I brew the Darjeeling first flush?"
"Do you ship to Canada?" The shipping policy lists where the shop ships and Canada is not on it, so the assistant should say no and cite the policy.
"What is your FSSAI licence number?" The data does not hold it, so the assistant should say the data does not cover it.
Use your own data
Point the server at your own folder with the SUNLEAF_DATA_DIR environment variable. The folder needs the same layout:
my-shop/
products.json
faqs.json
policies/
shipping.md
returns.md
privacy.md
wholesale.mdproducts.json: an array of products with
id,name,category,price_inr,price_usd,sizes(list),in_stock(true or false),tags(list) andshort_description.faqs.json: an array of FAQs with
id,question,answerandtags(list), plus an optionalpolicy(shipping,returns,privacyorwholesale) naming the policy that governs the FAQ. The named policy file must exist.policies/: Markdown files. Each
##heading becomes a separate section that can be cited. Missing policy files are skipped.Start each policy with a section that states its scope, such as where you ship or who can apply.
answer_sourcesreturns that first section together with any other section of the same policy and with any FAQ linked to it throughpolicy, so an answer about shipping costs or a wholesale FAQ cannot lose the rule about destinations.Ids ignore case and surrounding spaces, in validation and lookup alike.
X-1andx-1count as the same id, so a file with both is rejected as a duplicate.
The server checks both JSON files when it starts, and stops with a clear message if a field is missing or an id is used twice.
In Claude Desktop, set the variable in the server entry:
"sunleaf": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/sunleaf-mcp-demo/build/index.js"],
"env": { "SUNLEAF_DATA_DIR": "/ABSOLUTE/PATH/TO/my-shop" }
}Use an absolute path. A relative path is resolved from this package's folder, not from wherever the AI client starts.
Screenshots
Coming soon: Claude Desktop (docs/claude-desktop.png), Cursor (docs/cursor.png), MCP Inspector (docs/inspector.png) and a short demo GIF (docs/demo.gif).
Security notes
Read-only. No tool writes, deletes or sends anything.
Local files only. The server reads its data folder and nothing else. It makes no network calls.
stdio. It runs as a local process that your AI client starts and stops.
Real business data. Whatever the tools return is shown to the AI client and, through it, to the model provider. Only put in the data folder what you are comfortable sharing that way.
How it works
src/index.tsstarts the server over stdio. It never writes to stdout, because stdout carries the MCP protocol. Logs go to stderr.src/server.tsregisters the tools, resources and prompt with the official MCP TypeScript SDK (@modelcontextprotocol/serverv2).src/search.tsis a small offline keyword search. A word in a product name or FAQ question counts 3 times, in tags 2 times and in body text once, and rare words count more than common ones.answer_sourcesgrades each passage by the share of the question it covers, weighted by rarity. At least half: it is returned as an answer. Less: the closest passages come back marked as partial, because some questions are answered by exclusion ("Do you ship to Canada?" is answered by the list of countries the shop ships to). Nothing at all: it says so.src/data.tsloads and checks the data folder.
Limits. This is keyword search, not semantic search. A paraphrase that shares no words with the data can miss, and no retrieval method can guarantee that an AI never guesses. For real business data, add embeddings or a synonym list, and keep the instruction to answer only from returned passages.
Development
npm run dev # run from source with tsx
npm test # unit tests and an in-process client/server test
npm run build # compile to build/License
MIT. See LICENSE.
© 2026 dydxfx · https://dydxfx.com
Available Tools
5 toolsanswer_sourcesFind answer sourcesARead-onlyIdempotent
Search the FAQs and policies together for a customer question. Returns passages with ids to cite, marked as answers or as partial matches, plus the scope rules of any policy they come from or are governed by. A partial match can still answer by exclusion: a list of the countries the shop ships to answers whether it ships somewhere else. If nothing matches, it says so: tell the customer instead of guessing.
| Name | Required | Description | Default |
|---|---|---|---|
| question | Yes | The customer's question, in their own words |
Output Schema
| Name | Required | Description |
|---|---|---|
| match | Yes | |
| sources | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, etc. The description adds valuable context beyond that: partial matches can answer by exclusion, and the tool explicitly reports no match. This helps the agent interpret results and decide how to respond, but it doesn't cover other behavioral aspects like rate limits or error handling, which are less critical 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact (two sentences) and front-loaded with the core action, followed by result details and behavioral guidance. No wasted words; every sentence contributes to understanding the tool.
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 tool with an output schema and safety annotations, the description covers all essential aspects: what it returns, how to interpret partial matches, and how to handle no-match cases. Nothing critical is missing for correct invocation and response handling.
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 100% and the single parameter 'question' is already well-described in the schema. The description reinforces the parameter's purpose by linking it to the FAQ/policy search, but adds minimal new meaning beyond the schema, so a baseline 3 is appropriate.
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?
The description clearly states a specific verb (search) and resource (FAQs + policies together), and describes what it returns (passages with ids, marked as answers/partial matches, plus scope rules). It effectively differentiates from siblings like search_faqs and search_policy by combining both corpora.
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 when to use the tool (for customer questions spanning both FAQs and policies) but does not explicitly name alternatives or exclusions. It gives behavioral guidance for no-match scenarios, which helps with decision-making, but lacks explicit routing compared to other tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_policyGet policyARead-onlyIdempotent
The full text of one Sunleaf store policy as Markdown: shipping, returns, privacy or wholesale.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Which policy to read |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the Markdown output format detail, which is useful but minimal additional context. No contradiction with annotations.
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?
A single front-loaded sentence with zero filler. The core purpose, format, and available options are packed efficiently without redundancy.
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 simple single-parameter read tool with full schema coverage and comprehensive annotations, the description is nearly complete. It specifies the output format and available values; the only gap is behavior for invalid input, which the enum constraint largely mitigates.
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 coverage is 100%, with the single 'name' parameter fully documented via its enum and description. The description's list of policies (shipping, returns, privacy, wholesale) mirrors the enum values, adding little beyond what the schema already provides. Baseline 3 is appropriate.
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 resource (Sunleaf store policy), the deliverable (full text as Markdown), and enumerates the four available policies. This clearly distinguishes it from siblings like search_faqs and search_products, which retrieve different content types.
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 implies usage for policy text retrieval by listing the policy names, but offers no explicit when-to-use vs. alternatives guidance. It does not reference siblings or state exclusions, though the enumerated policy list narrows scope effectively.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_productGet productARead-onlyIdempotent
Full details for one Sunleaf product by its id (from search_products): description, sizes, tags, price and stock.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Product id, for example SL-HRB-001 |
Output Schema
| Name | Required | Description |
|---|---|---|
| product | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds that the tool returns a single product's full details with specific fields, but it does not disclose operational behavior such as not-found handling or rate limits; given annotation coverage, this is adequate rather than exceptional.
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 front-loaded sentence conveys the resource, the id source, and the returned fields with no filler. Every phrase earns its place, and it is immediately scannable by an agent.
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 simple one-parameter getter, the combination of description, full input schema, output schema, and safety annotations is complete. The description tells an agent exactly what will be returned, and nothing essential 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?
The input schema already documents id with type, minLength, and an example, so the baseline is 3. The description adds meaning beyond the schema by clarifying that the id comes from search_products and identifies a specific Sunleaf product, which helps an agent chain tools correctly.
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?
The description states a specific action and resource: 'Full details for one Sunleaf product by its id.' It also lists the contained fields and explicitly references search_products as the source of the id, so the tool is clearly distinguished from the search-style sibling tools.
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 gives clear usage context by saying the id comes from search_products, which routes an agent to first call search_products and then this tool. It does not explicitly state when-not-to-use exclusions, but the intended workflow is evident and the sibling list is small enough to make the guidance safe.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_faqsSearch FAQsARead-onlyIdempotent
Find the Sunleaf FAQ entries that best match a question. Returns each question and answer with its FAQ id for citation.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | The customer's question or keywords | |
| max_results | No | How many FAQs to return, 1 to 5 (default 3) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only, idempotent, non-destructive safety profile. The description adds the return shape and the 'best match' ranking behavior, but does not disclose edge behavior such as empty results, ranking details, or what happens when no FAQ matches.
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 no filler: the first front-loads the action and scope, the second states the return value and intended citation use. Every phrase 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?
For a simple two-parameter read-only search with full schema coverage, the description provides enough operational context: scope, return content, and citation purpose. It lacks only minor guidance on no-result behavior and sibling-tool differentiation, which are not critical for this low-complexity tool.
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 100%, so the parameters are already fully documented. The description adds little beyond restating that the query is a question, and does not supplement schema with extra format or usage details.
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?
Description uses a specific verb ('Find'), names the resource ('Sunleaf FAQ entries'), and states the return payload (question, answer, FAQ id for citation). This clearly distinguishes it from sibling tools like search_products or get_policy.
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 context ('best match a question') implies a FAQ lookup use case, but there is no explicit when-to-use guidance or mention of alternatives such as answer_sources. Usage must be inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_productsSearch productsARead-onlyIdempotent
Search the Sunleaf Tea Co. catalog by keywords such as a tea type, flavour, occasion or teaware item. Returns matching products with id, category, price in INR and USD, sizes and stock status. Use get_product for full details.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Keywords, for example "caffeine-free" or "green tea" | |
| category | No | Optional category filter: black tea, gift box, green tea, herbal, oolong tea, teaware, white tea | |
| max_results | No | How many results to return, 1 to 10 (default 8) | |
| in_stock_only | No | Return only products that are in stock |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds value by specifying the exact return fields (id, category, price in INR and USD, sizes, stock status), which is useful behavioral context beyond the annotations. No contradictions.
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 with no filler. The purpose and examples are front-loaded, and the alternative is stated in the second sentence. Every word 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?
The tool has an output schema, so return values are already structured. The description covers the query purpose, result contents, and the alternative for full details. With all parameters documented in the schema and annotations covering safety, nothing an agent needs to call this 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 100%, so all parameters are already documented. The description adds a few extra examples for the query parameter (tea type, flavour, occasion, teaware) but this is marginal and largely redundant with the schema's own examples. It meets the baseline but does not significantly enhance parameter understanding.
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?
The description states a specific verb ('search'), a resource ('Sunleaf Tea Co. catalog'), and gives concrete examples of query types (tea type, flavour, occasion, teaware). It also explicitly distinguishes itself from the sibling get_product by saying 'Use get_product for full details,' so an agent can tell them apart without opening schemas.
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 indicates when to use this tool (search by keywords for summary results) and when not to (when full details are needed), naming the alternative get_product. This explicit routing leaves no ambiguity about selection.
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.
5 tool updates
v0.1.0- First observed
answer_sources - First observed
get_policy - First observed
get_product - First observed
search_faqs - First observed
search_products
TDQS
Scored across 5 tools
Each tool has a clearly distinct purpose: FAQ search, product search, product detail retrieval, policy retrieval, and a combined answer tool that searches both FAQs and policies with citations. Even though search_faqs and answer_sources overlap on FAQs, answer_sources is broader and returns different output, so there's no real ambiguity.
All tool names follow a consistent verb_noun pattern in snake_case (search_faqs, search_products, get_product, get_policy, answer_sources). The pattern is predictable and uniform throughout.
With 5 tools, the server is well-scoped for a read-only customer support context covering products, FAQs, and policies. Each tool serves a necessary role, and the count is neither too thin nor excessive.
The surface fully covers the domain: product search and details, FAQ search, policy retrieval, and a combined answer tool that handles cross-domain queries. There are no obvious missing operations for the stated purpose of answering customer questions.
Maintenance
Related MCP Connectors
Connect AI to store orders, products and inventory with scoped access and human approvals.
Ask questions across Shopify, Klaviyo, GA4 and 20+ e-commerce sources in plain English.
Run your website's AI support agent: knowledge, conversations, leads and live replies.
AI support employee for any website: learns the site, answers visitors by chat and voice.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables e-commerce shop owners to query their business data using natural language through local AI models. Provides secure, privacy-focused access to sales reports, inventory management, customer analytics, and order data without sending sensitive information to external services.-
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to access and manage Shopify store data including products, orders, inventory, and analytics through the Model Context Protocol. It allows users to query store performance and customer details using natural language.-
- AlicenseAqualityDmaintenanceProvides AI assistants with real-time access to Shopify store analytics, sales data, and inventory through ShopifyQL and the Admin GraphQL API. It enables users to query store performance, customer metrics, and marketing insights using natural language.13MIT
- FlicenseNot gradedqualityFmaintenanceEnables AI assistants to query and interact with Shopify store data via the Storefront API, including products, collections, carts, and customer information.9-