Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions core/src/main/scala/chimp/McpHandler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,27 @@ import sttp.tapir.docs.apispec.schema.TapirSchemaToJsonSchema
* The server name (for protocol reporting).
* @param version
* The server version (for protocol reporting).
* @param showJsonSchemaMetadata
* Whether to include JSON Schema metadata (such as $schema) in the tool input schemas. Some agents do not recognize it, so it can be
* disabled.
*/
class McpHandler[F[_]](tools: List[ServerTool[?, F]], name: String = "Chimp MCP server", version: String = "1.0.0"):
class McpHandler[F[_]](
tools: List[ServerTool[?, F]],
name: String = "Chimp MCP server",
version: String = "1.0.0",
showJsonSchemaMetadata: Boolean = true
):
private val logger = LoggerFactory.getLogger(classOf[McpHandler[_]])
private val ProtocolVersion = "2025-03-26"
private val toolsByName = tools.map(t => t.name -> t).toMap

/** Converts a ServerTool to its protocol definition. */
private def toolToDefinition(tool: ServerTool[?, F]): ToolDefinition =
val jsonSchema = TapirSchemaToJsonSchema(tool.inputSchema, markOptionsAsNullable = true)
val jsonSchema =
val base = TapirSchemaToJsonSchema(tool.inputSchema, markOptionsAsNullable = true)
if showJsonSchemaMetadata then base
else base.copy($schema = None)

val json = jsonSchema.asJson
ToolDefinition(
name = tool.name,
Expand Down
10 changes: 8 additions & 2 deletions core/src/main/scala/chimp/mcpEndpoint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ private val logger = LoggerFactory.getLogger(classOf[McpHandler[_]])
* @tparam F
* The effect type. Might be `Identity` for a endpoints with synchronous logic.
*/
def mcpEndpoint[F[_]](tools: List[ServerTool[?, F]], path: List[String]): ServerEndpoint[Any, F] =
val mcpHandler = new McpHandler(tools)
def mcpEndpoint[F[_]](
tools: List[ServerTool[?, F]],
path: List[String],
name: String = "Chimp MCP server",
version: String = "1.0.0",
showJsonSchemaMetadata: Boolean = true
): ServerEndpoint[Any, F] =
val mcpHandler = new McpHandler(tools, name, version, showJsonSchemaMetadata)
val e = infallibleEndpoint.post
.in(path.foldLeft(emptyInput)((inputSoFar, pathComponent) => inputSoFar / pathComponent))
.in(extractFromRequest(_.headers))
Expand Down