planko-mcp-server 0.4.0 → 0.4.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/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 } from './src/sanitize.js';
23
24
  import {
24
25
  blockNoteToMarkdown,
25
26
  markdownToBlockNote,
@@ -633,7 +634,7 @@ const taskProps = {
633
634
  function buildTaskBody(params) {
634
635
  const body = {};
635
636
  for (const [key, value] of Object.entries(params)) {
636
- if (value === undefined) continue;
637
+ if (isBlankValue(value)) continue;
637
638
  body[key] = value;
638
639
  }
639
640
  if ('description' in body) {
@@ -680,7 +681,7 @@ async function handleCreate(type, params, kindLabel) {
680
681
 
681
682
  // Resolve projectName -> projectId via the API. When omitted, OMIT the key
682
683
  // entirely so the backend applies the user's default project.
683
- if (projectName) {
684
+ if (!isBlankValue(projectName)) {
684
685
  body.projectId = await resolveProjectId(projectName);
685
686
  }
686
687
 
@@ -885,10 +886,10 @@ async function buildListParams(type, params) {
885
886
  const { projectName, ...rest } = params;
886
887
  const out = { type };
887
888
  for (const [key, value] of Object.entries(rest)) {
888
- if (value === undefined) continue;
889
+ if (isBlankValue(value)) continue;
889
890
  out[key] = value;
890
891
  }
891
- if (projectName) {
892
+ if (!isBlankValue(projectName)) {
892
893
  out.projectId = await resolveProjectId(projectName);
893
894
  }
894
895
  return out;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "planko-mcp-server",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "MCP server for syncing Planko tasks with local Markdown files",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,23 @@
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
+ }