@sellhapi/mcp 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ /**
3
+ * Wireframe schema resource.
4
+ *
5
+ * Documents the exact shape and conventions for wireframe HTML submitted via
6
+ * apply_wireframe. The AI client generates mid-fidelity wireframes per page,
7
+ * presents each one to the user for review, then submits the approved set.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.WIREFRAME_SCHEMA = void 0;
11
+ exports.WIREFRAME_SCHEMA = `
12
+ # SellHapi Wireframe Schema
13
+
14
+ Wireframes are mid-fidelity HTML page layouts — one per storefront page.
15
+ They are the USER'S checkpoint before code is written: present each page
16
+ wireframe in the conversation, collect feedback, revise if needed, then
17
+ call apply_wireframe only after the user approves the full set.
18
+
19
+ ---
20
+
21
+ ## Data shape
22
+
23
+ \`\`\`
24
+ { [pageSlug: string]: htmlString }
25
+ \`\`\`
26
+
27
+ - Each key is a page slug that MUST match one of the slugs in designDirection.pages
28
+ - Each value is a valid HTML string for that page's mid-fidelity wireframe
29
+ - All pages from designDirection.pages should be included (missing pages means no wireframe guidance for code generation on that page)
30
+
31
+ ---
32
+
33
+ ## What a wireframe IS
34
+
35
+ Mid-fidelity structural HTML. It communicates:
36
+ - Which sections appear on the page and in what order
37
+ - What content each section contains (headings, CTAs, placeholder data)
38
+ - Navigation structure (links, cart icon, CTA button)
39
+ - Footer structure (columns, links)
40
+ - Which runtime hook each section will use
41
+
42
+ It does NOT include:
43
+ - Real CSS (use only inline style for basic layout structure if needed)
44
+ - JavaScript or React
45
+ - Actual product/service data (use descriptive placeholders)
46
+ - Final colour values or fonts (those come from designDirection.visualDirection)
47
+
48
+ ---
49
+
50
+ ## Structure rules
51
+
52
+ ### Navigation — MANDATORY on every page
53
+ \`\`\`html
54
+ <nav>
55
+ <div class="nav-logo">[Business Name]</div>
56
+ <ul class="nav-links">
57
+ <li><a href="#/home">Home</a></li>
58
+ <li><a href="#/shop">Shop</a></li>
59
+ <!-- one <li> per page in designDirection.pages -->
60
+ </ul>
61
+ <!-- If physical_products or digital_products in capabilityIds: -->
62
+ <button class="nav-cart">Cart (0)</button>
63
+ <button class="nav-cta">[Primary CTA]</button>
64
+ </nav>
65
+ \`\`\`
66
+
67
+ - Navigation HTML must be **identical across all pages** — copy verbatim after the first page
68
+ - Highlight the current page's link as active (add class="active" to that <li>)
69
+ - Cart icon only when capability includes physical_products or digital_products
70
+
71
+ ### Footer — MANDATORY on every page
72
+ \`\`\`html
73
+ <footer>
74
+ <div class="footer-col">
75
+ <div class="footer-logo">[Business Name]</div>
76
+ <p>[tagline]</p>
77
+ </div>
78
+ <div class="footer-col">
79
+ <h4>NAVIGATE</h4>
80
+ <ul><!-- one <li> per page --></ul>
81
+ </div>
82
+ <div class="footer-col">
83
+ <h4>RESOURCES</h4>
84
+ <ul><!-- relevant links for this business type --></ul>
85
+ </div>
86
+ <div class="footer-col">
87
+ <h4>CONNECT</h4>
88
+ <!-- social platform links -->
89
+ </div>
90
+ <div class="footer-bottom">© [year] [Business Name]. All rights reserved.</div>
91
+ </footer>
92
+ \`\`\`
93
+
94
+ - Footer HTML must be **identical across all pages** — copy verbatim after the first page
95
+
96
+ ### Sections
97
+ Each section gets a wrapper with a comment and data-hook attribute:
98
+
99
+ \`\`\`html
100
+ <!-- Hero Section -->
101
+ <section data-section="hero" data-hook="none">
102
+ <h1>[Headline — use the business tagline]</h1>
103
+ <p>[Supporting copy]</p>
104
+ <button>[Primary CTA]</button>
105
+ <div class="hero-image">[Hero image placeholder]</div>
106
+ </section>
107
+
108
+ <!-- Product Grid Section -->
109
+ <section data-section="product-grid" data-hook="useProducts">
110
+ <h2>Our Products</h2>
111
+ <div class="product-grid">
112
+ <div class="product-card">
113
+ <div class="product-image">[Product image]</div>
114
+ <h3>[Product name]</h3>
115
+ <p>[Price in ₦]</p>
116
+ <button>Add to Cart</button>
117
+ </div>
118
+ <!-- repeat 2 more placeholder cards -->
119
+ </div>
120
+ </section>
121
+
122
+ <!-- Testimonials Section -->
123
+ <section data-section="testimonials" data-hook="useContentTestimonials">
124
+ <h2>What Customers Say</h2>
125
+ <div class="testimonials-grid">
126
+ <blockquote>[Testimonial 1]</blockquote>
127
+ <blockquote>[Testimonial 2]</blockquote>
128
+ <blockquote>[Testimonial 3]</blockquote>
129
+ </div>
130
+ </section>
131
+ \`\`\`
132
+
133
+ ---
134
+
135
+ ## data-hook values by capability
136
+
137
+ Use these exact hook names in data-hook attributes so code generation
138
+ matches the correct runtime hook:
139
+
140
+ | Section type | data-hook |
141
+ |-------------------------------|---------------------------------|
142
+ | Product listing / grid | useProducts |
143
+ | Product collections | useProductCollections |
144
+ | Single collection | useCollection |
145
+ | Category sections | useSections |
146
+ | Service listings | useServiceListings |
147
+ | Appointment booking | useBookAppointment |
148
+ | Available dates | useAvailableDates |
149
+ | Events listing | useEvents |
150
+ | Donation campaigns | useDonationCampaigns |
151
+ | Membership tiers | useMemberships |
152
+ | Content images | useContentImages |
153
+ | Testimonials | useContentTestimonials |
154
+ | FAQs | useContentFaqs |
155
+ | Team members | useContentTeam |
156
+ | Stats / social proof | useContentStats |
157
+ | Feature highlights | useContentFeatures |
158
+ | Contact / enquiry form | useSubmitForm |
159
+ | Listings (classifieds/jobs) | useListings |
160
+ | Non-data sections (hero, about, footer, nav) | none |
161
+
162
+ ---
163
+
164
+ ## Presenting wireframes to the user
165
+
166
+ Before calling apply_wireframe, show each page to the user like this:
167
+
168
+ \`\`\`
169
+ 📄 HOME PAGE
170
+ ━━━━━━━━━━━━
171
+ [NAV] Logo | Home · Shop · About · Contact [Cart] [Shop Now]
172
+
173
+ [HERO]
174
+ "Authentic Nigerian fashion for the bold"
175
+ Subheading + CTA button
176
+ Full-width hero image
177
+
178
+ [FEATURED PRODUCTS] (useProducts)
179
+ 3-column product grid — 6 products
180
+ Each card: image, name, price, Add to Cart
181
+
182
+ [COLLECTIONS] (useProductCollections)
183
+ 4 collection tiles with cover images
184
+
185
+ [TESTIMONIALS] (useContentTestimonials)
186
+ 3 customer quotes in a row
187
+
188
+ [NEWSLETTER]
189
+ Email capture form
190
+
191
+ [FOOTER] 4-column footer
192
+ ━━━━━━━━━━━━
193
+
194
+ Does this structure look right? Any sections to add, remove, or reorder?
195
+ \`\`\`
196
+
197
+ Wait for explicit user approval before proceeding to apply_wireframe.
198
+ If the user requests changes, update the affected page(s) and show again.
199
+
200
+ ---
201
+
202
+ ## Submission
203
+
204
+ Once ALL pages are approved by the user:
205
+
206
+ \`\`\`
207
+ apply_wireframe(projectId, {
208
+ "home": "<nav>...</nav><main>...</main><footer>...</footer>",
209
+ "shop": "<nav>...</nav><main>...</main><footer>...</footer>",
210
+ "about": "<nav>...</nav><main>...</main><footer>...</footer>",
211
+ "contact": "<nav>...</nav><main>...</main><footer>...</footer>"
212
+ })
213
+ \`\`\`
214
+
215
+ Returns: \`{ pageCount: 4, slugs: ["home", "shop", "about", "contact"] }\`
216
+
217
+ After this, proceed to generate React code using the wireframe as your
218
+ structural reference. The wireframe defines WHAT to build — runtime-hooks
219
+ and build-rules define HOW to build it in React.
220
+ `;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shared MCP server factory.
3
+ *
4
+ * Both the stdio CLI entry point and the hosted HTTP entry point use this
5
+ * to create an identically-configured McpServer instance.
6
+ */
7
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
+ export declare function createMcpServer(): McpServer;
package/dist/server.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /**
3
+ * Shared MCP server factory.
4
+ *
5
+ * Both the stdio CLI entry point and the hosted HTTP entry point use this
6
+ * to create an identically-configured McpServer instance.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createMcpServer = createMcpServer;
10
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
11
+ const studio_js_1 = require("./tools/studio.js");
12
+ const commerce_js_1 = require("./tools/commerce.js");
13
+ const content_js_1 = require("./tools/content.js");
14
+ const intelligence_js_1 = require("./tools/intelligence.js");
15
+ const index_js_1 = require("./resources/index.js");
16
+ function createMcpServer() {
17
+ const server = new mcp_js_1.McpServer({
18
+ name: "sellhapi",
19
+ version: "0.1.0",
20
+ });
21
+ (0, studio_js_1.registerStudioTools)(server);
22
+ (0, commerce_js_1.registerCommerceTools)(server);
23
+ (0, content_js_1.registerContentTools)(server);
24
+ (0, intelligence_js_1.registerIntelligenceTools)(server);
25
+ (0, index_js_1.registerResources)(server);
26
+ return server;
27
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Commerce tools — read-only access to products, services, events, memberships, donations, appointments.
3
+ *
4
+ * All URLs point to /api/mcp/* (API key auth). Write endpoints are not yet
5
+ * available on the MCP route layer — create tools will be added when backend
6
+ * write proxies are shipped.
7
+ */
8
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
+ export declare function registerCommerceTools(server: McpServer): void;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ /**
3
+ * Commerce tools — read-only access to products, services, events, memberships, donations, appointments.
4
+ *
5
+ * All URLs point to /api/mcp/* (API key auth). Write endpoints are not yet
6
+ * available on the MCP route layer — create tools will be added when backend
7
+ * write proxies are shipped.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.registerCommerceTools = registerCommerceTools;
11
+ const client_js_1 = require("../client.js");
12
+ const util_js_1 = require("../util.js");
13
+ function registerCommerceTools(server) {
14
+ // ── Products ───────────────────────────────────────────────────────────────
15
+ server.registerTool("list_products", {
16
+ title: "List Products",
17
+ description: "List all physical products for this vendor.",
18
+ annotations: { readOnlyHint: true },
19
+ }, async () => (0, util_js_1.safeCall)(async () => {
20
+ const data = await (0, client_js_1.get)("/api/mcp/products");
21
+ return JSON.stringify(data.products, null, 2);
22
+ }));
23
+ // ── Digital Products ───────────────────────────────────────────────────────
24
+ server.registerTool("list_digital_products", {
25
+ title: "List Digital Products",
26
+ description: "List all digital products (ebooks, courses, downloads) for this vendor.",
27
+ annotations: { readOnlyHint: true },
28
+ }, async () => (0, util_js_1.safeCall)(async () => {
29
+ const data = await (0, client_js_1.get)("/api/mcp/digital-products");
30
+ return JSON.stringify(data.products, null, 2);
31
+ }));
32
+ // ── Service Listings ───────────────────────────────────────────────────────
33
+ server.registerTool("list_service_listings", {
34
+ title: "List Service Listings",
35
+ description: "List all service listings for this vendor.",
36
+ annotations: { readOnlyHint: true },
37
+ }, async () => (0, util_js_1.safeCall)(async () => {
38
+ const data = await (0, client_js_1.get)("/api/mcp/service-listings");
39
+ return JSON.stringify(data.listings, null, 2);
40
+ }));
41
+ // ── Events ─────────────────────────────────────────────────────────────────
42
+ server.registerTool("list_events", {
43
+ title: "List Events",
44
+ description: "List all events for this vendor, including ticket types.",
45
+ annotations: { readOnlyHint: true },
46
+ }, async () => (0, util_js_1.safeCall)(async () => {
47
+ const data = await (0, client_js_1.get)("/api/mcp/events");
48
+ return JSON.stringify(data.events, null, 2);
49
+ }));
50
+ // ── Membership Tiers ───────────────────────────────────────────────────────
51
+ server.registerTool("list_membership_tiers", {
52
+ title: "List Membership Tiers",
53
+ description: "List all membership tiers for this vendor.",
54
+ annotations: { readOnlyHint: true },
55
+ }, async () => (0, util_js_1.safeCall)(async () => {
56
+ const data = await (0, client_js_1.get)("/api/mcp/memberships");
57
+ return JSON.stringify(data.tiers, null, 2);
58
+ }));
59
+ // ── Donation Campaigns ─────────────────────────────────────────────────────
60
+ server.registerTool("list_donation_campaigns", {
61
+ title: "List Donation Campaigns",
62
+ description: "List all donation campaigns for this vendor.",
63
+ annotations: { readOnlyHint: true },
64
+ }, async () => (0, util_js_1.safeCall)(async () => {
65
+ const data = await (0, client_js_1.get)("/api/mcp/donations/campaigns");
66
+ return JSON.stringify(data.campaigns, null, 2);
67
+ }));
68
+ // ── Appointments ───────────────────────────────────────────────────────────
69
+ server.registerTool("list_appointment_services", {
70
+ title: "List Appointment Services",
71
+ description: "List all bookable appointment services for this vendor.",
72
+ annotations: { readOnlyHint: true },
73
+ }, async () => (0, util_js_1.safeCall)(async () => {
74
+ const data = await (0, client_js_1.get)("/api/mcp/appointments/services");
75
+ return JSON.stringify(data.services, null, 2);
76
+ }));
77
+ // ── Capabilities ───────────────────────────────────────────────────────────
78
+ server.registerTool("list_capabilities", {
79
+ title: "List Capabilities",
80
+ description: "List all available capabilities and which ones are active for this vendor. Capabilities include: physical_products, digital_products, services, appointments, events, donations, memberships, content, listings, customer_accounts.",
81
+ annotations: { readOnlyHint: true },
82
+ }, async () => (0, util_js_1.safeCall)(async () => {
83
+ const data = await (0, client_js_1.get)("/api/mcp/capabilities");
84
+ return JSON.stringify(data.capabilities, null, 2);
85
+ }));
86
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Content/CMS tools — read-only access to content items, forms, articles, collections.
3
+ *
4
+ * All URLs point to /api/mcp/* (API key auth). Write endpoints are not yet
5
+ * available on the MCP route layer.
6
+ */
7
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
+ export declare function registerContentTools(server: McpServer): void;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ /**
3
+ * Content/CMS tools — read-only access to content items, forms, articles, collections.
4
+ *
5
+ * All URLs point to /api/mcp/* (API key auth). Write endpoints are not yet
6
+ * available on the MCP route layer.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.registerContentTools = registerContentTools;
10
+ const client_js_1 = require("../client.js");
11
+ const util_js_1 = require("../util.js");
12
+ function registerContentTools(server) {
13
+ // ── Content Items ──────────────────────────────────────────────────────────
14
+ server.registerTool("list_content", {
15
+ title: "List Content",
16
+ description: "List all CMS content items (images, videos, testimonials, FAQs, etc.) for this vendor.",
17
+ annotations: { readOnlyHint: true },
18
+ }, async () => (0, util_js_1.safeCall)(async () => {
19
+ const data = await (0, client_js_1.get)("/api/mcp/content/items");
20
+ return JSON.stringify(data.items, null, 2);
21
+ }));
22
+ // ── Forms ──────────────────────────────────────────────────────────────────
23
+ server.registerTool("list_forms", {
24
+ title: "List Forms",
25
+ description: "List all forms (contact, order, survey, etc.) for this vendor.",
26
+ annotations: { readOnlyHint: true },
27
+ }, async () => (0, util_js_1.safeCall)(async () => {
28
+ const data = await (0, client_js_1.get)("/api/mcp/content/forms");
29
+ return JSON.stringify(data.forms, null, 2);
30
+ }));
31
+ // ── Collections ────────────────────────────────────────────────────────────
32
+ server.registerTool("list_collections", {
33
+ title: "List Collections",
34
+ description: "List all product collections for this vendor.",
35
+ annotations: { readOnlyHint: true },
36
+ }, async () => (0, util_js_1.safeCall)(async () => {
37
+ const data = await (0, client_js_1.get)("/api/mcp/collections");
38
+ return JSON.stringify(data.collections, null, 2);
39
+ }));
40
+ // ── Articles ───────────────────────────────────────────────────────────────
41
+ server.registerTool("list_articles", {
42
+ title: "List Articles",
43
+ description: "List all CMS articles/blog posts for this vendor.",
44
+ annotations: { readOnlyHint: true },
45
+ }, async () => (0, util_js_1.safeCall)(async () => {
46
+ const data = await (0, client_js_1.get)("/api/mcp/content/articles");
47
+ return JSON.stringify(data.articles, null, 2);
48
+ }));
49
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Read-only intelligence tools — orders, wallet balance.
3
+ */
4
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ export declare function registerIntelligenceTools(server: McpServer): void;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ /**
3
+ * Read-only intelligence tools — orders, wallet balance.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerIntelligenceTools = registerIntelligenceTools;
7
+ const v4_1 = require("zod/v4");
8
+ const client_js_1 = require("../client.js");
9
+ const util_js_1 = require("../util.js");
10
+ function registerIntelligenceTools(server) {
11
+ // ── Orders ─────────────────────────────────────────────────────────────────
12
+ server.registerTool("list_orders", {
13
+ title: "List Orders",
14
+ description: "List recent orders for this vendor. Returns order details, status, customer info, and products.",
15
+ inputSchema: {
16
+ status: v4_1.z.string().optional().describe("Filter by status: pending, confirmed, shipped, delivered, cancelled"),
17
+ limit: v4_1.z.number().optional().describe("Max orders to return (default 20, max 100)"),
18
+ },
19
+ annotations: { readOnlyHint: true },
20
+ }, async ({ status, limit }) => (0, util_js_1.safeCall)(async () => {
21
+ const params = new URLSearchParams();
22
+ if (status)
23
+ params.set("status", status);
24
+ if (limit)
25
+ params.set("limit", String(limit));
26
+ const qs = params.toString();
27
+ const data = await (0, client_js_1.get)(`/api/mcp/orders${qs ? `?${qs}` : ""}`);
28
+ return JSON.stringify(data.orders, null, 2);
29
+ }));
30
+ // ── Wallet balance ─────────────────────────────────────────────────────────
31
+ server.registerTool("get_wallet_balance", {
32
+ title: "Get Wallet Balance",
33
+ description: "Get the vendor's current wallet balance (available funds and AI credits).",
34
+ annotations: { readOnlyHint: true },
35
+ }, async () => (0, util_js_1.safeCall)(async () => {
36
+ const data = await (0, client_js_1.get)("/api/mcp/wallet");
37
+ return JSON.stringify(data, null, 2);
38
+ }));
39
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Studio tools — website lifecycle management.
3
+ */
4
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ export declare function registerStudioTools(server: McpServer): void;