mcp-grocy 1.9.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.
@@ -0,0 +1,230 @@
1
+ import { BaseToolHandler } from '../base.js';
2
+ import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
3
+ import apiClient from '../../api/client.js';
4
+ import config from '../../config/environment.js';
5
+ export const systemToolDefinitions = [
6
+ {
7
+ name: 'get_locations',
8
+ description: 'Get all storage locations from your Grocy instance. Use this to find location IDs and names when working with other tools that require locationId parameters.',
9
+ inputSchema: {
10
+ type: 'object',
11
+ properties: {},
12
+ required: []
13
+ }
14
+ },
15
+ {
16
+ name: 'get_quantity_units',
17
+ description: 'Get all quantity units from your Grocy instance.',
18
+ inputSchema: {
19
+ type: 'object',
20
+ properties: {},
21
+ required: []
22
+ }
23
+ },
24
+ {
25
+ name: 'get_users',
26
+ description: 'Get all users from your Grocy instance.',
27
+ inputSchema: {
28
+ type: 'object',
29
+ properties: {},
30
+ required: []
31
+ }
32
+ },
33
+ {
34
+ name: 'get_chores',
35
+ description: 'Get all chores from your Grocy instance.',
36
+ inputSchema: {
37
+ type: 'object',
38
+ properties: {},
39
+ required: []
40
+ }
41
+ },
42
+ {
43
+ name: 'get_tasks',
44
+ description: 'Get all tasks from your Grocy instance.',
45
+ inputSchema: {
46
+ type: 'object',
47
+ properties: {},
48
+ required: []
49
+ }
50
+ },
51
+ {
52
+ name: 'get_batteries',
53
+ description: 'Get all batteries from your Grocy instance.',
54
+ inputSchema: {
55
+ type: 'object',
56
+ properties: {},
57
+ required: []
58
+ }
59
+ },
60
+ {
61
+ name: 'get_equipment',
62
+ description: 'Get all equipment from your Grocy instance.',
63
+ inputSchema: {
64
+ type: 'object',
65
+ properties: {},
66
+ required: []
67
+ }
68
+ },
69
+ {
70
+ name: 'call_grocy_api',
71
+ description: 'Call a specific Grocy API endpoint with custom parameters.',
72
+ inputSchema: {
73
+ type: 'object',
74
+ properties: {
75
+ endpoint: {
76
+ type: 'string',
77
+ description: 'Grocy API endpoint to call (e.g., "objects/products"). Do not include /api/ prefix.'
78
+ },
79
+ method: {
80
+ type: 'string',
81
+ enum: ['GET', 'POST', 'PUT', 'DELETE'],
82
+ description: 'HTTP method to use',
83
+ default: 'GET'
84
+ },
85
+ body: {
86
+ type: 'object',
87
+ description: 'Optional request body for POST/PUT requests'
88
+ }
89
+ },
90
+ required: ['endpoint']
91
+ }
92
+ },
93
+ {
94
+ name: 'test_request',
95
+ description: `Test a REST API endpoint and get detailed response information. Base URL: ${config.getGrocyBaseUrl()} | SSL Verification ${config.get().GROCY_ENABLE_SSL_VERIFY ? 'enabled' : 'disabled'} (see config resource for SSL settings) | Authentication: ${config.hasApiKeyAuth() ? 'API Key using header: GROCY-API-KEY' : 'No authentication configured'}`,
96
+ inputSchema: {
97
+ type: 'object',
98
+ properties: {
99
+ method: {
100
+ type: 'string',
101
+ enum: ['GET', 'POST', 'PUT', 'DELETE'],
102
+ description: 'HTTP method to use'
103
+ },
104
+ endpoint: {
105
+ type: 'string',
106
+ description: 'Endpoint path (e.g. "/users"). Do not include full URLs - only the path.'
107
+ },
108
+ body: {
109
+ type: 'object',
110
+ description: 'Optional request body for POST/PUT requests'
111
+ },
112
+ headers: {
113
+ type: 'object',
114
+ description: 'Optional request headers for one-time use.',
115
+ additionalProperties: {
116
+ type: 'string'
117
+ }
118
+ }
119
+ },
120
+ required: ['method', 'endpoint']
121
+ }
122
+ }
123
+ ];
124
+ class SystemToolHandlers extends BaseToolHandler {
125
+ getLocations = async (args) => {
126
+ return this.handleApiCall('/objects/locations', 'Get all storage locations');
127
+ };
128
+ getQuantityUnits = async (args) => {
129
+ return this.handleApiCall('/objects/quantity_units', 'Get all quantity units');
130
+ };
131
+ getUsers = async (args) => {
132
+ return this.handleApiCall('/users', 'Get all users');
133
+ };
134
+ getChores = async (args) => {
135
+ return this.handleApiCall('/objects/chores', 'Get all chores');
136
+ };
137
+ getTasks = async (args) => {
138
+ return this.handleApiCall('/objects/tasks', 'Get all tasks');
139
+ };
140
+ getBatteries = async (args) => {
141
+ return this.handleApiCall('/objects/batteries', 'Get all batteries');
142
+ };
143
+ getEquipment = async (args) => {
144
+ return this.handleApiCall('/objects/equipment', 'Get all equipment');
145
+ };
146
+ callGrocyApi = async (args) => {
147
+ const { endpoint, method = 'GET', body = null } = args;
148
+ if (!endpoint) {
149
+ throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: endpoint');
150
+ }
151
+ // Remove leading /api/ if present
152
+ const cleanEndpoint = endpoint.replace(/^\/?(?:api\/)?/, '');
153
+ try {
154
+ const response = await apiClient.request(`/${cleanEndpoint}`, {
155
+ method,
156
+ body
157
+ });
158
+ return this.createSuccessResult(response.data);
159
+ }
160
+ catch (error) {
161
+ console.error(`Error calling Grocy API endpoint ${endpoint}:`, error);
162
+ return this.createErrorResult(`Failed to call Grocy API endpoint ${endpoint}: ${error.message}`);
163
+ }
164
+ };
165
+ testRequest = async (args) => {
166
+ // This is a more complex handler that provides detailed request/response information
167
+ // Implementation would be similar to the original handleTestRequest but simplified
168
+ const { method, endpoint, body, headers = {} } = args;
169
+ if (!method || !endpoint) {
170
+ throw new McpError(ErrorCode.InvalidParams, 'method and endpoint are required');
171
+ }
172
+ const normalizedEndpoint = `/${endpoint.replace(/^\/+|\/+$/g, '')}`;
173
+ try {
174
+ const startTime = Date.now();
175
+ const response = await apiClient.request(normalizedEndpoint, {
176
+ method,
177
+ body,
178
+ headers
179
+ });
180
+ const endTime = Date.now();
181
+ const responseObj = {
182
+ request: {
183
+ url: `${config.getGrocyBaseUrl()}${normalizedEndpoint}`,
184
+ method,
185
+ headers: { ...config.getCustomHeaders(), ...headers },
186
+ body,
187
+ authMethod: config.hasApiKeyAuth() ? 'apikey' : 'none'
188
+ },
189
+ response: {
190
+ statusCode: response.status,
191
+ timing: `${endTime - startTime}ms`,
192
+ headers: response.headers,
193
+ body: response.data
194
+ },
195
+ validation: {
196
+ isError: response.status >= 400,
197
+ messages: response.status >= 400 ?
198
+ [`Request failed with status ${response.status}`] :
199
+ ['Request completed successfully']
200
+ }
201
+ };
202
+ return this.createSuccessResult(responseObj);
203
+ }
204
+ catch (error) {
205
+ return this.createErrorResult(`Test request failed: ${error.message}`, {
206
+ request: {
207
+ url: `${config.getGrocyBaseUrl()}${normalizedEndpoint}`,
208
+ method,
209
+ headers: { ...config.getCustomHeaders(), ...headers },
210
+ body
211
+ }
212
+ });
213
+ }
214
+ };
215
+ }
216
+ const systemHandlers = new SystemToolHandlers();
217
+ export const systemModule = {
218
+ definitions: systemToolDefinitions,
219
+ handlers: {
220
+ get_locations: systemHandlers.getLocations,
221
+ get_quantity_units: systemHandlers.getQuantityUnits,
222
+ get_users: systemHandlers.getUsers,
223
+ get_chores: systemHandlers.getChores,
224
+ get_tasks: systemHandlers.getTasks,
225
+ get_batteries: systemHandlers.getBatteries,
226
+ get_equipment: systemHandlers.getEquipment,
227
+ call_grocy_api: systemHandlers.callGrocyApi,
228
+ test_request: systemHandlers.testRequest
229
+ }
230
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ // Auto-generated file - DO NOT MODIFY
2
+ export const VERSION = '1.9.0';
3
+ export const PACKAGE_NAME = 'mcp-grocy';
4
+ export const SERVER_NAME = 'grocy-api';
package/package.json ADDED
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "mcp-grocy",
3
+ "version": "1.9.0",
4
+ "description": "Model Context Protocol (MCP) server for Grocy integration",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "publishConfig": {
8
+ "name": "mcp-grocy",
9
+ "access": "public"
10
+ },
11
+ "bin": {
12
+ "mcp-grocy": "./build/main.js"
13
+ },
14
+ "files": [
15
+ "build",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "scripts": {
20
+ "prebuild": "node scripts/build.js",
21
+ "build": "tsc",
22
+ "prepare": "npm run build",
23
+ "watch": "tsc --watch",
24
+ "inspector": "npx @modelcontextprotocol/inspector build/main.js",
25
+ "test": "vitest run",
26
+ "test:watch": "vitest",
27
+ "check-tools": "node scripts/check-tools.js",
28
+ "validate-release": "node scripts/check-tools.js --validate-release",
29
+ "update-api-docs": "node scripts/fetch-grocy-api.js",
30
+ "verify-release-config": "node scripts/verify-release-config.js",
31
+ "prepare-dev-release": "node scripts/prepare-dev-release.js",
32
+ "prepare-dev-release:patch": "node scripts/prepare-dev-release.js --patch",
33
+ "prepare-dev-release:minor": "node scripts/prepare-dev-release.js --minor",
34
+ "prepare-dev-release:major": "node scripts/prepare-dev-release.js --major",
35
+ "prepare-dev-release:dryrun": "node scripts/prepare-dev-release.js --dry-run"
36
+ },
37
+ "dependencies": {
38
+ "@modelcontextprotocol/sdk": "^1.11.4",
39
+ "axios": "^1.6.7",
40
+ "cors": "^2.8.5",
41
+ "dotenv": "^16.5.0",
42
+ "express": "^5.1.0",
43
+ "fuse.js": "^7.0.0",
44
+ "uuid": "^11.1.0",
45
+ "zod": "^3.22.0"
46
+ },
47
+ "devDependencies": {
48
+ "@commitlint/cli": "^19.6.1",
49
+ "@commitlint/config-conventional": "^19.6.0",
50
+ "@commitlint/types": "^19.6.1",
51
+ "@semantic-release/changelog": "^6.0.3",
52
+ "@semantic-release/exec": "^6.0.3",
53
+ "@semantic-release/git": "^10.0.1",
54
+ "@types/cors": "^2.8.18",
55
+ "@types/express": "^5.0.2",
56
+ "@types/node": "^20.11.20",
57
+ "@types/uuid": "^10.0.0",
58
+ "fs-extra": "^11.2.0",
59
+ "semantic-release": "^22.0.12",
60
+ "ts-node": "^10.9.1",
61
+ "typescript": "^5.3.3",
62
+ "vitest": "^3.1.3"
63
+ },
64
+ "keywords": [
65
+ "grocy",
66
+ "mcp",
67
+ "rest",
68
+ "api",
69
+ "http",
70
+ "testing",
71
+ "cline",
72
+ "development",
73
+ "typescript"
74
+ ],
75
+ "author": "miguelangel-nubla",
76
+ "repository": {
77
+ "type": "git",
78
+ "url": "git+https://github.com/miguelangel-nubla/mcp-grocy.git"
79
+ },
80
+ "bugs": {
81
+ "url": "https://github.com/miguelangel-nubla/mcp-grocy/issues"
82
+ },
83
+ "homepage": "https://github.com/miguelangel-nubla/mcp-grocy#readme",
84
+ "engines": {
85
+ "node": ">=18.0.0"
86
+ }
87
+ }