Skip to content

Fix: LLM autoScheduled parameter handling — defensive JSON parsing and improved description #88

@devondragon

Description

@devondragon

Problem

LLMs interacting with this MCP server struggle with the oneOf schema for autoScheduled, which accepts both a string and an object. Two failure modes observed:

  1. JSON-stringified objects: LLMs serialize the object as a JSON string ('{"schedule":"Work Hours","startDate":"2026-03-05"}') instead of passing a native object — the server then tries to match the entire JSON blob as a schedule name, which fails.
  2. Ignored startDate: LLMs use the string shorthand and ignore startDate entirely because it's not a top-level param and the tool description/examples don't show it.

Solution

1. Defensive JSON parsing in parseAutoScheduledParam()

File: src/utils/parameterUtils.ts

In the string handling branch, before treating the string as a schedule name, check if it looks like a JSON object (startsWith('{')) and attempt to parse it. If parsing succeeds and the result is an object, return it directly. If parsing fails, fall through to treat the string as a schedule name as before.

2. Improved tool description for autoScheduled

File: src/tools/ToolDefinitions.ts

Update the description to:

  • Explicitly show both forms (string shorthand vs object)
  • Include startDate in the object example
  • Tell LLMs they MUST use the object form when the user specifies a start date

3. Unit tests for defensive JSON parsing

File: tests/parameterUtils.spec.ts

New test cases:

  • JSON-stringified object with schedule → parsed to object
  • JSON-stringified object with schedule + startDate → parsed to object
  • JSON-stringified object with schedule + deadlineType → parsed to object
  • Invalid JSON starting with { → treated as schedule name (graceful fallback)
  • JSON array string [...] → not caught by { check, treated as schedule name

Files Modified

  1. src/utils/parameterUtils.ts
  2. src/tools/ToolDefinitions.ts
  3. tests/parameterUtils.spec.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions