Skip to content

Conversation

@BuddhiLW
Copy link
Contributor

@BuddhiLW BuddhiLW commented Jan 1, 2026

Summary

This PR fixes two issues encountered when building an MCP server with the SDK.

Context

While developing emacs-mcp, an MCP server that integrates Claude Code with Emacs, we encountered a crash on server startup:

Execution error (JsonGenerationException) at cheshire.generate/generate (generate.clj:155).
Cannot JSON encode object of class: class emacs_mcp.tools$handle_eval_elisp

Investigating the stack trace led us to validate-spec!, which was trying to log the full server-spec (including handler functions) when validation failed. This revealed a second issue: the spec validation itself was failing because our tool definitions used keyword keys in inputSchema.properties (e.g., :function_name), but the spec only accepted string keys.

Changes

server.clj

  • Modified validate-spec! to strip :handler keys from tools, prompts, and resources before logging
  • Added docstring explaining the fix

specs.clj

  • Changed :tool/properties spec from (s/map-of string? any?) to (s/map-of (s/or :str string? :kw keyword?) any?) to accept both string and keyword keys

Test plan

  • MCP server starts without crashing when tools use keyword keys in inputSchema
  • Spec validation errors are properly logged without JSON serialization failures

🤖 Generated with Claude Code

Co-Authored-By: Pedro Branquinho [email protected]
Co-Authored-By: Claude Opus 4.5 [email protected]

@vedang
Copy link
Contributor

vedang commented Jan 1, 2026

Please submit only the change of loggable-spec and the or check for str or keyword. Undo everything else -- the indentation changes and the change to your fork.

Happy to accept the PR post that.

Thank you for your contribution and for using this SDK!

…l properties

Changes:
- server.clj: Add loggable-spec that strips :handler functions before logging
  to prevent JSON serialization errors when validation fails
- specs.clj: Accept both string and keyword keys in tool inputSchema.properties

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Pedro Branquinho <[email protected]>
Co-Authored-By: Claude Opus 4.5 <[email protected]>
@BuddhiLW
Copy link
Contributor Author

BuddhiLW commented Jan 1, 2026

@vedang Done! I've cleaned up the PR to include only the essential changes:

Changes retained:

  1. loggable-spec in validate-spec! - strips :handler functions before logging
  2. s/or :str string? :kw keyword? in :tool/properties spec

Removed:

  • All indentation changes
  • deps.edn fork reference

The diff is now minimal (10 additions, 3 deletions across 2 files).

Happy to use your project; it's very useful, and enables me to write very interesting tools. Happy to collaborate!

@BuddhiLW
Copy link
Contributor Author

BuddhiLW commented Jan 1, 2026

Side note:

In clojure-lsp/jsonrpc4clj#2 I have also submitted an improvement (to one of your project's dependencies) which was capping one of my emacs-mcp add-ons. Where I spawn a swarm of claudes controlled by a main-thread claude (which is talking to me and giving updates - keeping me on the loop - on a high-level).

That improvement enables my agents to do multiple mcp calls asynchronously.

If the changes go through, I will open another PR to bump the versions here. I intend to not necessarily use a custom fork in the future, in order to run my project :). Maybe it's also useful to other people, right?

Regards,
Pedro

@vedang vedang merged commit 97418ec into unravel-team:main Jan 2, 2026
@vedang
Copy link
Contributor

vedang commented Jan 2, 2026

Thank you, merged.

Yes, I'll be happy to accept PR with version bump once your changes are merged into jsonrpc4clj!

@BuddhiLW
Copy link
Contributor Author

BuddhiLW commented Jan 2, 2026

By the way, the coffee you are sipping in your photo seems very tasty 😃 . Love the photo, brother.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants