@fswap/mcp-vikunja 0.1.0 → 0.1.2

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
@@ -88,7 +88,7 @@ VIKUNJA_API_TOKEN = "tk_..."
88
88
  | `list_projects` | `GET /projects` | id, title, description, parent |
89
89
  | `get_project` | `GET /projects/{id}` | |
90
90
  | `create_project` | `PUT /projects` | optional parent project |
91
- | `list_tasks` | `GET /tasks/all` or `GET /projects/{id}/tasks` | open tasks by default; `filter`, `sortBy`, pagination |
91
+ | `list_tasks` | `GET /tasks` or `GET /projects/{id}/tasks` | open tasks by default; `assignedToMe`, `filter`, `sortBy`, pagination |
92
92
  | `get_task` | `GET /tasks/{id}` | full task incl. description, labels, assignees |
93
93
  | `create_task` | `PUT /projects/{id}/tasks` | title, description, dates, priority, labels |
94
94
  | `update_task` | `POST /tasks/{id}` | merges your changes onto the current task; `labelIds` replaces labels |
package/dist/index.js CHANGED
@@ -243,6 +243,7 @@ function summarizeTask(t) {
243
243
  projectId: t.project_id,
244
244
  identifier: t.identifier || null,
245
245
  labels: (t.labels ?? []).map((l) => l.title),
246
+ assignees: (t.assignees ?? []).map((u) => u.username),
246
247
  updated: t.updated
247
248
  };
248
249
  }
@@ -277,10 +278,11 @@ async function setLabels(vikunja, taskId, labelIds) {
277
278
  function registerTaskTools(server, vikunja, { allowDelete = false, defaultProjectId = null } = {}) {
278
279
  server.registerTool("list_tasks", {
279
280
  title: "List tasks",
280
- description: "List tasks, across all projects or within one project. Returns id, title, done, due date, priority and label names (no descriptions — use get_task). By default only open tasks are returned. For advanced queries pass a raw Vikunja `filter` string such as `done = false && due_date < now+7d` or `labels in 3, 5`.",
281
+ description: "List tasks, across all projects or within one project. Returns id, title, done, due date, priority, label names and assignee usernames (no descriptions — use get_task). By default only open tasks are returned. Set assignedToMe=true for the current user's tasks. For advanced queries pass a raw Vikunja `filter` string such as `done = false && due_date < now+7d`, `labels in 3, 5` or `assignees in alice`.",
281
282
  inputSchema: {
282
283
  projectId: z.number().int().optional().describe("Limit to this project (omit for all projects)"),
283
284
  includeDone: z.boolean().default(false).describe("Include completed tasks"),
285
+ assignedToMe: z.boolean().default(false).describe("Only tasks assigned to the authenticated user"),
284
286
  search: z.string().optional().describe("Full-text search in title/description"),
285
287
  filter: z.string().optional().describe("Raw Vikunja filter expression; overrides includeDone. Fields: done, due_date, priority, labels, assignees, project"),
286
288
  sortBy: z.enum([
@@ -296,9 +298,16 @@ function registerTaskTools(server, vikunja, { allowDelete = false, defaultProjec
296
298
  page: z.number().int().min(1).default(1),
297
299
  perPage: z.number().int().min(1).max(100).default(50)
298
300
  }
299
- }, guard(async ({ projectId, includeDone, search, filter, sortBy, orderBy, page, perPage }) => {
300
- const effectiveFilter = filter ?? (includeDone ? void 0 : "done = false");
301
- const path = projectId != null ? `/projects/${projectId}/tasks` : "/tasks/all";
301
+ }, guard(async ({ projectId, includeDone, assignedToMe, search, filter, sortBy, orderBy, page, perPage }) => {
302
+ const clauses = [];
303
+ if (filter) clauses.push(`(${filter})`);
304
+ else if (!includeDone) clauses.push("done = false");
305
+ if (assignedToMe) {
306
+ const me = await vikunja.get("/user");
307
+ clauses.push(`assignees in '${me.username}'`);
308
+ }
309
+ const effectiveFilter = clauses.length > 0 ? clauses.join(" && ") : void 0;
310
+ const path = projectId != null ? `/projects/${projectId}/tasks` : "/tasks";
302
311
  return ok((await vikunja.get(path, {
303
312
  s: search,
304
313
  filter: effectiveFilter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fswap/mcp-vikunja",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "MCP server for Vikunja — list, create, update and complete tasks from Claude",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,7 +10,7 @@
10
10
  "dist"
11
11
  ],
12
12
  "engines": {
13
- "node": ">=18"
13
+ "node": ">=20.12.0"
14
14
  },
15
15
  "scripts": {
16
16
  "build": "tsdown",