yazio-mcp 0.0.3 → 0.0.6

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/README.md CHANGED
@@ -77,7 +77,7 @@ Easily log meals you forgot to track in the Yazio app directly from Claude or Cu
77
77
  ## Test Connection
78
78
 
79
79
  ```bash
80
- YAZIO_USERNAME=your_email YAZIO_PASSWORD=your_password npx yazio-mcp
80
+ YAZIO_USERNAME='your_email' YAZIO_PASSWORD='your_password' npx yazio-mcp
81
81
  ```
82
82
 
83
83
  ## ⚠️ Important Disclaimers
@@ -92,6 +92,14 @@ YAZIO_USERNAME=your_email YAZIO_PASSWORD=your_password npx yazio-mcp
92
92
  - Valid Yazio account
93
93
  - MCP-compatible client (Claude Desktop, Cursor, etc.)
94
94
 
95
+ # Development
96
+ 1. Download the repository
97
+ 2. Point to local copy in your mcp config
98
+ 3. Debugging:
99
+
100
+ ```
101
+ YAZIO_USERNAME=X YAZIO_PASSWORD=X npx -y @modelcontextprotocol/inspector npx <local-path>/yazio-mcp
102
+ ```
95
103
  ---
96
104
 
97
105
  ## 📄 License
package/dist/index.js CHANGED
@@ -1,23 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js';
5
4
  import { Yazio } from 'yazio';
6
- import { zodToJsonSchema } from 'zod-to-json-schema';
7
- import { GetFoodEntriesInputSchema, GetDailySummaryInputSchema, GetUserInfoInputSchema, GetUserWeightInputSchema, GetWaterIntakeInputSchema, SearchProductsInputSchema, GetProductInputSchema, GetUserExercisesInputSchema, GetUserSettingsInputSchema, GetUserSuggestedProductsInputSchema, AddConsumedItemInputSchema, RemoveConsumedItemInputSchema, GetDietaryPreferencesInputSchema, GetUserGoalsInputSchema } from './schemas.js';
5
+ import { v4 as uuidv4 } from "uuid";
6
+ import { GetFoodEntriesInputSchema, GetDailySummaryInputSchema, GetUserInfoInputSchema, GetUserWeightInputSchema, GetWaterIntakeInputSchema, SearchProductsInputSchema, GetProductInputSchema, GetUserExercisesInputSchema, GetUserSettingsInputSchema, GetUserSuggestedProductsInputSchema, AddConsumedItemInputSchema, RemoveConsumedItemInputSchema, GetDietaryPreferencesInputSchema, GetUserGoalsInputSchema, } from './schemas.js';
8
7
  class YazioMcpServer {
9
8
  server;
10
9
  yazioClient = null;
11
10
  constructor() {
12
- this.server = new Server({
11
+ this.server = new McpServer({
13
12
  name: 'yazio-mcp',
14
- version: '0.0.2',
15
- }, {
16
- capabilities: {
17
- tools: {},
18
- },
13
+ version: '0.0.6',
19
14
  });
20
15
  this.setupToolHandlers();
16
+ this.setupPromptHandlers();
21
17
  this.setupErrorHandling();
22
18
  this.initializeClient();
23
19
  }
@@ -47,187 +43,241 @@ class YazioMcpServer {
47
43
  }
48
44
  }
49
45
  setupErrorHandling() {
50
- this.server.onerror = (error) => console.error('[MCP Error]', error);
51
46
  process.on('SIGINT', async () => {
52
47
  await this.server.close();
53
48
  process.exit(0);
54
49
  });
55
50
  }
56
51
  setupToolHandlers() {
57
- this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
58
- tools: [
59
- {
60
- name: 'get_product',
61
- description: 'Get detailed information about a specific product by ID',
62
- inputSchema: zodToJsonSchema(GetProductInputSchema),
63
- annotations: {
64
- readOnlyHint: true,
65
- idempotentHint: true,
66
- openWorldHint: true
67
- }
68
- },
69
- {
70
- name: 'get_user',
71
- description: 'Get Yazio user profile information',
72
- inputSchema: zodToJsonSchema(GetUserInfoInputSchema),
73
- annotations: {
74
- readOnlyHint: true,
75
- idempotentHint: true
76
- }
77
- },
78
- {
79
- name: 'get_user_consumed_items',
80
- description: 'Get food entries for a specific date',
81
- inputSchema: zodToJsonSchema(GetFoodEntriesInputSchema),
82
- annotations: {
83
- readOnlyHint: true,
84
- idempotentHint: true
85
- }
86
- },
87
- {
88
- name: 'get_user_dietary_preferences',
89
- description: 'Get user dietary preferences and restrictions',
90
- inputSchema: zodToJsonSchema(GetDietaryPreferencesInputSchema),
91
- annotations: {
92
- readOnlyHint: true,
93
- idempotentHint: true
94
- }
95
- },
96
- {
97
- name: 'get_user_exercises',
98
- description: 'Get user exercise data for a date or date range',
99
- inputSchema: zodToJsonSchema(GetUserExercisesInputSchema),
100
- annotations: {
101
- readOnlyHint: true,
102
- idempotentHint: true
103
- }
104
- },
105
- {
106
- name: 'get_user_goals',
107
- description: 'Get user nutrition and fitness goals',
108
- inputSchema: zodToJsonSchema(GetUserGoalsInputSchema),
109
- annotations: {
110
- readOnlyHint: true,
111
- idempotentHint: true
112
- }
113
- },
114
- {
115
- name: 'get_user_settings',
116
- description: 'Get user settings and preferences',
117
- inputSchema: zodToJsonSchema(GetUserSettingsInputSchema),
118
- annotations: {
119
- readOnlyHint: true,
120
- idempotentHint: true
121
- }
122
- },
123
- {
124
- name: 'get_user_suggested_products',
125
- description: 'Get product suggestions for the user',
126
- inputSchema: zodToJsonSchema(GetUserSuggestedProductsInputSchema),
127
- annotations: {
128
- readOnlyHint: true,
129
- idempotentHint: true,
130
- openWorldHint: true
131
- }
132
- },
133
- {
134
- name: 'get_user_water_intake',
135
- description: 'Get water intake data for a specific date',
136
- inputSchema: zodToJsonSchema(GetWaterIntakeInputSchema),
137
- annotations: {
138
- readOnlyHint: true,
139
- idempotentHint: true
140
- }
141
- },
142
- {
143
- name: 'get_user_weight',
144
- description: 'Get user weight data',
145
- inputSchema: zodToJsonSchema(GetUserWeightInputSchema),
146
- annotations: {
147
- readOnlyHint: true,
148
- idempotentHint: true
149
- }
150
- },
151
- {
152
- name: 'search_products',
153
- description: 'Search for food products in Yazio database',
154
- inputSchema: zodToJsonSchema(SearchProductsInputSchema),
155
- annotations: {
156
- readOnlyHint: true,
157
- idempotentHint: true,
158
- openWorldHint: true
159
- }
160
- },
161
- {
162
- name: 'get_user_daily_summary',
163
- description: 'Get daily nutrition summary for a specific date',
164
- inputSchema: zodToJsonSchema(GetDailySummaryInputSchema),
165
- annotations: {
166
- readOnlyHint: true,
167
- idempotentHint: true
168
- }
169
- },
170
- {
171
- name: 'add_user_consumed_item',
172
- description: 'Add a food item to user consumption log',
173
- inputSchema: zodToJsonSchema(AddConsumedItemInputSchema),
174
- annotations: {
175
- readOnlyHint: false,
176
- idempotentHint: false
52
+ this.server.registerTool('get_user', {
53
+ description: 'Get Yazio user profile information',
54
+ inputSchema: GetUserInfoInputSchema,
55
+ annotations: {
56
+ readOnlyHint: true,
57
+ idempotentHint: true,
58
+ },
59
+ }, async () => {
60
+ return await this.getUser();
61
+ });
62
+ this.server.registerTool('get_user_consumed_items', {
63
+ description: 'Get food entries for a specific date',
64
+ inputSchema: GetFoodEntriesInputSchema,
65
+ annotations: {
66
+ readOnlyHint: true,
67
+ idempotentHint: true,
68
+ },
69
+ }, async (args) => {
70
+ return await this.getUserConsumedItems(args);
71
+ });
72
+ this.server.registerTool('get_user_dietary_preferences', {
73
+ description: 'Get user dietary preferences and restrictions',
74
+ inputSchema: GetDietaryPreferencesInputSchema,
75
+ annotations: {
76
+ readOnlyHint: true,
77
+ idempotentHint: true,
78
+ },
79
+ }, async () => {
80
+ return await this.getUserDietaryPreferences();
81
+ });
82
+ this.server.registerTool('get_user_exercises', {
83
+ description: 'Get user exercise data for a date or date range',
84
+ inputSchema: GetUserExercisesInputSchema,
85
+ annotations: {
86
+ readOnlyHint: true,
87
+ idempotentHint: true,
88
+ },
89
+ }, async (args) => {
90
+ return await this.getUserExercises(args);
91
+ });
92
+ this.server.registerTool('get_user_goals', {
93
+ description: 'Get user nutrition and fitness goals',
94
+ inputSchema: GetUserGoalsInputSchema,
95
+ annotations: {
96
+ readOnlyHint: true,
97
+ idempotentHint: true,
98
+ },
99
+ }, async () => {
100
+ return await this.getUserGoals();
101
+ });
102
+ this.server.registerTool('get_user_settings', {
103
+ description: 'Get user settings and preferences',
104
+ inputSchema: GetUserSettingsInputSchema,
105
+ annotations: {
106
+ readOnlyHint: true,
107
+ idempotentHint: true,
108
+ },
109
+ }, async () => {
110
+ return await this.getUserSettings();
111
+ });
112
+ this.server.registerTool('get_user_suggested_products', {
113
+ description: 'Get product suggestions for the user',
114
+ inputSchema: GetUserSuggestedProductsInputSchema,
115
+ annotations: {
116
+ readOnlyHint: true,
117
+ idempotentHint: true,
118
+ openWorldHint: true,
119
+ },
120
+ }, async (args) => {
121
+ return await this.getUserSuggestedProducts(args);
122
+ });
123
+ this.server.registerTool('get_user_water_intake', {
124
+ description: 'Get water intake data for a specific date',
125
+ inputSchema: GetWaterIntakeInputSchema,
126
+ annotations: {
127
+ readOnlyHint: true,
128
+ idempotentHint: true,
129
+ },
130
+ }, async (args) => {
131
+ return await this.getUserWaterIntake(args);
132
+ });
133
+ this.server.registerTool('get_user_weight', {
134
+ description: 'Get user weight data',
135
+ inputSchema: GetUserWeightInputSchema,
136
+ annotations: {
137
+ readOnlyHint: true,
138
+ idempotentHint: true,
139
+ },
140
+ }, async () => {
141
+ return await this.getUserWeight();
142
+ });
143
+ this.server.registerTool('get_user_daily_summary', {
144
+ description: 'Get daily nutrition summary for a specific date',
145
+ inputSchema: GetDailySummaryInputSchema,
146
+ annotations: {
147
+ readOnlyHint: true,
148
+ idempotentHint: true,
149
+ },
150
+ }, async (args) => {
151
+ return await this.getUserDailySummary(args);
152
+ });
153
+ this.server.registerTool('search_products', {
154
+ description: 'Search for food products in Yazio database',
155
+ inputSchema: SearchProductsInputSchema,
156
+ // outputSchema: SearchProductsOutputSchema,
157
+ annotations: {
158
+ readOnlyHint: true,
159
+ idempotentHint: true,
160
+ openWorldHint: true,
161
+ },
162
+ }, async (args) => {
163
+ return await this.searchProducts(args);
164
+ });
165
+ this.server.registerTool('get_product', {
166
+ description: 'Get detailed information about a specific product by ID',
167
+ inputSchema: GetProductInputSchema,
168
+ annotations: {
169
+ readOnlyHint: true,
170
+ idempotentHint: true,
171
+ openWorldHint: true,
172
+ },
173
+ }, async (args) => {
174
+ return await this.getProduct(args);
175
+ });
176
+ this.server.registerTool('add_user_consumed_item', {
177
+ description: 'Add a food item to user consumption log',
178
+ inputSchema: AddConsumedItemInputSchema,
179
+ annotations: {
180
+ readOnlyHint: false,
181
+ idempotentHint: false,
182
+ },
183
+ }, async (args) => {
184
+ return await this.addUserConsumedItem(args);
185
+ });
186
+ this.server.registerTool('remove_user_consumed_item', {
187
+ description: 'Remove a food item from user consumption log',
188
+ inputSchema: RemoveConsumedItemInputSchema,
189
+ annotations: {
190
+ readOnlyHint: false,
191
+ destructiveHint: true,
192
+ idempotentHint: true,
193
+ },
194
+ }, async (args) => {
195
+ return await this.removeUserConsumedItem(args);
196
+ });
197
+ }
198
+ setupPromptHandlers() {
199
+ this.server.registerPrompt('add_food_item', {
200
+ title: 'Add Food Item to Log',
201
+ description: 'Guide for adding a food item to the user\'s consumption log',
202
+ }, async () => {
203
+ return {
204
+ messages: [
205
+ {
206
+ role: 'user',
207
+ content: {
208
+ type: 'text',
209
+ text: `To add a food item to the user's consumption log, follow these steps:
210
+
211
+ 1. **Search for the product**: Use the \`search_products\` tool with a query string (e.g., "chicken breast", "apple", "pasta"). This will return a list of matching products with their IDs.
212
+
213
+ 2. **Clarify the product**: If multiple products are found, ask the user to clarify which product they want to use.
214
+
215
+ 3. **Get product details**: Use the \`get_product\` tool with the \`product_id\` from the search results. This will show you:
216
+ - Available serving types (e.g., "portion", "gram", "piece", "cup") and their amounts in base units (g or ml)
217
+ - Base unit (g or ml)
218
+ - Full nutritional information
219
+
220
+ 4. **Clarify the serving**: If the user doesn't provide a serving type and quantity, ask them to clarify the serving type provided by previous step and quantity they want to add.
221
+
222
+ 5. **Add the consumed item**: Use the \`add_user_consumed_item\` tool with:
223
+ - \`product_id\`: The UUID from step 1
224
+ - \`date\`: Date in YYYY-MM-DD format
225
+ - \`daytime\`: One of: "breakfast", "lunch", "dinner", or "snack"
226
+ - \`serving\`: Use a serving type from step 2 (e.g., "portion", "piece", "cup") OR base unit (g or ml)
227
+ - \`serving_quantity\`: Quantity of the serving type (e.g., 1, 2, 0.5)
228
+ - \`amount\`: Direct amount in base units (g or ml). If serving type is provided, use the amount of the serving type * serving_quantity. If serving type is not provided, use the amount of the base unit.
229
+
230
+ **Important Notes**:
231
+ - Always search first if you don't have a product_id
232
+ - Check product details to understand available serving types, base unit (g or ml) and amount in serving
233
+ - The date should be in ISO format (YYYY-MM-DD)
234
+ - You can use serving or base unit approach:
235
+ 1. serving type + serving quantity + amount (amount for selected serving type multiplied by serving quantity)
236
+ 2. amount in g/ml - serving fields could be omitted
237
+ Example:
238
+ 1. "I ate 2 apples" - serving type "piece" which has 100g amount (from product details) + serving quantity 2 + amount 200g
239
+ 2. "I ate 200g of chicken breast" - amount 200g
240
+ - Always provide amount in base units (g or ml), not in servings.
241
+ `
242
+ }
177
243
  }
178
- },
179
- {
180
- name: 'remove_user_consumed_item',
181
- description: 'Remove a food item from user consumption log',
182
- inputSchema: zodToJsonSchema(RemoveConsumedItemInputSchema),
183
- annotations: {
184
- readOnlyHint: false,
185
- destructiveHint: true,
186
- idempotentHint: true
244
+ ]
245
+ };
246
+ });
247
+ this.server.registerPrompt('remove_food_item', {
248
+ title: 'Remove Food Item from Log',
249
+ description: 'Guide for removing a food item from the user\'s consumption log',
250
+ }, async () => {
251
+ return {
252
+ messages: [
253
+ {
254
+ role: 'user',
255
+ content: {
256
+ type: 'text',
257
+ text: `To remove a food item from the user's consumption log, follow these steps:
258
+
259
+ 1. **Get consumed items**: Use the \`get_user_consumed_items\` tool with the \`date\` parameter (in YYYY-MM-DD format) to retrieve all food entries for that date.
260
+
261
+ 2. **Identify the item**: From the returned list of consumed items, identify the specific item you want to remove. Each item will have:
262
+ - \`id\`: The unique identifier for the consumed item (this is what you need for removal)
263
+ - \`product_id\`: The product identifier
264
+ - \`name\`: The product name
265
+ - \`date\`: The date it was consumed
266
+ - \`daytime\`: The meal type (breakfast, lunch, dinner, snack)
267
+ - Other details like amount, serving, etc.
268
+
269
+ 3. **Remove the item**: Use the \`remove_user_consumed_item\` tool with:
270
+ - \`itemId\`: The \`id\` field from the consumed item you identified in step 2
271
+
272
+ **Important Notes**:
273
+ - You must first retrieve the consumed items to get the item ID
274
+ - The \`itemId\` is different from \`product_id\` - use the \`id\` field from the consumed item
275
+ - The date should be in ISO format (YYYY-MM-DD)
276
+ - If multiple items match the description, you may need to ask the user to clarify which specific item to remove`
277
+ }
187
278
  }
188
- },
189
- ],
190
- }));
191
- this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
192
- const { name, arguments: args } = request.params;
193
- try {
194
- switch (name) {
195
- case 'get_product':
196
- return await this.getProduct(GetProductInputSchema.parse(args));
197
- case 'get_user':
198
- return await this.getUser();
199
- case 'get_user_consumed_items':
200
- return await this.getUserConsumedItems(GetFoodEntriesInputSchema.parse(args));
201
- case 'get_user_dietary_preferences':
202
- return await this.getUserDietaryPreferences();
203
- case 'get_user_exercises':
204
- return await this.getUserExercises(GetUserExercisesInputSchema.parse(args));
205
- case 'get_user_goals':
206
- return await this.getUserGoals();
207
- case 'get_user_settings':
208
- return await this.getUserSettings();
209
- case 'get_user_suggested_products':
210
- return await this.getUserSuggestedProducts(GetUserSuggestedProductsInputSchema.parse(args));
211
- case 'get_user_water_intake':
212
- return await this.getUserWaterIntake(GetWaterIntakeInputSchema.parse(args));
213
- case 'get_user_weight':
214
- return await this.getUserWeight();
215
- case 'search_products':
216
- return await this.searchProducts(SearchProductsInputSchema.parse(args));
217
- case 'get_user_daily_summary':
218
- return await this.getUserDailySummary(GetDailySummaryInputSchema.parse(args));
219
- case 'add_user_consumed_item':
220
- return await this.addUserConsumedItem(AddConsumedItemInputSchema.parse(args));
221
- case 'remove_user_consumed_item':
222
- return await this.removeUserConsumedItem(RemoveConsumedItemInputSchema.parse(args));
223
- default:
224
- throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
225
- }
226
- }
227
- catch (error) {
228
- const errorMessage = error instanceof Error ? error.message : String(error);
229
- throw new McpError(ErrorCode.InternalError, errorMessage);
230
- }
279
+ ]
280
+ };
231
281
  });
232
282
  }
233
283
  async ensureAuthenticated() {
@@ -330,9 +380,10 @@ class YazioMcpServer {
330
380
  content: [
331
381
  {
332
382
  type: 'text',
333
- text: `Search results for "${args.query}":\n\n${JSON.stringify(products, null, 2)}`,
383
+ text: `Products:\n\n${JSON.stringify(products, null, 2)}`,
334
384
  },
335
385
  ],
386
+ products,
336
387
  };
337
388
  }
338
389
  catch (error) {
@@ -418,14 +469,15 @@ class YazioMcpServer {
418
469
  async addUserConsumedItem(args) {
419
470
  const client = await this.ensureAuthenticated();
420
471
  try {
421
- // The Yazio API expects specific parameters, we'll pass them directly
422
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
423
- const result = await client.user.addConsumedItem(args);
472
+ await client.user.addConsumedItem({
473
+ ...args,
474
+ id: uuidv4(),
475
+ });
424
476
  return {
425
477
  content: [
426
478
  {
427
479
  type: 'text',
428
- text: `Successfully added consumed item:\n\n${JSON.stringify(result, null, 2)}`,
480
+ text: `Successfully added consumed item`,
429
481
  },
430
482
  ],
431
483
  };
package/dist/schemas.d.ts CHANGED
@@ -1,126 +1,93 @@
1
- import { z } from 'zod';
2
- export declare const DaytimeSchema: z.ZodEnum<["breakfast", "lunch", "dinner", "snack"]>;
3
- export type Daytime = z.infer<typeof DaytimeSchema>;
4
- export declare const DateStringSchema: z.ZodString;
5
- export declare const ProductIdSchema: z.ZodString;
6
- export declare const ItemIdSchema: z.ZodString;
1
+ import * as z from "zod";
2
+ export declare const DaytimeSchema: z.ZodEnum<{
3
+ breakfast: "breakfast";
4
+ lunch: "lunch";
5
+ dinner: "dinner";
6
+ snack: "snack";
7
+ }>;
8
+ export declare const DateStringSchema: z.ZodISODate;
9
+ export declare const ProductIdSchema: z.ZodUUID;
10
+ export declare const ItemIdSchema: z.ZodUUID;
11
+ export declare const ServingTypeSchema: z.ZodString;
7
12
  export declare const QueryStringSchema: z.ZodString;
8
13
  export declare const LimitSchema: z.ZodOptional<z.ZodNumber>;
9
14
  export declare const DateInputSchema: z.ZodObject<{
10
- date: z.ZodString;
11
- }, "strip", z.ZodTypeAny, {
12
- date: string;
13
- }, {
14
- date: string;
15
- }>;
15
+ date: z.ZodISODate;
16
+ }, z.core.$strip>;
16
17
  export declare const OptionalDateInputSchema: z.ZodObject<{
17
- date: z.ZodOptional<z.ZodString>;
18
- }, "strip", z.ZodTypeAny, {
19
- date?: string | undefined;
20
- }, {
21
- date?: string | undefined;
22
- }>;
18
+ date: z.ZodOptional<z.ZodISODate>;
19
+ }, z.core.$strip>;
23
20
  export declare const QueryInputSchema: z.ZodObject<{
24
21
  query: z.ZodString;
25
- }, "strip", z.ZodTypeAny, {
26
- query: string;
27
- }, {
28
- query: string;
29
- }>;
22
+ }, z.core.$strip>;
30
23
  export declare const OptionalQueryInputSchema: z.ZodObject<{
31
24
  query: z.ZodOptional<z.ZodString>;
32
25
  limit: z.ZodOptional<z.ZodNumber>;
33
- }, "strip", z.ZodTypeAny, {
34
- query?: string | undefined;
35
- limit?: number | undefined;
36
- }, {
37
- query?: string | undefined;
38
- limit?: number | undefined;
39
- }>;
40
- export declare const EmptyInputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
26
+ }, z.core.$strip>;
27
+ export declare const EmptyInputSchema: z.ZodObject<{}, z.core.$strip>;
41
28
  export declare const GetFoodEntriesInputSchema: z.ZodObject<{
42
- date: z.ZodString;
43
- }, "strip", z.ZodTypeAny, {
44
- date: string;
45
- }, {
46
- date: string;
47
- }>;
29
+ date: z.ZodISODate;
30
+ }, z.core.$strip>;
48
31
  export declare const GetDailySummaryInputSchema: z.ZodObject<{
49
- date: z.ZodString;
50
- }, "strip", z.ZodTypeAny, {
51
- date: string;
52
- }, {
53
- date: string;
54
- }>;
55
- export declare const GetUserInfoInputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
56
- export declare const GetUserWeightInputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
32
+ date: z.ZodISODate;
33
+ }, z.core.$strip>;
34
+ export declare const GetUserInfoInputSchema: z.ZodObject<{}, z.core.$strip>;
35
+ export declare const GetUserWeightInputSchema: z.ZodObject<{}, z.core.$strip>;
57
36
  export declare const GetWaterIntakeInputSchema: z.ZodObject<{
58
- date: z.ZodString;
59
- }, "strip", z.ZodTypeAny, {
60
- date: string;
61
- }, {
62
- date: string;
63
- }>;
37
+ date: z.ZodISODate;
38
+ }, z.core.$strip>;
64
39
  export declare const SearchProductsInputSchema: z.ZodObject<{
65
40
  query: z.ZodString;
66
- }, "strip", z.ZodTypeAny, {
67
- query: string;
68
- }, {
69
- query: string;
70
- }>;
41
+ }, z.core.$strip>;
42
+ export declare const SearchProductsOutputSchema: z.ZodObject<{
43
+ products: z.ZodArray<z.ZodObject<{
44
+ score: z.ZodNumber;
45
+ name: z.ZodString;
46
+ product_id: z.ZodUUID;
47
+ serving: z.ZodString;
48
+ serving_quantity: z.ZodNumber;
49
+ amount: z.ZodNumber;
50
+ base_unit: z.ZodEnum<{
51
+ g: "g";
52
+ ml: "ml";
53
+ }>;
54
+ producer: z.ZodNullable<z.ZodString>;
55
+ is_verified: z.ZodBoolean;
56
+ nutrients: z.ZodRecord<z.ZodString, z.ZodNumber>;
57
+ countries: z.ZodArray<z.ZodString>;
58
+ language: z.ZodString;
59
+ }, z.core.$strip>>;
60
+ }, z.core.$strip>;
71
61
  export declare const GetProductInputSchema: z.ZodObject<{
72
- id: z.ZodString;
73
- }, "strip", z.ZodTypeAny, {
74
- id: string;
75
- }, {
76
- id: string;
77
- }>;
62
+ id: z.ZodUUID;
63
+ }, z.core.$strip>;
78
64
  export declare const GetUserExercisesInputSchema: z.ZodObject<{
79
- date: z.ZodOptional<z.ZodString>;
80
- }, "strip", z.ZodTypeAny, {
81
- date?: string | undefined;
82
- }, {
83
- date?: string | undefined;
84
- }>;
85
- export declare const GetUserSettingsInputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
65
+ date: z.ZodOptional<z.ZodISODate>;
66
+ }, z.core.$strip>;
67
+ export declare const GetUserSettingsInputSchema: z.ZodObject<{}, z.core.$strip>;
86
68
  export declare const GetUserSuggestedProductsInputSchema: z.ZodObject<{
87
69
  query: z.ZodOptional<z.ZodString>;
88
70
  limit: z.ZodOptional<z.ZodNumber>;
89
- }, "strip", z.ZodTypeAny, {
90
- query?: string | undefined;
91
- limit?: number | undefined;
92
- }, {
93
- query?: string | undefined;
94
- limit?: number | undefined;
95
- }>;
71
+ }, z.core.$strip>;
96
72
  export declare const AddConsumedItemInputSchema: z.ZodObject<{
97
- productId: z.ZodOptional<z.ZodString>;
98
- amount: z.ZodOptional<z.ZodNumber>;
99
- unit: z.ZodOptional<z.ZodString>;
100
- date: z.ZodOptional<z.ZodString>;
101
- mealType: z.ZodOptional<z.ZodEnum<["breakfast", "lunch", "dinner", "snack"]>>;
102
- }, "strip", z.ZodTypeAny, {
103
- date?: string | undefined;
104
- productId?: string | undefined;
105
- amount?: number | undefined;
106
- unit?: string | undefined;
107
- mealType?: "breakfast" | "lunch" | "dinner" | "snack" | undefined;
108
- }, {
109
- date?: string | undefined;
110
- productId?: string | undefined;
111
- amount?: number | undefined;
112
- unit?: string | undefined;
113
- mealType?: "breakfast" | "lunch" | "dinner" | "snack" | undefined;
114
- }>;
73
+ product_id: z.ZodUUID;
74
+ date: z.ZodISODate;
75
+ daytime: z.ZodEnum<{
76
+ breakfast: "breakfast";
77
+ lunch: "lunch";
78
+ dinner: "dinner";
79
+ snack: "snack";
80
+ }>;
81
+ amount: z.ZodNumber;
82
+ serving: z.ZodOptional<z.ZodString>;
83
+ serving_quantity: z.ZodOptional<z.ZodNumber>;
84
+ }, z.core.$strip>;
115
85
  export declare const RemoveConsumedItemInputSchema: z.ZodObject<{
116
- itemId: z.ZodString;
117
- }, "strip", z.ZodTypeAny, {
118
- itemId: string;
119
- }, {
120
- itemId: string;
121
- }>;
122
- export declare const GetDietaryPreferencesInputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
123
- export declare const GetUserGoalsInputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
86
+ itemId: z.ZodUUID;
87
+ }, z.core.$strip>;
88
+ export declare const GetDietaryPreferencesInputSchema: z.ZodObject<{}, z.core.$strip>;
89
+ export declare const GetUserGoalsInputSchema: z.ZodObject<{}, z.core.$strip>;
90
+ export type Daytime = z.infer<typeof DaytimeSchema>;
124
91
  export type GetFoodEntriesInput = z.infer<typeof GetFoodEntriesInputSchema>;
125
92
  export type GetDailySummaryInput = z.infer<typeof GetDailySummaryInputSchema>;
126
93
  export type GetUserInfoInput = z.infer<typeof GetUserInfoInputSchema>;
package/dist/schemas.js CHANGED
@@ -1,15 +1,16 @@
1
- import { z } from 'zod';
1
+ import * as z from "zod";
2
2
  export const DaytimeSchema = z.enum(['breakfast', 'lunch', 'dinner', 'snack']);
3
- export const DateStringSchema = z.string().describe('Date in YYYY-MM-DD format');
4
- export const ProductIdSchema = z.string().describe('Unique product identifier');
5
- export const ItemIdSchema = z.string().describe('Unique item identifier');
3
+ export const DateStringSchema = z.iso.date().describe('Date in YYYY-MM-DD format');
4
+ export const ProductIdSchema = z.uuid().describe('Product UUID v1/v4 (e.g. 4ceff6e9-78ce-441b-964a-22e81c1dee92)');
5
+ export const ItemIdSchema = ProductIdSchema.describe('Unique item identifier');
6
+ export const ServingTypeSchema = z.string().describe('Serving type (e.g. portion, fruit, glass, cup, slice, piece, bar, gram, bottle, can, etc.)');
6
7
  export const QueryStringSchema = z.string().describe('Search query string');
7
8
  export const LimitSchema = z.number().optional().describe('Maximum number of results to return');
8
9
  export const DateInputSchema = z.object({
9
- date: DateStringSchema.describe('Date to get data for')
10
+ date: DateStringSchema
10
11
  });
11
12
  export const OptionalDateInputSchema = z.object({
12
- date: DateStringSchema.optional().describe('Specific date to get data for (optional)')
13
+ date: DateStringSchema.optional()
13
14
  });
14
15
  export const QueryInputSchema = z.object({
15
16
  query: QueryStringSchema.describe('Search query')
@@ -25,6 +26,22 @@ export const GetUserInfoInputSchema = EmptyInputSchema;
25
26
  export const GetUserWeightInputSchema = EmptyInputSchema; // Yazio getWeight doesn't accept parameters
26
27
  export const GetWaterIntakeInputSchema = DateInputSchema;
27
28
  export const SearchProductsInputSchema = QueryInputSchema;
29
+ export const SearchProductsOutputSchema = z.object({
30
+ products: z.array(z.object({
31
+ score: z.number(),
32
+ name: z.string(),
33
+ product_id: ProductIdSchema,
34
+ serving: ServingTypeSchema,
35
+ serving_quantity: z.number(),
36
+ amount: z.number(),
37
+ base_unit: z.enum(['g', 'ml']).describe('Base unit: grams (g) or milliliters (ml)'),
38
+ producer: z.string().nullable().describe('Producer name'),
39
+ is_verified: z.boolean(),
40
+ nutrients: z.record(z.string(), z.number()).describe('Nutrients object with keys like energy.energy, nutrient.carb, etc.'),
41
+ countries: z.array(z.string()).describe('Array of country codes (e.g. ["US", "DE"])'),
42
+ language: z.string().describe('Language code (e.g. "en", "de")'),
43
+ })),
44
+ });
28
45
  export const GetProductInputSchema = z.object({
29
46
  id: ProductIdSchema.describe('Product ID to get details for')
30
47
  });
@@ -32,11 +49,13 @@ export const GetUserExercisesInputSchema = OptionalDateInputSchema; // Only supp
32
49
  export const GetUserSettingsInputSchema = EmptyInputSchema;
33
50
  export const GetUserSuggestedProductsInputSchema = OptionalQueryInputSchema;
34
51
  export const AddConsumedItemInputSchema = z.object({
35
- productId: z.string().optional().describe('ID of the product to add'),
36
- amount: z.number().optional().describe('Amount of the product consumed'),
37
- unit: z.string().optional().describe('Unit of measurement (g, ml, pieces, etc.)'),
38
- date: z.string().optional().describe('Date when the food was consumed (defaults to today) in YYYY-MM-DD format'),
39
- mealType: DaytimeSchema.optional().describe('Type of meal')
52
+ // id: ProductIdSchema.describe('Random identifier for the consumed item'),
53
+ product_id: ProductIdSchema,
54
+ date: DateStringSchema.describe('Date when the food was consumed'),
55
+ daytime: DaytimeSchema.describe('Type of meal (breakfast, lunch, dinner, snack)'),
56
+ amount: z.number().describe('Amount of the product consumed in base units (g or ml)'),
57
+ serving: ServingTypeSchema.optional(),
58
+ serving_quantity: z.number().optional().describe('Quantity of servings')
40
59
  });
41
60
  export const RemoveConsumedItemInputSchema = z.object({
42
61
  itemId: ItemIdSchema.describe('ID of the consumed item to remove')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yazio-mcp",
3
- "version": "0.0.3",
3
+ "version": "0.0.6",
4
4
  "description": "MCP server for accessing Yazio user & nutrition data (unofficial)",
5
5
  "mcpName": "io.github.fliptheweb/yazio-mcp",
6
6
  "author": "fliptheweb",
@@ -47,16 +47,15 @@
47
47
  "node": ">=18.0.0"
48
48
  },
49
49
  "dependencies": {
50
- "@modelcontextprotocol/sdk": "^1.18.2",
50
+ "@modelcontextprotocol/sdk": "^1.25.0",
51
+ "uuid": "^13.0.0",
51
52
  "yazio": "^1.0.0",
52
- "zod": "^3.22.0",
53
- "zod-to-json-schema": "^3.24.6"
53
+ "zod": "^4.2.1"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/node": "^20.0.0",
57
57
  "@typescript-eslint/eslint-plugin": "^8.44.1",
58
58
  "@typescript-eslint/parser": "^8.44.1",
59
- "ajv-cli": "^5.0.0",
60
59
  "eslint": "^9.36.0",
61
60
  "globals": "^16.4.0",
62
61
  "prettier": "^3.6.2",