Skip to content

Object of type datetime is not JSON serializable #13

@paulhugel

Description

@paulhugel

MCP-Dataverse Bug Report

Context

  • Environment: Apple Silicon M4
Image Image

Mac mini, Jan.app, Visual Studio Code with Codex, GitHub Copilot, GitHub Copilot extensions enabled.

  • Goal: Connect to Dataverse MCP server (https://mcp.dataverse.org/sse) via Jan and VS Code.

Configuration

Jan.app (working config)

{
  "command": "npx",
  "args": ["-y", "mcp-remote", "https://mcp.dataverse.org/sse", "--transport", "sse-only"],
  "env": {},
  "active": true
}

VS Code (settings.json)

{
  "mcp": {
    "servers": {
      "mcp-dataverse": {
        "type": "sse",
        "url": "https://mcp.dataverse.org/sse"
      }
    }
  }
}

Problem

When invoking get_croissant_record with a DOI (e.g., 10.7910/DVN/RI9JFU), the server throws:

Object of type datetime is not JSON serializable

Root Cause

  • The mcp-dataverse server code returns raw Python datetime objects in responses.
  • JSON has no native datetime type, so serialization fails.

Fix (Server-Side)

Patch the Python code in mcp-dataverse to serialize datetime objects:

import datetime, json

def _json_default(o):
    if isinstance(o, (datetime.datetime, datetime.date)):
        return o.isoformat()
    return str(o)

# Example usage when sending tool results
json.dumps(payload, default=_json_default, ensure_ascii=False)

Notes

  • This bug is inside the MCP server, not in Jan.app or VS Code configuration.
  • Hosted endpoint (https://mcp.dataverse.org/sse) cannot be patched by end users. Only maintainers can fix it.
  • Workaround: Run a local clone of mcp-dataverse, apply the patch, and register that server in Jan or VS Code.

Status

  • Jan.app: Successfully connects via mcp-remote with --transport sse-only.
  • Jan.app: Successfully lists 8 tools available
  • VS Code: Can register MCP server, but same datetime serialization bug will appear until server is patched.

New Evidence (SSE + curl Reproduction)

The issue was reproduced end-to-end using plain curl over SSE. This confirms the problems are entirely server-side.

How to Reproduce

  1. Open SSE stream (Terminal A):
curl -N -H "Accept: text/event-stream" https://mcp.dataverse.org/sse

This returns an endpoint with a session id, e.g.:

event: endpoint
data: /messages/?session_id=0e4fd22090504f7999724c944acb7e6b
  1. In a second terminal (Terminal B), send requests to that exact endpoint:
curl -sS -X POST 'https://mcp.dataverse.org/messages/?session_id=0e4fd22090504f7999724c944acb7e6b' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":"1","method":"initialize","params":{"protocolVersion":"1.0","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'

curl -sS -X POST 'https://mcp.dataverse.org/messages/?session_id=0e4fd22090504f7999724c944acb7e6b' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":"2","method":"tools/list","params":{}}'

Responses to POSTs are 202 Accepted; actual results appear in the SSE stream (Terminal A).

Observed SSE Results

  • tools/list returned the following tools (abridged):
{"jsonrpc":"2.0","id":"2","result":{"tools":[
  {"name":"fetch","description":"Fetches a website...","endpoint":"/fetch"},
  {"name":"onboarding","description":"Get the onboarding instruction...","endpoint":"/onboarding"},
  {"name":"get_croissant_record","description":"Convert a dataset to Croissant ML format...","endpoint":"/get_croissant_record"},
  {"name":"datatool","description":"Process a file in a dataset...","endpoint":"/tools/datatool"},
  {"name":"overview","endpoint":"/overview"},
  {"name":"overview_datasets","endpoint":"/overview/datasets"},
  {"name":"overview_files","endpoint":"/overview/files"},
  {"name":"search_datasets","endpoint":"/search/datasets"}
]}}

tools/call Behavior

  • Calling get_croissant_record produced the known serialization error:
{"jsonrpc":"2.0","id":"6","result":{"content":[{"type":"text","text":"Object of type datetime is not JSON serializable"}],"isError":true}}
  • Calling other listed tools by their names returned "Unknown tool":
onboarding      -> Unknown tool
overview        -> Unknown tool
fetch           -> Unknown tool
datatool        -> Unknown tool
overview_datasets -> Unknown tool
search_datasets -> Unknown tool

Conclusions

  • Bug 1 (serialization): get_croissant_record returns Python datetime objects that are not JSON-serializable. Needs ISO 8601 conversion (see Fix section above).
  • Bug 2 (dispatch mismatch): tools/list advertises multiple tools, but tools/call cannot invoke most of them by name. This suggests a mismatch between the registered tool names and the dispatcher’s routing logic. The server should ensure the same keys used in tools/list are accepted by tools/call.

Suggested Server Fixes

  • Serialization: Apply a default handler to json.dumps (or pre-convert datetimes) so all responses are JSON-serializable.
  • Tool dispatch: Align the tool registry and call handler so that names returned by tools/list are invokable by tools/call without leading slashes or alternate identifiers. Add tests asserting that every listed tool name is callable.

Impact

  • Jan.app, VS Code, and any MCP client using SSE will experience both issues: inability to call most advertised tools and failure on get_croissant_record due to datetime serialization.

VS Code Notes

  • Expected behavior mirrors the curl results above since VS Code speaks the same MCP methods. If you have specific VS Code error output (e.g., "Unknown tool: …" or the datetime error surfaced in the tool result panel), include it here to strengthen the report.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions