planko-mcp-server 0.4.0 → 0.4.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/index.js +6 -4
- package/package.json +1 -1
- package/src/sanitize.js +37 -0
package/index.js
CHANGED
|
@@ -20,6 +20,7 @@ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
|
20
20
|
import { join } from 'node:path';
|
|
21
21
|
|
|
22
22
|
import { createApiClient } from './src/api.js';
|
|
23
|
+
import { isBlankValue, applyDueDateFallback } from './src/sanitize.js';
|
|
23
24
|
import {
|
|
24
25
|
blockNoteToMarkdown,
|
|
25
26
|
markdownToBlockNote,
|
|
@@ -633,9 +634,10 @@ const taskProps = {
|
|
|
633
634
|
function buildTaskBody(params) {
|
|
634
635
|
const body = {};
|
|
635
636
|
for (const [key, value] of Object.entries(params)) {
|
|
636
|
-
if (value
|
|
637
|
+
if (isBlankValue(value)) continue;
|
|
637
638
|
body[key] = value;
|
|
638
639
|
}
|
|
640
|
+
applyDueDateFallback(body);
|
|
639
641
|
if ('description' in body) {
|
|
640
642
|
body.description = markdownToDescription(body.description);
|
|
641
643
|
}
|
|
@@ -680,7 +682,7 @@ async function handleCreate(type, params, kindLabel) {
|
|
|
680
682
|
|
|
681
683
|
// Resolve projectName -> projectId via the API. When omitted, OMIT the key
|
|
682
684
|
// entirely so the backend applies the user's default project.
|
|
683
|
-
if (projectName) {
|
|
685
|
+
if (!isBlankValue(projectName)) {
|
|
684
686
|
body.projectId = await resolveProjectId(projectName);
|
|
685
687
|
}
|
|
686
688
|
|
|
@@ -885,10 +887,10 @@ async function buildListParams(type, params) {
|
|
|
885
887
|
const { projectName, ...rest } = params;
|
|
886
888
|
const out = { type };
|
|
887
889
|
for (const [key, value] of Object.entries(rest)) {
|
|
888
|
-
if (value
|
|
890
|
+
if (isBlankValue(value)) continue;
|
|
889
891
|
out[key] = value;
|
|
890
892
|
}
|
|
891
|
-
if (projectName) {
|
|
893
|
+
if (!isBlankValue(projectName)) {
|
|
892
894
|
out.projectId = await resolveProjectId(projectName);
|
|
893
895
|
}
|
|
894
896
|
return out;
|
package/package.json
CHANGED
package/src/sanitize.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Argument sanitization for MCP tool inputs.
|
|
3
|
+
*
|
|
4
|
+
* LLM tool-callers (especially GPT-class models) tend to fill EVERY schema
|
|
5
|
+
* field with placeholder/default values instead of omitting optional ones:
|
|
6
|
+
* empty strings, the all-zero ObjectId ("000000000000000000000000"), and
|
|
7
|
+
* empty arrays. Left untouched, a placeholder `projectId` makes the backend
|
|
8
|
+
* throw "Project not found", a placeholder `parentId` filters to a nonexistent
|
|
9
|
+
* parent (→ 0 results), and empty `tags`/`search` add noise. Treat all of
|
|
10
|
+
* these as "field omitted".
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export const ZERO_OBJECT_ID = '000000000000000000000000';
|
|
14
|
+
|
|
15
|
+
export function isBlankValue(value) {
|
|
16
|
+
if (value === undefined || value === null) return true;
|
|
17
|
+
if (typeof value === 'string') {
|
|
18
|
+
const trimmed = value.trim();
|
|
19
|
+
return trimmed === '' || trimmed === ZERO_OBJECT_ID;
|
|
20
|
+
}
|
|
21
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* LLM callers often put the date in `datePlain` and leave `dueDate` empty.
|
|
27
|
+
* The backend derives datePlain FROM dueDate but not the reverse, so a
|
|
28
|
+
* datePlain-only task ends up with dueDate=null and never appears on day/agenda
|
|
29
|
+
* views (it looks "not created"). Mirror datePlain -> dueDate in that case.
|
|
30
|
+
* Mutates and returns `body`.
|
|
31
|
+
*/
|
|
32
|
+
export function applyDueDateFallback(body) {
|
|
33
|
+
if (isBlankValue(body.dueDate) && !isBlankValue(body.datePlain)) {
|
|
34
|
+
body.dueDate = body.datePlain;
|
|
35
|
+
}
|
|
36
|
+
return body;
|
|
37
|
+
}
|