plaky-mcp 0.1.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) 2026 Pavle Aleksic
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,142 @@
1
+ # Plaky MCP Server
2
+
3
+ A [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the
4
+ [Plaky](https://plaky.com) project-management REST API to MCP-compatible AI clients
5
+ (Claude Desktop, Claude Code, Cursor, etc.).
6
+
7
+ It wraps the full Plaky public API surface — spaces, boards, items/subitems, fields,
8
+ comments, reactions, files, users and teams — as **26 well-described tools**.
9
+
10
+ ## Features
11
+
12
+ - **Workspace** — current user, list/get users (filter by email/status/type), list/get teams
13
+ - **Spaces & boards** — list/get spaces, list boards, get board structure (groups, fields, allowed values)
14
+ - **Items** — list (with view/parent/expand filters + pagination), get, create item or subitem, delete
15
+ - **Fields** — update one field or many at once, by field key or title, with per-type value formats
16
+ - **Comments** — list, create (incl. replies), update, delete, and set emoji reactions
17
+ - **Files** — list, get, upload (from a local path), rename/describe, delete, download
18
+ - Clean error reporting (status + API error body), 429 rate-limit awareness, 1-indexed pagination with `hasMore`.
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ npm install plaky-mcp
24
+ ```
25
+
26
+ Or run without installing globally:
27
+
28
+ ```bash
29
+ npx plaky-mcp
30
+ ```
31
+
32
+ You need a Plaky **API key** (Plaky → Profile settings → API). It is sent as the
33
+ `X-API-Key` header on every request.
34
+
35
+ ## Client configuration
36
+
37
+ ### Claude Desktop / Claude Code (`claude_desktop_config.json` or `.mcp.json`)
38
+
39
+ ```json
40
+ {
41
+ "mcpServers": {
42
+ "plaky": {
43
+ "command": "npx",
44
+ "args": ["-y", "plaky-mcp"],
45
+ "env": {
46
+ "PLAKY_API_KEY": "your-api-key"
47
+ }
48
+ }
49
+ }
50
+ }
51
+ ```
52
+
53
+ For Claude Code you can also run:
54
+
55
+ ```bash
56
+ claude mcp add plaky --env PLAKY_API_KEY=your-api-key -- npx -y plaky-mcp
57
+ ```
58
+
59
+ ### Cursor
60
+
61
+ Add to your MCP settings (`.cursor/mcp.json` or Cursor Settings → MCP):
62
+
63
+ ```json
64
+ {
65
+ "mcpServers": {
66
+ "plaky": {
67
+ "command": "npx",
68
+ "args": ["-y", "plaky-mcp"],
69
+ "env": {
70
+ "PLAKY_API_KEY": "your-api-key"
71
+ }
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ ## Development
78
+
79
+ ```bash
80
+ git clone https://github.com/pavlealeksic/plaky-mcp.git
81
+ cd plaky-mcp
82
+ npm install
83
+ npm run build
84
+ export PLAKY_API_KEY="your-api-key"
85
+ npm start
86
+ ```
87
+
88
+ ## Environment variables
89
+
90
+ | Variable | Required | Description |
91
+ | ---------------- | -------- | ------------------------------------------------------ |
92
+ | `PLAKY_API_KEY` | yes | Plaky API key, sent as `X-API-Key`. |
93
+ | `PLAKY_BASE_URL` | no | Override the API base URL (default `https://api.plaky.com`). |
94
+
95
+ ## Tool reference
96
+
97
+ All tools are prefixed `plaky_`. IDs are integers. Typical flow:
98
+ `plaky_list_spaces` → `plaky_list_boards` → `plaky_get_board` (to learn field keys
99
+ and allowed values) → `plaky_list_items` / `plaky_create_item` /
100
+ `plaky_update_item_fields`.
101
+
102
+ | Tool | Description |
103
+ | --- | --- |
104
+ | `plaky_get_current_user` | The API key's owner (verify auth). |
105
+ | `plaky_list_users` / `plaky_list_teams` / `plaky_get_team` | Workspace members and teams. |
106
+ | `plaky_list_spaces` / `plaky_get_space` | Spaces (optionally expand boards). |
107
+ | `plaky_list_boards` / `plaky_get_board` | Boards and board structure. |
108
+ | `plaky_list_items` / `plaky_get_item` / `plaky_list_subitems` | Read items. |
109
+ | `plaky_create_item` / `plaky_delete_item` | Create item/subitem; delete item. |
110
+ | `plaky_update_item_field` / `plaky_update_item_fields` | Change one / many field values. |
111
+ | `plaky_list_item_comments` / `plaky_create_item_comment` / `plaky_update_item_comment` / `plaky_delete_item_comment` | Comments. |
112
+ | `plaky_set_comment_reactions` | Set the caller's emoji reactions on a comment. |
113
+ | `plaky_list_item_files` / `plaky_get_item_file` / `plaky_upload_item_file` / `plaky_update_item_file` / `plaky_delete_item_file` / `plaky_download_item_file` | File attachments. |
114
+
115
+ ### Field value formats
116
+
117
+ When setting `fields` (on create/update), keys are field **keys** (`"status-1"`) or
118
+ **titles** (`"Status"`). Values by type:
119
+
120
+ | Type | Example |
121
+ | --- | --- |
122
+ | String / Rich text | `"some text"` |
123
+ | Number | `13.4` |
124
+ | Date | `"2026-01-02T18:10:15.254Z"` |
125
+ | Timeline | `{ "start": "...", "end": "..." }` |
126
+ | Status | `"To do"` or label id `"1"` |
127
+ | Tag | `["Product", "HR"]` (titles or ids) |
128
+ | Link | `"https://..."` or `{ "url": "...", "displayText": "..." }` |
129
+ | Person | `{ "users": [{ "id": "1" }, { "email": "x@y.com" }], "teams": [{ "id": 1 }] }` |
130
+
131
+ ```bash
132
+ npm run dev # tsx watch on src/index.ts
133
+ npm run build # tsc -> dist/
134
+ ```
135
+
136
+ ## Notes
137
+
138
+ - Rate limit: **200 requests / user / minute**; exceeding it returns HTTP 429.
139
+
140
+ ## License
141
+
142
+ MIT
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Thin HTTP client for the Plaky public REST API.
3
+ *
4
+ * Auth: every request carries the `X-API-Key` header.
5
+ * Base URL: https://api.plaky.com
6
+ * Rate limit: 200 requests per user per minute (429 TOO_MANY_REQUESTS on excess).
7
+ */
8
+ export interface PlakyClientOptions {
9
+ apiKey: string;
10
+ baseUrl?: string;
11
+ }
12
+ export interface RequestOptions {
13
+ /** Query parameters. Arrays are serialized as comma-separated values. Null/undefined are skipped. */
14
+ query?: Record<string, unknown>;
15
+ /** JSON request body. */
16
+ body?: unknown;
17
+ /** A pre-built multipart body (FormData). When set, `body` is ignored and no JSON Content-Type is sent. */
18
+ form?: FormData;
19
+ /** When true, return the raw Response instead of parsing (used for binary downloads). */
20
+ raw?: boolean;
21
+ }
22
+ /** Error thrown for any non-2xx response, carrying the parsed body for diagnostics. */
23
+ export declare class PlakyError extends Error {
24
+ readonly status: number;
25
+ readonly statusText: string;
26
+ readonly body: unknown;
27
+ readonly method: string;
28
+ readonly path: string;
29
+ constructor(status: number, statusText: string, body: unknown, method: string, path: string);
30
+ }
31
+ export declare class PlakyClient {
32
+ private readonly apiKey;
33
+ private readonly baseUrl;
34
+ constructor(opts: PlakyClientOptions);
35
+ private buildUrl;
36
+ request<T = unknown>(method: string, path: string, options?: RequestOptions): Promise<T>;
37
+ }
package/dist/client.js ADDED
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Thin HTTP client for the Plaky public REST API.
3
+ *
4
+ * Auth: every request carries the `X-API-Key` header.
5
+ * Base URL: https://api.plaky.com
6
+ * Rate limit: 200 requests per user per minute (429 TOO_MANY_REQUESTS on excess).
7
+ */
8
+ /** Error thrown for any non-2xx response, carrying the parsed body for diagnostics. */
9
+ export class PlakyError extends Error {
10
+ status;
11
+ statusText;
12
+ body;
13
+ method;
14
+ path;
15
+ constructor(status, statusText, body, method, path) {
16
+ super(`Plaky API ${status} ${statusText} on ${method} ${path}: ${stringifyBody(body)}`);
17
+ this.status = status;
18
+ this.statusText = statusText;
19
+ this.body = body;
20
+ this.method = method;
21
+ this.path = path;
22
+ this.name = "PlakyError";
23
+ }
24
+ }
25
+ function stringifyBody(body) {
26
+ if (body == null)
27
+ return "";
28
+ if (typeof body === "string")
29
+ return body;
30
+ try {
31
+ return JSON.stringify(body);
32
+ }
33
+ catch {
34
+ return String(body);
35
+ }
36
+ }
37
+ export class PlakyClient {
38
+ apiKey;
39
+ baseUrl;
40
+ constructor(opts) {
41
+ if (!opts.apiKey) {
42
+ throw new Error("PlakyClient requires an apiKey.");
43
+ }
44
+ this.apiKey = opts.apiKey;
45
+ this.baseUrl = (opts.baseUrl ?? "https://api.plaky.com").replace(/\/+$/, "");
46
+ }
47
+ buildUrl(path, query) {
48
+ const url = new URL(this.baseUrl + path);
49
+ if (query) {
50
+ for (const [key, value] of Object.entries(query)) {
51
+ if (value == null)
52
+ continue;
53
+ if (Array.isArray(value)) {
54
+ if (value.length === 0)
55
+ continue;
56
+ url.searchParams.set(key, value.join(","));
57
+ }
58
+ else {
59
+ url.searchParams.set(key, String(value));
60
+ }
61
+ }
62
+ }
63
+ return url.toString();
64
+ }
65
+ async request(method, path, options = {}) {
66
+ const url = this.buildUrl(path, options.query);
67
+ const headers = {
68
+ "X-API-Key": this.apiKey,
69
+ Accept: "application/json",
70
+ };
71
+ let body;
72
+ if (options.form) {
73
+ body = options.form; // browser/undici sets the multipart boundary Content-Type automatically
74
+ }
75
+ else if (options.body !== undefined) {
76
+ headers["Content-Type"] = "application/json";
77
+ body = JSON.stringify(options.body);
78
+ }
79
+ const res = await fetch(url, { method, headers, body });
80
+ if (options.raw) {
81
+ if (!res.ok) {
82
+ throw new PlakyError(res.status, res.statusText, await safeParse(res), method, path);
83
+ }
84
+ return res;
85
+ }
86
+ const parsed = await safeParse(res);
87
+ if (!res.ok) {
88
+ if (res.status === 429) {
89
+ throw new PlakyError(429, "Too Many Requests", parsed ?? "Rate limit exceeded (200 requests/user/minute). Retry after a short backoff.", method, path);
90
+ }
91
+ throw new PlakyError(res.status, res.statusText, parsed, method, path);
92
+ }
93
+ return parsed;
94
+ }
95
+ }
96
+ async function safeParse(res) {
97
+ const text = await res.text();
98
+ if (!text)
99
+ return null;
100
+ const contentType = res.headers.get("content-type") ?? "";
101
+ if (contentType.includes("application/json")) {
102
+ try {
103
+ return JSON.parse(text);
104
+ }
105
+ catch {
106
+ return text;
107
+ }
108
+ }
109
+ return text;
110
+ }
111
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Plaky MCP server.
4
+ *
5
+ * Exposes the Plaky public REST API (https://docs.plaky.com) as Model Context
6
+ * Protocol tools over stdio. Configure with the PLAKY_API_KEY environment variable.
7
+ */
8
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,436 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Plaky MCP server.
4
+ *
5
+ * Exposes the Plaky public REST API (https://docs.plaky.com) as Model Context
6
+ * Protocol tools over stdio. Configure with the PLAKY_API_KEY environment variable.
7
+ */
8
+ import { readFile } from "node:fs/promises";
9
+ import { writeFile } from "node:fs/promises";
10
+ import { basename } from "node:path";
11
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
12
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
13
+ import { z } from "zod";
14
+ import { PlakyClient, PlakyError } from "./client.js";
15
+ const apiKey = process.env.PLAKY_API_KEY;
16
+ if (!apiKey) {
17
+ console.error("[plaky-mcp] Missing PLAKY_API_KEY environment variable. " +
18
+ "Generate an API key in Plaky (Profile settings -> API) and set PLAKY_API_KEY.");
19
+ process.exit(1);
20
+ }
21
+ const client = new PlakyClient({
22
+ apiKey,
23
+ baseUrl: process.env.PLAKY_BASE_URL,
24
+ });
25
+ const server = new McpServer({
26
+ name: "plaky-mcp",
27
+ version: "0.1.0",
28
+ });
29
+ function ok(data) {
30
+ const text = typeof data === "string" ? data : JSON.stringify(data, null, 2);
31
+ return { content: [{ type: "text", text: text || "(empty response)" }] };
32
+ }
33
+ function fail(error) {
34
+ let message;
35
+ if (error instanceof PlakyError) {
36
+ message =
37
+ `Plaky API error ${error.status} (${error.statusText}) on ${error.method} ${error.path}.\n` +
38
+ `Details: ${typeof error.body === "string" ? error.body : JSON.stringify(error.body, null, 2)}`;
39
+ }
40
+ else if (error instanceof Error) {
41
+ message = `${error.name}: ${error.message}`;
42
+ }
43
+ else {
44
+ message = `Unknown error: ${String(error)}`;
45
+ }
46
+ return { content: [{ type: "text", text: message }], isError: true };
47
+ }
48
+ /** Register a tool with shared try/catch error handling. */
49
+ function tool(name, config, handler) {
50
+ server.registerTool(name, {
51
+ title: config.title,
52
+ description: config.description,
53
+ inputSchema: config.inputSchema ?? {},
54
+ }, async (args) => {
55
+ try {
56
+ return await handler(args ?? {});
57
+ }
58
+ catch (error) {
59
+ return fail(error);
60
+ }
61
+ });
62
+ }
63
+ // Reusable schema fragments
64
+ const spaceId = z.number().int().describe("Unique space identifier.");
65
+ const boardId = z.number().int().describe("Unique board identifier.");
66
+ const itemId = z.number().int().describe("Unique item identifier.");
67
+ const page = z
68
+ .number()
69
+ .int()
70
+ .min(1)
71
+ .optional()
72
+ .describe("Page number (1-indexed). Omit for the first page.");
73
+ const pageSize = z
74
+ .number()
75
+ .int()
76
+ .min(1)
77
+ .optional()
78
+ .describe("Number of results per page. Omit for the API default.");
79
+ const itemExpand = z
80
+ .array(z.enum(["space", "board", "group", "createdBy", "parent", "subscriptions", "fields"]))
81
+ .optional()
82
+ .describe("Relationships to expand into full objects instead of bare IDs, e.g. [\"fields\",\"group\"].");
83
+ const base = "/v1/public";
84
+ /* -------------------------------------------------------------------------- */
85
+ /* Workspace: users & teams */
86
+ /* -------------------------------------------------------------------------- */
87
+ tool("plaky_get_current_user", {
88
+ title: "Get current user",
89
+ description: "Get the user that owns the API key making the request. Useful for verifying authentication and discovering the caller's user id.",
90
+ }, async () => ok(await client.request("GET", `${base}/users/me`)));
91
+ tool("plaky_list_users", {
92
+ title: "List workspace users",
93
+ description: "List users in the workspace. Optionally filter by emails, status, or membership type. Supports pagination.",
94
+ inputSchema: {
95
+ emails: z
96
+ .array(z.string())
97
+ .optional()
98
+ .describe("Filter to users with these email addresses."),
99
+ status: z
100
+ .enum(["ACTIVE", "PENDING", "INACTIVE"])
101
+ .optional()
102
+ .describe("Filter by account status."),
103
+ type: z
104
+ .enum(["OWNER", "ADMIN", "MEMBER", "VIEWER"])
105
+ .optional()
106
+ .describe("Filter by workspace membership type."),
107
+ page,
108
+ pageSize,
109
+ },
110
+ }, async (a) => ok(await client.request("GET", `${base}/users`, {
111
+ query: { emails: a.emails, status: a.status, type: a.type, page: a.page, pageSize: a.pageSize },
112
+ })));
113
+ tool("plaky_list_teams", {
114
+ title: "List workspace teams",
115
+ description: "List all teams in the workspace. Supports pagination.",
116
+ inputSchema: { page, pageSize },
117
+ }, async (a) => ok(await client.request("GET", `${base}/teams`, { query: { page: a.page, pageSize: a.pageSize } })));
118
+ tool("plaky_get_team", {
119
+ title: "Get team by id",
120
+ description: "Get a single team by its id.",
121
+ inputSchema: { teamId: z.number().int().describe("Unique team identifier.") },
122
+ }, async (a) => ok(await client.request("GET", `${base}/teams/${a.teamId}`)));
123
+ /* -------------------------------------------------------------------------- */
124
+ /* Spaces & boards */
125
+ /* -------------------------------------------------------------------------- */
126
+ tool("plaky_list_spaces", {
127
+ title: "List spaces",
128
+ description: "List spaces in the workspace. Spaces are top-level containers that hold boards. Use expand=[\"board\"] to include full board objects.",
129
+ inputSchema: {
130
+ expand: z
131
+ .array(z.enum(["board"]))
132
+ .optional()
133
+ .describe("Set to [\"board\"] to include full board objects instead of IDs."),
134
+ page,
135
+ pageSize,
136
+ },
137
+ }, async (a) => ok(await client.request("GET", `${base}/spaces`, { query: { expand: a.expand, page: a.page, pageSize: a.pageSize } })));
138
+ tool("plaky_get_space", {
139
+ title: "Get space by id",
140
+ description: "Get a single space by its id.",
141
+ inputSchema: {
142
+ spaceId,
143
+ expand: z
144
+ .array(z.enum(["board"]))
145
+ .optional()
146
+ .describe("Set to [\"board\"] to include full board objects instead of IDs."),
147
+ },
148
+ }, async (a) => ok(await client.request("GET", `${base}/spaces/${a.spaceId}`, { query: { expand: a.expand } })));
149
+ tool("plaky_list_boards", {
150
+ title: "List boards in a space",
151
+ description: "List the boards contained in a given space. Supports pagination.",
152
+ inputSchema: { spaceId, page, pageSize },
153
+ }, async (a) => ok(await client.request("GET", `${base}/spaces/${a.spaceId}/boards`, {
154
+ query: { page: a.page, pageSize: a.pageSize },
155
+ })));
156
+ tool("plaky_get_board", {
157
+ title: "Get board by id",
158
+ description: "Get a single board by id, including its structure: groups, field/column definitions and their configurations (status labels, tag labels, etc.). Read this before creating or updating items so you know the available field keys/titles and allowed values.",
159
+ inputSchema: { spaceId, boardId },
160
+ }, async (a) => ok(await client.request("GET", `${base}/spaces/${a.spaceId}/boards/${a.boardId}`)));
161
+ /* -------------------------------------------------------------------------- */
162
+ /* Items */
163
+ /* -------------------------------------------------------------------------- */
164
+ tool("plaky_list_items", {
165
+ title: "List board items",
166
+ description: "List items (rows) on a board, with optional filtering. Supports pagination; the response includes a `hasMore` flag indicating whether more pages exist.",
167
+ inputSchema: {
168
+ spaceId,
169
+ boardId,
170
+ boardViewId: z.number().int().optional().describe("Restrict to a specific board view's filtering/sorting."),
171
+ parentId: z
172
+ .number()
173
+ .int()
174
+ .optional()
175
+ .describe("Return subitems of this parent item id instead of top-level items."),
176
+ subitemsBehaviour: z
177
+ .enum(["INCLUDE", "EXCLUDE", "EMBED"])
178
+ .optional()
179
+ .describe("How subitems are treated: INCLUDE (default), EXCLUDE, or EMBED nested under their parent."),
180
+ expand: itemExpand,
181
+ page,
182
+ pageSize,
183
+ },
184
+ }, async (a) => ok(await client.request("GET", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items`, {
185
+ query: {
186
+ boardViewId: a.boardViewId,
187
+ parentId: a.parentId,
188
+ subitemsBehaviour: a.subitemsBehaviour,
189
+ expand: a.expand,
190
+ page: a.page,
191
+ pageSize: a.pageSize,
192
+ },
193
+ })));
194
+ tool("plaky_get_item", {
195
+ title: "Get item by id",
196
+ description: "Get a single item by id, including its field values.",
197
+ inputSchema: { spaceId, boardId, itemId, expand: itemExpand },
198
+ }, async (a) => ok(await client.request("GET", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}`, {
199
+ query: { expand: a.expand },
200
+ })));
201
+ tool("plaky_list_subitems", {
202
+ title: "List subitems of an item",
203
+ description: "List the subitems nested under a given item. Supports pagination.",
204
+ inputSchema: { spaceId, boardId, itemId, expand: itemExpand, page, pageSize },
205
+ }, async (a) => ok(await client.request("GET", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/sub-items`, { query: { expand: a.expand, page: a.page, pageSize: a.pageSize } })));
206
+ tool("plaky_create_item", {
207
+ title: "Create an item or subitem",
208
+ description: "Create a new item (row) on a board, or a subitem when `parentId` is set. " +
209
+ "Place it in a group via `groupId` or `groupTitle` (defaults to the first group). " +
210
+ "Set initial field values via `fields`: an object keyed by field key (e.g. \"status-1\") or field title (e.g. \"Status\"). " +
211
+ "Value formats by field type — String/RichText: \"text\"; Number: 13.4; Date: \"2026-01-02T18:10:15.254Z\"; " +
212
+ "Timeline: {start, end}; Status: \"To do\" or label id \"1\"; Tag: [\"Product\",\"HR\"] or ids; " +
213
+ "Link: \"https://...\" or {url, displayText}; Person: {users:[{id}|{email}], teams:[{id}|{title}]}. " +
214
+ "Call plaky_get_board first to discover available fields and allowed values.",
215
+ inputSchema: {
216
+ spaceId,
217
+ boardId,
218
+ title: z.string().max(255).optional().describe("Item title. Defaults to \"New Item\" / \"New Subitem\"."),
219
+ parentId: z
220
+ .number()
221
+ .int()
222
+ .optional()
223
+ .describe("If set, creates a subitem under this parent item id instead of a top-level item."),
224
+ groupId: z.number().int().optional().describe("Id of the group to create the item in."),
225
+ groupTitle: z
226
+ .string()
227
+ .optional()
228
+ .describe("Title of the group to create the item in (used if groupId is omitted)."),
229
+ fields: z
230
+ .record(z.any())
231
+ .optional()
232
+ .describe("Initial field values keyed by field key or title. See tool description for value formats."),
233
+ },
234
+ }, async (a) => ok(await client.request("POST", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items`, {
235
+ body: {
236
+ title: a.title,
237
+ parentId: a.parentId,
238
+ groupId: a.groupId,
239
+ groupTitle: a.groupTitle,
240
+ fields: a.fields,
241
+ },
242
+ })));
243
+ tool("plaky_delete_item", {
244
+ title: "Delete an item",
245
+ description: "Permanently delete an item (and its subitems) by id. This cannot be undone.",
246
+ inputSchema: { spaceId, boardId, itemId },
247
+ }, async (a) => ok(await client.request("DELETE", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}`)));
248
+ tool("plaky_update_item_field", {
249
+ title: "Update a single item field value",
250
+ description: "Change the value of one field on an item, identified by the field key or title (`itemFieldKey`). " +
251
+ "The `value` format depends on the field type — String/RichText: \"text\"; Number: 13.4; " +
252
+ "Date: \"2026-01-02T18:10:15.254Z\"; Timeline: {start, end}; Status: \"To do\" or \"1\"; " +
253
+ "Tag: [\"Product\",\"HR\"]; Link: \"https://...\" or {url, displayText}; " +
254
+ "Person: {users:[{id}|{email}], teams:[{id}|{title}]}.",
255
+ inputSchema: {
256
+ spaceId,
257
+ boardId,
258
+ itemId,
259
+ itemFieldKey: z.string().describe("Field key (e.g. \"status-1\") or field title (e.g. \"Status\")."),
260
+ value: z.any().describe("New field value. Format depends on the field type (see description)."),
261
+ },
262
+ }, async (a) => ok(await client.request("PATCH", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/fields/${encodeURIComponent(a.itemFieldKey)}`, { body: { value: a.value } })));
263
+ tool("plaky_update_item_fields", {
264
+ title: "Update multiple item field values",
265
+ description: "Change several field values on an item in one request. `fields` is an object keyed by field key or title, " +
266
+ "with values following the same per-type formats as plaky_create_item (e.g. {\"Status\":\"Done\", \"number-1\":42}).",
267
+ inputSchema: {
268
+ spaceId,
269
+ boardId,
270
+ itemId,
271
+ fields: z
272
+ .record(z.any())
273
+ .describe("Object mapping field key/title to new value. See plaky_create_item for value formats."),
274
+ },
275
+ }, async (a) => ok(await client.request("PATCH", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/fields`, { body: a.fields })));
276
+ /* -------------------------------------------------------------------------- */
277
+ /* Comments & reactions */
278
+ /* -------------------------------------------------------------------------- */
279
+ tool("plaky_list_item_comments", {
280
+ title: "List item comments",
281
+ description: "List all comments on an item, including replies and reaction details.",
282
+ inputSchema: { spaceId, boardId, itemId },
283
+ }, async (a) => ok(await client.request("GET", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/comments`)));
284
+ tool("plaky_create_item_comment", {
285
+ title: "Create item comment",
286
+ description: "Add a comment to an item. Set `repliesToId` to post the comment as a reply to an existing comment.",
287
+ inputSchema: {
288
+ spaceId,
289
+ boardId,
290
+ itemId,
291
+ text: z.string().min(1).describe("Comment text."),
292
+ repliesToId: z.number().int().optional().describe("Id of the comment this is a reply to."),
293
+ },
294
+ }, async (a) => ok(await client.request("POST", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/comments`, { body: { text: a.text, repliesToId: a.repliesToId } })));
295
+ tool("plaky_update_item_comment", {
296
+ title: "Update item comment",
297
+ description: "Edit the text of an existing comment.",
298
+ inputSchema: {
299
+ spaceId,
300
+ boardId,
301
+ itemId,
302
+ itemCommentId: z.number().int().describe("Unique comment identifier."),
303
+ text: z.string().min(1).describe("New comment text."),
304
+ repliesToId: z.number().int().optional().describe("Id of the comment this is a reply to."),
305
+ },
306
+ }, async (a) => ok(await client.request("PUT", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/comments/${a.itemCommentId}`, { body: { text: a.text, repliesToId: a.repliesToId } })));
307
+ tool("plaky_delete_item_comment", {
308
+ title: "Delete item comment",
309
+ description: "Permanently delete a comment by id.",
310
+ inputSchema: {
311
+ spaceId,
312
+ boardId,
313
+ itemId,
314
+ itemCommentId: z.number().int().describe("Unique comment identifier."),
315
+ },
316
+ }, async (a) => ok(await client.request("DELETE", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/comments/${a.itemCommentId}`)));
317
+ tool("plaky_set_comment_reactions", {
318
+ title: "Set comment reactions",
319
+ description: "Set the authenticated user's reactions on a comment. This OVERRIDES any existing reactions by the caller; " +
320
+ "pass an empty array to remove all of them. Each reaction is an emoji's unicode codepoint without the \"U+\" " +
321
+ "prefix (case-insensitive) — e.g. \"1f44d\" (thumbs up), \"2705\" (check mark), \"2764\" (heart).",
322
+ inputSchema: {
323
+ spaceId,
324
+ boardId,
325
+ itemId,
326
+ itemCommentId: z.number().int().describe("Unique comment identifier."),
327
+ reactions: z
328
+ .array(z.string())
329
+ .describe("Emoji unicode codepoints (no \"U+\" prefix), e.g. [\"1f44d\"]. Empty array removes all."),
330
+ },
331
+ }, async (a) => ok(await client.request("PUT", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/comments/${a.itemCommentId}/reactions`, { body: { reactions: a.reactions.map((value) => ({ value })) } })));
332
+ /* -------------------------------------------------------------------------- */
333
+ /* Files */
334
+ /* -------------------------------------------------------------------------- */
335
+ tool("plaky_list_item_files", {
336
+ title: "List item files",
337
+ description: "List the files attached to an item.",
338
+ inputSchema: { spaceId, boardId, itemId },
339
+ }, async (a) => ok(await client.request("GET", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/files`)));
340
+ tool("plaky_get_item_file", {
341
+ title: "Get item file details",
342
+ description: "Get metadata for a single file attached to an item.",
343
+ inputSchema: {
344
+ spaceId,
345
+ boardId,
346
+ itemId,
347
+ itemFileId: z.number().int().describe("Unique item file identifier."),
348
+ },
349
+ }, async (a) => ok(await client.request("GET", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/files/${a.itemFileId}`)));
350
+ tool("plaky_upload_item_file", {
351
+ title: "Upload a file to an item",
352
+ description: "Upload a local file and attach it to an item. Provide the absolute path to a file on the machine running this MCP server.",
353
+ inputSchema: {
354
+ spaceId,
355
+ boardId,
356
+ itemId,
357
+ filePath: z.string().describe("Absolute path to the local file to upload."),
358
+ fileName: z
359
+ .string()
360
+ .optional()
361
+ .describe("Optional name to store the file as (defaults to the local file name)."),
362
+ },
363
+ }, async (a) => {
364
+ const buffer = await readFile(a.filePath);
365
+ const form = new FormData();
366
+ const name = a.fileName ?? basename(a.filePath);
367
+ form.append("file", new Blob([buffer]), name);
368
+ return ok(await client.request("POST", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/files`, { form }));
369
+ });
370
+ tool("plaky_update_item_file", {
371
+ title: "Update item file metadata",
372
+ description: "Rename a file or change its description. The original file extension/type is preserved regardless of the name given.",
373
+ inputSchema: {
374
+ spaceId,
375
+ boardId,
376
+ itemId,
377
+ itemFileId: z.number().int().describe("Unique item file identifier."),
378
+ name: z.string().min(1).max(255).describe("New file name."),
379
+ description: z.string().max(255).optional().describe("New file description."),
380
+ },
381
+ }, async (a) => ok(await client.request("PUT", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/files/${a.itemFileId}`, { body: { name: a.name, description: a.description } })));
382
+ tool("plaky_delete_item_file", {
383
+ title: "Delete item file",
384
+ description: "Permanently delete a file attached to an item.",
385
+ inputSchema: {
386
+ spaceId,
387
+ boardId,
388
+ itemId,
389
+ itemFileId: z.number().int().describe("Unique item file identifier."),
390
+ },
391
+ }, async (a) => ok(await client.request("DELETE", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/files/${a.itemFileId}`)));
392
+ tool("plaky_download_item_file", {
393
+ title: "Download item file",
394
+ description: "Download a file attached to an item. If the API returns JSON (e.g. a presigned download URL) that is returned directly. " +
395
+ "If it returns binary content, provide `savePath` to write it to disk; the tool then returns the saved path and size. " +
396
+ "Binary content is never streamed into the conversation.",
397
+ inputSchema: {
398
+ spaceId,
399
+ boardId,
400
+ itemId,
401
+ itemFileId: z.number().int().describe("Unique item file identifier."),
402
+ savePath: z
403
+ .string()
404
+ .optional()
405
+ .describe("Absolute path to write the downloaded bytes to (required if the API returns raw file content)."),
406
+ },
407
+ }, async (a) => {
408
+ const res = (await client.request("GET", `${base}/spaces/${a.spaceId}/boards/${a.boardId}/items/${a.itemId}/files/${a.itemFileId}/download`, { raw: true }));
409
+ const contentType = res.headers.get("content-type") ?? "";
410
+ if (contentType.includes("application/json")) {
411
+ return ok(await res.json());
412
+ }
413
+ if (contentType.startsWith("text/")) {
414
+ return ok(await res.text());
415
+ }
416
+ const bytes = Buffer.from(await res.arrayBuffer());
417
+ if (!a.savePath) {
418
+ return fail(new Error(`File is binary (${contentType || "unknown type"}, ${bytes.length} bytes). ` +
419
+ `Re-run with a 'savePath' to save it to disk.`));
420
+ }
421
+ await writeFile(a.savePath, bytes);
422
+ return ok({ saved: a.savePath, bytes: bytes.length, contentType: contentType || null });
423
+ });
424
+ /* -------------------------------------------------------------------------- */
425
+ /* Bootstrap */
426
+ /* -------------------------------------------------------------------------- */
427
+ async function main() {
428
+ const transport = new StdioServerTransport();
429
+ await server.connect(transport);
430
+ console.error("[plaky-mcp] server running on stdio");
431
+ }
432
+ main().catch((error) => {
433
+ console.error("[plaky-mcp] fatal:", error);
434
+ process.exit(1);
435
+ });
436
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "plaky-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Model Context Protocol (MCP) server for the Plaky project-management API",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "bin": {
15
+ "plaky-mcp": "dist/index.js"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md",
20
+ "LICENSE"
21
+ ],
22
+ "author": "Pavle Aleksic <pavlealeksic@live.com>",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/pavlealeksic/plaky-mcp.git"
26
+ },
27
+ "homepage": "https://github.com/pavlealeksic/plaky-mcp#readme",
28
+ "bugs": {
29
+ "url": "https://github.com/pavlealeksic/plaky-mcp/issues"
30
+ },
31
+ "scripts": {
32
+ "build": "tsc",
33
+ "start": "node dist/index.js",
34
+ "dev": "tsx watch src/index.ts",
35
+ "prepublishOnly": "npm run build"
36
+ },
37
+ "keywords": [
38
+ "mcp",
39
+ "model-context-protocol",
40
+ "plaky",
41
+ "project-management",
42
+ "llm",
43
+ "ai"
44
+ ],
45
+ "license": "MIT",
46
+ "engines": {
47
+ "node": ">=18.18"
48
+ },
49
+ "dependencies": {
50
+ "@modelcontextprotocol/sdk": "^1.29.0",
51
+ "zod": "^3.25.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^22.10.0",
55
+ "tsx": "^4.19.2",
56
+ "typescript": "^5.7.2"
57
+ }
58
+ }