MCP-scala

Una implementación del servidor del Protocolo de Contexto de Modelo escrita en Scala 3.

Documentación

MCP-scala

Servidor del Model Context Protocol escrito en Scala 3

Etapa de desarrollo

Este software se encuentra actualmente en estado ALPHA.

  • Derivación automática de JSON Schema
  • Define tu herramienta
  • Parte de contenido de texto
  • Otras partes de contenido
  • Manejo de notificaciones
  • Manejo de capacidades
  • transporte stdio
  • transporte HTTP
  • Característica de autorización

Esta implementación necesita tu atención y contribución.

No dudes en abrir un Issue / PR para contribuir a este proyecto.

Demostración

Primero, compila el servidor a JS:

sbt example/fastLinkJS

Luego, utiliza el servidor en tu cliente MCP:

// Example for Cline
{
  "mcpServers": {
    "mcpscala": {
      "disabled": false,
      "timeout": 30,
      "command": "sh",
      "args": ["/path/to/run.sh"],
      "transportType": "stdio"
    }
  }
}

Puedes ejecutar alguna herramienta:

  • randomNumber
    • genera un número aleatorio entre min y max.
  • iota
    • genera una secuencia de números desde min hasta max.
  • sum
    • calcula la suma de una secuencia de números.

Implementa tu herramienta

Consulta Main.scala para más detalles.

//> using scala 3
//> using toolkit typelevel:default
//> using dep dev.capslock::mcpscala:0.1.0

package dev.capslock.mcpscala

import cats.effect.IO
import cats.effect.IOApp
import dev.capslock.mcpscala.transport.StdioServer
import dev.capslock.mcpscala.mcp.ContentPart
import sttp.tapir.Schema.annotations.description

case class RandomNumberInput(
    @description("Minimum value (inclusive)") min: Int,
    @description("Maximum value (exclusive)") max: Int
) derives io.circe.Decoder,
      sttp.tapir.Schema

def randomNumber(input: RandomNumberInput): IO[Seq[ContentPart]] = IO {
  val random = scala.util.Random.between(input.min, input.max)
  Seq(ContentPart.TextContentPart(random.toString))
}

/** Entry point for the Stdio server.
  */
object StdioMain extends McpIOApp(
    name = "random-number",
    header = "Generate a random number",
  ):
    
  val handlers = Handler.methodHandlers(
    Map(
      "randomNumber" -> server.Tool(randomNumber),
    )
  )