@tomaspavlin/rohlik-mcp 1.0.0

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Tomas Pavlin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # Rohlik MCP Server
2
+
3
+ A Model Context Protocol (MCP) server that enables AI assistants to interact with Rohlik.cz, the Czech Republic's leading online grocery delivery service. This server provides tools for searching products, managing shopping carts, and accessing shopping lists.
4
+
5
+ > [!WARNING]
6
+ > This MCP server is made by reverse engineering Rohlik.cz API that is used by the rohlik.cz website. Use this at your own risk.
7
+
8
+ ## Usage
9
+
10
+ ### Claude Desktop Configuration
11
+
12
+ On MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
13
+
14
+ On Windows: `%APPDATA%/Claude/claude_desktop_config.json`
15
+
16
+ Add this to your Claude Desktop configuration:
17
+
18
+ ```json
19
+ {
20
+ "mcpServers": {
21
+ "rohlik": {
22
+ "command": "npx",
23
+ "args": ["-y", "@tomaspavlin/rohlik-mcp"],
24
+ "env": {
25
+ "ROHLIK_USERNAME": "your-email@example.com",
26
+ "ROHLIK_PASSWORD": "your-password"
27
+ }
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ ## Tools
34
+
35
+ - `search_products` - Search for grocery products by name with filtering options
36
+ - `add_to_cart` - Add multiple products to your shopping cart
37
+ - `get_cart_content` - View current cart contents and totals
38
+ - `remove_from_cart` - Remove items from your shopping cart
39
+ - `get_shopping_list` - Retrieve shopping lists by ID
40
+
41
+ ## Development
42
+
43
+ ### Installation
44
+
45
+ ```bash
46
+ npm install
47
+ npm run build
48
+ ```
49
+
50
+ ### Scripts
51
+
52
+ - `npm run build` - Compile TypeScript to JavaScript
53
+ - `npm start` - Launch the production server
54
+ - `npm run dev` - Start development mode with watch
55
+ - `npm run inspect` - Test with MCP Inspector
56
+
57
+ ## Testing
58
+
59
+ ### Testing with Claude Desktop
60
+
61
+ Add this to configuration:
62
+
63
+ ```json
64
+ {
65
+ "mcpServers": {
66
+ "rohlik-local": {
67
+ "command": "node",
68
+ "args": ["/path/to/rohlik-mcp/dist/index.js"],
69
+ "env": {
70
+ "ROHLIK_USERNAME": "your-email@example.com",
71
+ "ROHLIK_PASSWORD": "your-password"
72
+ }
73
+ }
74
+ }
75
+ }
76
+ ```
77
+
78
+ ### Testing with MCP Inspector
79
+
80
+ You can test the MCP server using the official MCP Inspector (https://modelcontextprotocol.io/legacy/tools/inspector):
81
+
82
+ ```bash
83
+ npm run inspect
84
+ ```
85
+
86
+ In the Inspector, set the ROHLIK_USERNAME and ROHLIK_PASSWORD envs.
87
+
88
+ ### Publishing as NPM package
89
+
90
+ 1. Update version in package.json
91
+ 2. `npm publish`
92
+
93
+ ## License
94
+
95
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
96
+
97
+ ## Acknowledgements
98
+
99
+ - https://github.com/dvejsada/HA-RohlikCZ for reverse engineering the Rohlik.cz API
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,234 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { z } from "zod";
5
+ import { RohlikAPI } from "./rohlik-api.js";
6
+ const server = new McpServer({
7
+ name: "rohlik-mcp",
8
+ version: "0.0.1",
9
+ }, {
10
+ capabilities: {
11
+ tools: {},
12
+ },
13
+ });
14
+ function getCredentials() {
15
+ const username = process.env.ROHLIK_USERNAME;
16
+ const password = process.env.ROHLIK_PASSWORD;
17
+ if (!username || !password) {
18
+ throw new Error('ROHLIK_USERNAME and ROHLIK_PASSWORD environment variables are required');
19
+ }
20
+ return { username, password };
21
+ }
22
+ function createRohlikAPI() {
23
+ const credentials = getCredentials();
24
+ return new RohlikAPI(credentials);
25
+ }
26
+ server.registerTool("search_products", {
27
+ title: "Search Products",
28
+ description: "Search for products on Rohlik.cz by name",
29
+ inputSchema: {
30
+ product_name: z.string().min(1, "Product name cannot be empty").describe("The name or search term for the product"),
31
+ limit: z.number().min(1).max(50).default(10).describe("Maximum number of products to return (1-50, default: 10)"),
32
+ favourite_only: z.boolean().default(false).describe("Whether to return only favourite products (default: false)")
33
+ }
34
+ }, async ({ product_name, limit = 10, favourite_only = false }) => {
35
+ try {
36
+ const api = createRohlikAPI();
37
+ const results = await api.searchProducts(product_name, limit, favourite_only);
38
+ const output = `Found ${results.length} products:\n\n` +
39
+ results.map(product => `• ${product.name} (${product.brand})\n Price: ${product.price}\n Amount: ${product.amount}\n ID: ${product.id}`).join('\n\n');
40
+ return {
41
+ content: [
42
+ {
43
+ type: "text",
44
+ text: output
45
+ }
46
+ ]
47
+ };
48
+ }
49
+ catch (error) {
50
+ return {
51
+ content: [
52
+ {
53
+ type: "text",
54
+ text: error instanceof Error ? error.message : String(error)
55
+ }
56
+ ],
57
+ isError: true
58
+ };
59
+ }
60
+ });
61
+ server.registerTool("add_to_cart", {
62
+ title: "Add to Cart",
63
+ description: "Add products to the shopping cart",
64
+ inputSchema: {
65
+ products: z.array(z.object({
66
+ product_id: z.number().describe("The ID of the product to add"),
67
+ quantity: z.number().min(1).describe("Quantity of the product to add")
68
+ })).min(1, "At least one product is required").describe("Array of products to add to cart")
69
+ }
70
+ }, async ({ products }) => {
71
+ try {
72
+ const api = createRohlikAPI();
73
+ const addedProducts = await api.addToCart(products);
74
+ const successCount = addedProducts.length;
75
+ const totalRequested = products.length;
76
+ const output = `Successfully added ${successCount}/${totalRequested} products to cart.\n` +
77
+ (addedProducts.length > 0 ? `Added product IDs: ${addedProducts.join(', ')}` : 'No products were added.');
78
+ return {
79
+ content: [
80
+ {
81
+ type: "text",
82
+ text: output
83
+ }
84
+ ]
85
+ };
86
+ }
87
+ catch (error) {
88
+ return {
89
+ content: [
90
+ {
91
+ type: "text",
92
+ text: error instanceof Error ? error.message : String(error)
93
+ }
94
+ ],
95
+ isError: true
96
+ };
97
+ }
98
+ });
99
+ server.registerTool("get_cart_content", {
100
+ title: "Get Cart Content",
101
+ description: "Get the current contents of the shopping cart",
102
+ inputSchema: {}
103
+ }, async () => {
104
+ try {
105
+ const api = createRohlikAPI();
106
+ const cartContent = await api.getCartContent();
107
+ if (cartContent.total_items === 0) {
108
+ return {
109
+ content: [
110
+ {
111
+ type: "text",
112
+ text: "Your cart is empty."
113
+ }
114
+ ]
115
+ };
116
+ }
117
+ const output = `Cart Summary:
118
+ • Total items: ${cartContent.total_items}
119
+ • Total price: ${cartContent.total_price} CZK
120
+ • Can order: ${cartContent.can_make_order ? 'Yes' : 'No'}
121
+
122
+ Products in cart:
123
+ ${cartContent.products.map(product => `• ${product.name} (${product.brand})\n Quantity: ${product.quantity}\n Price: ${product.price} CZK\n Category: ${product.category_name}\n Cart ID: ${product.cart_item_id}`).join('\n\n')}`;
124
+ return {
125
+ content: [
126
+ {
127
+ type: "text",
128
+ text: output
129
+ }
130
+ ]
131
+ };
132
+ }
133
+ catch (error) {
134
+ return {
135
+ content: [
136
+ {
137
+ type: "text",
138
+ text: error instanceof Error ? error.message : String(error)
139
+ }
140
+ ],
141
+ isError: true
142
+ };
143
+ }
144
+ });
145
+ server.registerTool("remove_from_cart", {
146
+ title: "Remove from Cart",
147
+ description: "Remove an item from the shopping cart",
148
+ inputSchema: {
149
+ order_field_id: z.string().min(1, "Order field ID is required").describe("The order field ID of the item to remove (cart_item_id from cart content)")
150
+ }
151
+ }, async ({ order_field_id }) => {
152
+ try {
153
+ const api = createRohlikAPI();
154
+ const success = await api.removeFromCart(order_field_id);
155
+ const output = success
156
+ ? `Successfully removed item with ID ${order_field_id} from cart.`
157
+ : `Failed to remove item with ID ${order_field_id} from cart.`;
158
+ return {
159
+ content: [
160
+ {
161
+ type: "text",
162
+ text: output
163
+ }
164
+ ]
165
+ };
166
+ }
167
+ catch (error) {
168
+ return {
169
+ content: [
170
+ {
171
+ type: "text",
172
+ text: error instanceof Error ? error.message : String(error)
173
+ }
174
+ ],
175
+ isError: true
176
+ };
177
+ }
178
+ });
179
+ server.registerTool("get_shopping_list", {
180
+ title: "Get Shopping List",
181
+ description: "Get a shopping list by ID",
182
+ inputSchema: {
183
+ shopping_list_id: z.string().min(1, "Shopping list ID is required").describe("The ID of the shopping list to retrieve")
184
+ }
185
+ }, async ({ shopping_list_id }) => {
186
+ try {
187
+ const api = createRohlikAPI();
188
+ const shoppingList = await api.getShoppingList(shopping_list_id);
189
+ if (!shoppingList.products || shoppingList.products.length === 0) {
190
+ return {
191
+ content: [
192
+ {
193
+ type: "text",
194
+ text: `Shopping list "${shoppingList.name}" is empty.`
195
+ }
196
+ ]
197
+ };
198
+ }
199
+ const output = `Shopping List: ${shoppingList.name}
200
+ Total products: ${shoppingList.products.length}
201
+
202
+ Products:
203
+ ${shoppingList.products.map((product, index) => `${index + 1}. ${product.name || 'Unknown product'}`).join('\n')}`;
204
+ return {
205
+ content: [
206
+ {
207
+ type: "text",
208
+ text: output
209
+ }
210
+ ]
211
+ };
212
+ }
213
+ catch (error) {
214
+ return {
215
+ content: [
216
+ {
217
+ type: "text",
218
+ text: error instanceof Error ? error.message : String(error)
219
+ }
220
+ ],
221
+ isError: true
222
+ };
223
+ }
224
+ });
225
+ async function main() {
226
+ const transport = new StdioServerTransport();
227
+ await server.connect(transport);
228
+ console.error("Rohlik MCP server running on stdio");
229
+ }
230
+ main().catch((error) => {
231
+ console.error("Server error:", error);
232
+ process.exit(1);
233
+ });
234
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { Product, SearchResult, CartContent, RohlikCredentials } from './types.js';
2
+ export declare class RohlikAPIError extends Error {
3
+ status?: number | undefined;
4
+ constructor(message: string, status?: number | undefined);
5
+ }
6
+ export declare class RohlikAPI {
7
+ private credentials;
8
+ private userId?;
9
+ private addressId?;
10
+ private sessionCookies;
11
+ constructor(credentials: RohlikCredentials);
12
+ private makeRequest;
13
+ login(): Promise<void>;
14
+ logout(): Promise<void>;
15
+ searchProducts(productName: string, limit?: number, favouriteOnly?: boolean): Promise<SearchResult[]>;
16
+ addToCart(products: Product[]): Promise<number[]>;
17
+ getCartContent(): Promise<CartContent>;
18
+ removeFromCart(orderFieldId: string): Promise<boolean>;
19
+ getShoppingList(shoppingListId: string): Promise<{
20
+ name: string;
21
+ products: any[];
22
+ }>;
23
+ }
24
+ //# sourceMappingURL=rohlik-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rohlik-api.d.ts","sourceRoot":"","sources":["../src/rohlik-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAqB,MAAM,YAAY,CAAC;AAItG,qBAAa,cAAe,SAAQ,KAAK;IACH,MAAM,CAAC,EAAE,MAAM;gBAAvC,OAAO,EAAE,MAAM,EAAS,MAAM,CAAC,EAAE,MAAM,YAAA;CAIpD;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAc;gBAExB,WAAW,EAAE,iBAAiB;YAI5B,WAAW;IA6BnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAOvB,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,MAAW,EAClB,aAAa,GAAE,OAAe,GAC7B,OAAO,CAAC,YAAY,EAAE,CAAC;IA0CpB,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiCjD,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IA0BtC,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBtD,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;CAe1F"}
@@ -0,0 +1,183 @@
1
+ import fetch from 'node-fetch';
2
+ const BASE_URL = 'https://www.rohlik.cz';
3
+ export class RohlikAPIError extends Error {
4
+ status;
5
+ constructor(message, status) {
6
+ super(message);
7
+ this.status = status;
8
+ this.name = 'RohlikAPIError';
9
+ }
10
+ }
11
+ export class RohlikAPI {
12
+ credentials;
13
+ userId;
14
+ addressId;
15
+ sessionCookies = '';
16
+ constructor(credentials) {
17
+ this.credentials = credentials;
18
+ }
19
+ async makeRequest(url, options = {}) {
20
+ const headers = {
21
+ 'Content-Type': 'application/json',
22
+ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
23
+ ...(this.sessionCookies && { Cookie: this.sessionCookies }),
24
+ ...(options.headers || {})
25
+ };
26
+ const response = await fetch(`${BASE_URL}${url}`, {
27
+ ...options,
28
+ headers
29
+ });
30
+ // Store cookies for session management
31
+ const setCookieHeader = response.headers.get('set-cookie');
32
+ if (setCookieHeader) {
33
+ this.sessionCookies = setCookieHeader;
34
+ }
35
+ if (!response.ok) {
36
+ throw new RohlikAPIError(`HTTP ${response.status}: ${response.statusText}`, response.status);
37
+ }
38
+ return await response.json();
39
+ }
40
+ async login() {
41
+ const loginData = {
42
+ email: this.credentials.username,
43
+ password: this.credentials.password,
44
+ name: ''
45
+ };
46
+ const response = await this.makeRequest('/services/frontend-service/login', {
47
+ method: 'POST',
48
+ body: JSON.stringify(loginData)
49
+ });
50
+ if (response.status !== 200) {
51
+ if (response.status === 401) {
52
+ throw new RohlikAPIError('Invalid credentials', 401);
53
+ }
54
+ throw new RohlikAPIError(`Login failed: ${response.messages?.[0]?.content || 'Unknown error'}`);
55
+ }
56
+ this.userId = response.data?.user?.id;
57
+ this.addressId = response.data?.address?.id;
58
+ }
59
+ async logout() {
60
+ await this.makeRequest('/services/frontend-service/logout', {
61
+ method: 'POST'
62
+ });
63
+ this.sessionCookies = '';
64
+ }
65
+ async searchProducts(productName, limit = 10, favouriteOnly = false) {
66
+ await this.login();
67
+ try {
68
+ const searchParams = new URLSearchParams({
69
+ search: productName,
70
+ offset: '0',
71
+ limit: String(limit + 5),
72
+ companyId: '1',
73
+ filterData: JSON.stringify({ filters: [] }),
74
+ canCorrect: 'true'
75
+ });
76
+ const response = await this.makeRequest(`/services/frontend-service/search-metadata?${searchParams}`);
77
+ let products = response.data?.productList || [];
78
+ // Remove sponsored content
79
+ products = products.filter((p) => !p.badge?.some((badge) => badge.slug === 'promoted'));
80
+ // Filter favourites if requested
81
+ if (favouriteOnly) {
82
+ products = products.filter((p) => p.favourite);
83
+ }
84
+ // Limit results
85
+ products = products.slice(0, limit);
86
+ return products.map((p) => ({
87
+ id: p.productId,
88
+ name: p.productName,
89
+ price: `${p.price.full} ${p.price.currency}`,
90
+ brand: p.brand,
91
+ amount: p.textualAmount
92
+ }));
93
+ }
94
+ finally {
95
+ await this.logout();
96
+ }
97
+ }
98
+ async addToCart(products) {
99
+ await this.login();
100
+ try {
101
+ const addedProducts = [];
102
+ for (const product of products) {
103
+ try {
104
+ const payload = {
105
+ actionId: null,
106
+ productId: product.product_id,
107
+ quantity: product.quantity,
108
+ recipeId: null,
109
+ source: 'true:Shopping Lists'
110
+ };
111
+ await this.makeRequest('/services/frontend-service/v2/cart', {
112
+ method: 'POST',
113
+ body: JSON.stringify(payload)
114
+ });
115
+ addedProducts.push(product.product_id);
116
+ }
117
+ catch (error) {
118
+ console.error(`Failed to add product ${product.product_id}:`, error);
119
+ }
120
+ }
121
+ return addedProducts;
122
+ }
123
+ finally {
124
+ await this.logout();
125
+ }
126
+ }
127
+ async getCartContent() {
128
+ await this.login();
129
+ try {
130
+ const response = await this.makeRequest('/services/frontend-service/v2/cart');
131
+ const data = response.data || {};
132
+ return {
133
+ total_price: data.totalPrice || 0,
134
+ total_items: Object.keys(data.items || {}).length,
135
+ can_make_order: data.submitConditionPassed || false,
136
+ products: Object.entries(data.items || {}).map(([productId, productData]) => ({
137
+ id: productId,
138
+ cart_item_id: productData.orderFieldId || '',
139
+ name: productData.productName || '',
140
+ quantity: productData.quantity || 0,
141
+ price: productData.price || 0,
142
+ category_name: productData.primaryCategoryName || '',
143
+ brand: productData.brand || ''
144
+ }))
145
+ };
146
+ }
147
+ finally {
148
+ await this.logout();
149
+ }
150
+ }
151
+ async removeFromCart(orderFieldId) {
152
+ await this.login();
153
+ try {
154
+ await this.makeRequest(`/services/frontend-service/v2/cart?orderFieldId=${orderFieldId}`, {
155
+ method: 'DELETE'
156
+ });
157
+ return true;
158
+ }
159
+ catch (error) {
160
+ console.error(`Failed to remove item ${orderFieldId}:`, error);
161
+ return false;
162
+ }
163
+ finally {
164
+ await this.logout();
165
+ }
166
+ }
167
+ async getShoppingList(shoppingListId) {
168
+ await this.login();
169
+ try {
170
+ const response = await this.makeRequest(`/api/v1/shopping-lists/id/${shoppingListId}`);
171
+ // Handle both wrapped and direct responses
172
+ const listData = response.data || response;
173
+ return {
174
+ name: listData?.name || 'Unknown List',
175
+ products: listData?.products || []
176
+ };
177
+ }
178
+ finally {
179
+ await this.logout();
180
+ }
181
+ }
182
+ }
183
+ //# sourceMappingURL=rohlik-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rohlik-api.js","sourceRoot":"","sources":["../src/rohlik-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ import { z } from 'zod';
2
+ export declare const ProductSchema: z.ZodObject<{
3
+ product_id: z.ZodNumber;
4
+ quantity: z.ZodNumber;
5
+ }, "strip", z.ZodTypeAny, {
6
+ product_id: number;
7
+ quantity: number;
8
+ }, {
9
+ product_id: number;
10
+ quantity: number;
11
+ }>;
12
+ export declare const SearchResultSchema: z.ZodObject<{
13
+ id: z.ZodNumber;
14
+ name: z.ZodString;
15
+ price: z.ZodString;
16
+ brand: z.ZodString;
17
+ amount: z.ZodString;
18
+ }, "strip", z.ZodTypeAny, {
19
+ id: number;
20
+ name: string;
21
+ price: string;
22
+ brand: string;
23
+ amount: string;
24
+ }, {
25
+ id: number;
26
+ name: string;
27
+ price: string;
28
+ brand: string;
29
+ amount: string;
30
+ }>;
31
+ export declare const CartItemSchema: z.ZodObject<{
32
+ id: z.ZodString;
33
+ cart_item_id: z.ZodString;
34
+ name: z.ZodString;
35
+ quantity: z.ZodNumber;
36
+ price: z.ZodNumber;
37
+ category_name: z.ZodString;
38
+ brand: z.ZodString;
39
+ }, "strip", z.ZodTypeAny, {
40
+ quantity: number;
41
+ id: string;
42
+ name: string;
43
+ price: number;
44
+ brand: string;
45
+ cart_item_id: string;
46
+ category_name: string;
47
+ }, {
48
+ quantity: number;
49
+ id: string;
50
+ name: string;
51
+ price: number;
52
+ brand: string;
53
+ cart_item_id: string;
54
+ category_name: string;
55
+ }>;
56
+ export declare const CartContentSchema: z.ZodObject<{
57
+ total_price: z.ZodNumber;
58
+ total_items: z.ZodNumber;
59
+ can_make_order: z.ZodBoolean;
60
+ products: z.ZodArray<z.ZodObject<{
61
+ id: z.ZodString;
62
+ cart_item_id: z.ZodString;
63
+ name: z.ZodString;
64
+ quantity: z.ZodNumber;
65
+ price: z.ZodNumber;
66
+ category_name: z.ZodString;
67
+ brand: z.ZodString;
68
+ }, "strip", z.ZodTypeAny, {
69
+ quantity: number;
70
+ id: string;
71
+ name: string;
72
+ price: number;
73
+ brand: string;
74
+ cart_item_id: string;
75
+ category_name: string;
76
+ }, {
77
+ quantity: number;
78
+ id: string;
79
+ name: string;
80
+ price: number;
81
+ brand: string;
82
+ cart_item_id: string;
83
+ category_name: string;
84
+ }>, "many">;
85
+ }, "strip", z.ZodTypeAny, {
86
+ total_price: number;
87
+ total_items: number;
88
+ can_make_order: boolean;
89
+ products: {
90
+ quantity: number;
91
+ id: string;
92
+ name: string;
93
+ price: number;
94
+ brand: string;
95
+ cart_item_id: string;
96
+ category_name: string;
97
+ }[];
98
+ }, {
99
+ total_price: number;
100
+ total_items: number;
101
+ can_make_order: boolean;
102
+ products: {
103
+ quantity: number;
104
+ id: string;
105
+ name: string;
106
+ price: number;
107
+ brand: string;
108
+ cart_item_id: string;
109
+ category_name: string;
110
+ }[];
111
+ }>;
112
+ export type Product = z.infer<typeof ProductSchema>;
113
+ export type SearchResult = z.infer<typeof SearchResultSchema>;
114
+ export type CartItem = z.infer<typeof CartItemSchema>;
115
+ export type CartContent = z.infer<typeof CartContentSchema>;
116
+ export interface RohlikCredentials {
117
+ username: string;
118
+ password: string;
119
+ }
120
+ export interface RohlikAPIResponse<T = any> {
121
+ status: number;
122
+ data?: T;
123
+ messages?: Array<{
124
+ content: string;
125
+ }>;
126
+ }
127
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,aAAa;;;;;;;;;EAGxB,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;EAM7B,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;EAQzB,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK5B,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AACpD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,GAAG;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvC"}
package/dist/types.js ADDED
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod';
2
+ export const ProductSchema = z.object({
3
+ product_id: z.number(),
4
+ quantity: z.number().min(1)
5
+ });
6
+ export const SearchResultSchema = z.object({
7
+ id: z.number(),
8
+ name: z.string(),
9
+ price: z.string(),
10
+ brand: z.string(),
11
+ amount: z.string()
12
+ });
13
+ export const CartItemSchema = z.object({
14
+ id: z.string(),
15
+ cart_item_id: z.string(),
16
+ name: z.string(),
17
+ quantity: z.number(),
18
+ price: z.number(),
19
+ category_name: z.string(),
20
+ brand: z.string()
21
+ });
22
+ export const CartContentSchema = z.object({
23
+ total_price: z.number(),
24
+ total_items: z.number(),
25
+ can_make_order: z.boolean(),
26
+ products: z.array(CartItemSchema)
27
+ });
28
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC5B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;CACnB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE;IAC3B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC;CAClC,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@tomaspavlin/rohlik-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for controlling Rohlik.cz grocery shopping website",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "build": "tsc && chmod +x dist/*.js",
9
+ "start": "node dist/index.js",
10
+ "inspect": "npm run build && npx @modelcontextprotocol/inspector -e ROHLIK_USERNAME=your-email@example.com -e ROHLIK_PASSWORD=your-password node dist/index.js",
11
+ "watch": "tsc --watch",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "keywords": [
15
+ "mcp",
16
+ "rohlik",
17
+ "grocery",
18
+ "shopping",
19
+ "api"
20
+ ],
21
+ "author": "Tomas Pavlin",
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/tomaspavlin/rohlik-mcp.git"
26
+ },
27
+ "homepage": "https://github.com/tomaspavlin/rohlik-mcp#readme",
28
+ "bugs": {
29
+ "url": "https://github.com/tomaspavlin/rohlik-mcp/issues"
30
+ },
31
+ "files": [
32
+ "dist/**/*",
33
+ "README.md",
34
+ "LICENSE"
35
+ ],
36
+ "dependencies": {
37
+ "@modelcontextprotocol/sdk": "^1.0.0",
38
+ "node-fetch": "^3.3.2",
39
+ "zod": "^3.22.4"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^20.10.0",
43
+ "typescript": "^5.3.0"
44
+ },
45
+ "bin": {
46
+ "rohlik-mcp": "dist/index.js"
47
+ }
48
+ }