@pschroee/redmine-mcp 0.3.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.
package/README.md ADDED
@@ -0,0 +1,360 @@
1
+ # Redmine MCP Server
2
+
3
+ A Model Context Protocol (MCP) server for interacting with Redmine project management.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @pschroee/redmine-mcp
9
+ ```
10
+
11
+ Or use directly with npx:
12
+
13
+ ```bash
14
+ npx @pschroee/redmine-mcp --url=https://your-redmine.com --api-key=your-api-key
15
+ ```
16
+
17
+ ## Configuration
18
+
19
+ ### Required
20
+
21
+ - `--url` or `REDMINE_URL`: Your Redmine instance URL
22
+ - `--api-key` or `REDMINE_API_KEY`: Your Redmine API key
23
+
24
+ ### Optional
25
+
26
+ - `--tools=<groups>`: Comma-separated list of tool groups to enable
27
+ - `--exclude=<groups>`: Comma-separated list of tool groups to exclude
28
+ - `--help`: Show usage information
29
+
30
+ ## Tool Groups
31
+
32
+ | Group | Tools | Description |
33
+ |-------|-------|-------------|
34
+ | `core` | 14 | Issues & Projects (CRUD, watchers, archive) |
35
+ | `metadata` | 9 | Trackers, Statuses, Categories, Custom Fields, Queries |
36
+ | `wiki` | 5 | Wiki Pages (CRUD, versioning) |
37
+ | `files` | 5 | Attachments & Project Files |
38
+ | `relations` | 9 | Issue Relations & Versions |
39
+ | `search` | 1 | Global Search |
40
+ | `account` | 1 | Current User Account |
41
+ | `time` | 5 | Time Entry tracking (CRUD, filtering) |
42
+ | `enumerations` | 3 | Issue Priorities, Time Entry Activities, Document Categories |
43
+ | `memberships` | 5 | Project Memberships (CRUD) |
44
+ | `roles` | 2 | Roles listing and details |
45
+ | `admin` | 11 | Users & Groups management (admin only) |
46
+
47
+ **Total: 70 Tools**
48
+
49
+ ## Usage Examples
50
+
51
+ ### Load all tools (default)
52
+
53
+ ```bash
54
+ npx @pschroee/redmine-mcp --url=https://redmine.example.com --api-key=abc123
55
+ ```
56
+
57
+ ### Load only specific groups
58
+
59
+ ```bash
60
+ npx @pschroee/redmine-mcp --tools=core,metadata
61
+ ```
62
+
63
+ ### Exclude specific groups
64
+
65
+ ```bash
66
+ npx @pschroee/redmine-mcp --exclude=wiki,files
67
+ ```
68
+
69
+ ## Claude Configuration
70
+
71
+ ### Quick Setup with Claude CLI
72
+
73
+ **macOS / Linux:**
74
+
75
+ ```bash
76
+ claude mcp add redmine -s user -- npx -y @pschroee/redmine-mcp \
77
+ --url=https://your-redmine.com --api-key=your-api-key
78
+ ```
79
+
80
+ **Windows:**
81
+
82
+ ```bash
83
+ claude mcp add redmine -s user -- cmd /c npx -y @pschroee/redmine-mcp \
84
+ --url=https://your-redmine.com --api-key=your-api-key
85
+ ```
86
+
87
+ ### With Tool Groups
88
+
89
+ **macOS / Linux:**
90
+
91
+ ```bash
92
+ claude mcp add redmine -s user -- npx -y @pschroee/redmine-mcp \
93
+ --url=https://your-redmine.com --api-key=your-api-key \
94
+ --tools=core,metadata,search
95
+ ```
96
+
97
+ **Windows:**
98
+
99
+ ```bash
100
+ claude mcp add redmine -s user -- cmd /c npx -y @pschroee/redmine-mcp \
101
+ --url=https://your-redmine.com --api-key=your-api-key \
102
+ --tools=core,metadata,search
103
+ ```
104
+
105
+ ### Manual Configuration (Claude Desktop)
106
+
107
+ #### macOS / Linux
108
+
109
+ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
110
+
111
+ ```json
112
+ {
113
+ "mcpServers": {
114
+ "redmine": {
115
+ "command": "npx",
116
+ "args": [
117
+ "@pschroee/redmine-mcp",
118
+ "--url=https://your-redmine.com",
119
+ "--api-key=your-api-key"
120
+ ]
121
+ }
122
+ }
123
+ }
124
+ ```
125
+
126
+ #### Windows
127
+
128
+ Add to your Claude Desktop config (`%APPDATA%\Claude\claude_desktop_config.json`):
129
+
130
+ ```json
131
+ {
132
+ "mcpServers": {
133
+ "redmine": {
134
+ "command": "cmd",
135
+ "args": [
136
+ "/c",
137
+ "npx",
138
+ "@pschroee/redmine-mcp",
139
+ "--url=https://your-redmine.com",
140
+ "--api-key=your-api-key"
141
+ ]
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ #### With Tool Groups
148
+
149
+ **macOS / Linux:**
150
+
151
+ ```json
152
+ {
153
+ "mcpServers": {
154
+ "redmine": {
155
+ "command": "npx",
156
+ "args": [
157
+ "@pschroee/redmine-mcp",
158
+ "--url=https://your-redmine.com",
159
+ "--api-key=your-api-key",
160
+ "--tools=core,metadata,search"
161
+ ]
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ **Windows:**
168
+
169
+ ```json
170
+ {
171
+ "mcpServers": {
172
+ "redmine": {
173
+ "command": "cmd",
174
+ "args": [
175
+ "/c",
176
+ "npx",
177
+ "@pschroee/redmine-mcp",
178
+ "--url=https://your-redmine.com",
179
+ "--api-key=your-api-key",
180
+ "--tools=core,metadata,search"
181
+ ]
182
+ }
183
+ }
184
+ }
185
+ ```
186
+
187
+ ## Available Tools
188
+
189
+ ### Core (Issues & Projects)
190
+
191
+ - `list_issues` - List issues with filters and sorting
192
+ - `get_issue` - Get issue details with optional includes
193
+ - `create_issue` - Create new issue
194
+ - `update_issue` - Update issue (including adding notes)
195
+ - `delete_issue` - Delete issue
196
+ - `add_issue_watcher` - Add watcher to issue
197
+ - `remove_issue_watcher` - Remove watcher from issue
198
+ - `list_projects` - List all projects
199
+ - `get_project` - Get project details
200
+ - `create_project` - Create new project
201
+ - `update_project` - Update project
202
+ - `delete_project` - Delete project
203
+ - `archive_project` - Archive project (Redmine 5.0+)
204
+ - `unarchive_project` - Unarchive project (Redmine 5.0+)
205
+
206
+ ### Metadata
207
+
208
+ - `list_trackers` - List all trackers
209
+ - `list_issue_statuses` - List all issue statuses
210
+ - `list_issue_categories` - List categories for a project
211
+ - `get_issue_category` - Get category details
212
+ - `create_issue_category` - Create category
213
+ - `update_issue_category` - Update category
214
+ - `delete_issue_category` - Delete category
215
+ - `list_custom_fields` - List custom fields (admin)
216
+ - `list_queries` - List saved queries
217
+
218
+ ### Wiki
219
+
220
+ - `list_wiki_pages` - List wiki pages in project
221
+ - `get_wiki_page` - Get wiki page content
222
+ - `create_wiki_page` - Create wiki page
223
+ - `update_wiki_page` - Update wiki page
224
+ - `delete_wiki_page` - Delete wiki page
225
+
226
+ ### Files
227
+
228
+ - `get_attachment` - Get attachment metadata
229
+ - `delete_attachment` - Delete attachment
230
+ - `upload_file` - Upload file (returns token)
231
+ - `list_project_files` - List project files
232
+ - `upload_project_file` - Attach file to project
233
+
234
+ ### Relations
235
+
236
+ - `list_issue_relations` - List relations for issue
237
+ - `get_relation` - Get relation details
238
+ - `create_issue_relation` - Create relation
239
+ - `delete_relation` - Delete relation
240
+ - `list_versions` - List project versions
241
+ - `get_version` - Get version details
242
+ - `create_version` - Create version
243
+ - `update_version` - Update version
244
+ - `delete_version` - Delete version
245
+
246
+ ### Search
247
+
248
+ - `search` - Search across Redmine
249
+
250
+ ### Account
251
+
252
+ - `get_my_account` - Get current user info
253
+
254
+ ### Time Entries
255
+
256
+ - `list_time_entries` - List time entries with filters (project, user, date range)
257
+ - `get_time_entry` - Get time entry details
258
+ - `create_time_entry` - Log time on issue or project
259
+ - `update_time_entry` - Update time entry
260
+ - `delete_time_entry` - Delete time entry
261
+
262
+ ### Enumerations
263
+
264
+ - `list_issue_priorities` - List all issue priorities
265
+ - `list_time_entry_activities` - List all time entry activities
266
+ - `list_document_categories` - List all document categories
267
+
268
+ ### Memberships
269
+
270
+ - `list_project_memberships` - List project members
271
+ - `get_membership` - Get membership details
272
+ - `create_project_membership` - Add member to project
273
+ - `update_membership` - Update member roles
274
+ - `delete_membership` - Remove member from project
275
+
276
+ ### Roles
277
+
278
+ - `list_roles` - List all roles
279
+ - `get_role` - Get role with permissions
280
+
281
+ ### Admin (Users & Groups)
282
+
283
+ - `list_users` - List users with filters
284
+ - `get_user` - Get user details
285
+ - `create_user` - Create new user
286
+ - `update_user` - Update user
287
+ - `delete_user` - Delete user
288
+ - `list_groups` - List all groups
289
+ - `get_group` - Get group details
290
+ - `create_group` - Create group
291
+ - `delete_group` - Delete group
292
+ - `add_user_to_group` - Add user to group
293
+ - `remove_user_from_group` - Remove user from group
294
+
295
+ ## Development
296
+
297
+ ```bash
298
+ # Install dependencies
299
+ npm install
300
+
301
+ # Run linter
302
+ npm run lint
303
+
304
+ # Fix lint errors
305
+ npm run lint:fix
306
+
307
+ # Build
308
+ npm run build
309
+ ```
310
+
311
+ ## Testing
312
+
313
+ The project includes comprehensive integration tests that run against a real Redmine instance.
314
+
315
+ ### Setup
316
+
317
+ 1. Create a `.env` file in the project root:
318
+
319
+ ```bash
320
+ REDMINE_URL=http://your-redmine-instance:port
321
+ REDMINE_API_KEY=your-api-key
322
+ ```
323
+
324
+ 2. Run the tests:
325
+
326
+ ```bash
327
+ npm test
328
+ ```
329
+
330
+ ### Test Coverage
331
+
332
+ The test suite includes 195 tests across 12 test files:
333
+
334
+ | Test File | Tests | Description |
335
+ |-----------|-------|-------------|
336
+ | `account.test.ts` | 1 | Current user account |
337
+ | `core.test.ts` | 48 | Projects and Issues CRUD |
338
+ | `metadata.test.ts` | 14 | Trackers, Statuses, Categories |
339
+ | `relations.test.ts` | 24 | Versions and Issue Relations |
340
+ | `wiki.test.ts` | 14 | Wiki Pages CRUD |
341
+ | `files.test.ts` | 11 | File uploads and attachments |
342
+ | `search.test.ts` | 12 | Global search functionality |
343
+ | `enumerations.test.ts` | 4 | Issue priorities, activities, document categories |
344
+ | `time.test.ts` | 17 | Time entry CRUD operations |
345
+ | `roles.test.ts` | 4 | Roles listing and details |
346
+ | `admin.test.ts` | 33 | Users and Groups management |
347
+ | `memberships.test.ts` | 13 | Project membership operations |
348
+
349
+ Tests are run sequentially and share state. A global setup creates the test project with all required modules enabled, and a global teardown cleans up all test data.
350
+
351
+ ## Getting your API Key
352
+
353
+ 1. Log into your Redmine instance
354
+ 2. Go to My Account (usually `/my/account`)
355
+ 3. Find "API access key" in the sidebar
356
+ 4. Click "Show" or generate a new key
357
+
358
+ ## License
359
+
360
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { RedmineClient } from "./redmine/client.js";
4
+ import { createServer } from "./server.js";
5
+ import { resolveGroups, ALL_GROUPS } from "./tools/index.js";
6
+ function printHelp() {
7
+ console.log(`
8
+ Redmine MCP Server
9
+
10
+ Usage: redmine-mcp [options]
11
+
12
+ Options:
13
+ --url=<url> Redmine URL (or set REDMINE_URL)
14
+ --api-key=<key> API Key (or set REDMINE_API_KEY)
15
+ --tools=<groups> Comma-separated list of tool groups to enable
16
+ --exclude=<groups> Comma-separated list of tool groups to exclude
17
+ --help Show this help message
18
+
19
+ Tool Groups:
20
+ ${ALL_GROUPS.join(", ")}
21
+
22
+ Examples:
23
+ redmine-mcp --url=https://redmine.example.com --api-key=abc123
24
+ redmine-mcp --tools=core,metadata
25
+ redmine-mcp --exclude=wiki,files
26
+ `);
27
+ }
28
+ function parseArgs() {
29
+ const args = process.argv.slice(2);
30
+ let url;
31
+ let apiKey;
32
+ let toolsArg;
33
+ let excludeArg;
34
+ for (let i = 0; i < args.length; i++) {
35
+ const arg = args[i];
36
+ if (arg === "--help" || arg === "-h") {
37
+ printHelp();
38
+ process.exit(0);
39
+ }
40
+ if (arg === "--url" && args[i + 1]) {
41
+ url = args[++i];
42
+ }
43
+ else if (arg.startsWith("--url=")) {
44
+ url = arg.slice(6);
45
+ }
46
+ else if (arg === "--api-key" && args[i + 1]) {
47
+ apiKey = args[++i];
48
+ }
49
+ else if (arg.startsWith("--api-key=")) {
50
+ apiKey = arg.slice(10);
51
+ }
52
+ else if (arg === "--tools" && args[i + 1]) {
53
+ toolsArg = args[++i];
54
+ }
55
+ else if (arg.startsWith("--tools=")) {
56
+ toolsArg = arg.slice(8);
57
+ }
58
+ else if (arg === "--exclude" && args[i + 1]) {
59
+ excludeArg = args[++i];
60
+ }
61
+ else if (arg.startsWith("--exclude=")) {
62
+ excludeArg = arg.slice(10);
63
+ }
64
+ }
65
+ // Fallback to environment variables
66
+ url = url || process.env.REDMINE_URL;
67
+ apiKey = apiKey || process.env.REDMINE_API_KEY;
68
+ if (!url) {
69
+ console.error("Error: Redmine URL required. Use --url or set REDMINE_URL");
70
+ process.exit(1);
71
+ }
72
+ if (!apiKey) {
73
+ console.error("Error: API key required. Use --api-key or set REDMINE_API_KEY");
74
+ process.exit(1);
75
+ }
76
+ // Parse tool groups
77
+ const include = toolsArg ? toolsArg.split(",").map((s) => s.trim()).filter(Boolean) : undefined;
78
+ const exclude = excludeArg ? excludeArg.split(",").map((s) => s.trim()).filter(Boolean) : undefined;
79
+ let toolGroups;
80
+ try {
81
+ toolGroups = resolveGroups(include, exclude);
82
+ }
83
+ catch (err) {
84
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
85
+ process.exit(1);
86
+ }
87
+ return { url, apiKey, toolGroups };
88
+ }
89
+ async function main() {
90
+ const config = parseArgs();
91
+ const client = new RedmineClient(config.url, config.apiKey);
92
+ const server = createServer(client, config.toolGroups);
93
+ const transport = new StdioServerTransport();
94
+ await server.connect(transport);
95
+ }
96
+ main().catch((error) => {
97
+ console.error("Fatal error:", error);
98
+ process.exit(1);
99
+ });