A quick and easy way to deploy MCP servers using Scala
Documentation
FastMCP-Scala
A high‑level, developer‑friendly Scala 3 library for building Model Context Protocol (MCP) servers.
Features
- ZIO‑based effect handling and async support
- Annotation‑driven API (
@Tool,@Resource,@Prompt) - Automatic JSON Schema & handler generation via Scala 3 macros
- Two transports —
runStdio()orrunHttp()(streamable by default,stateless = truefor lightweight mode) - Seamless integration with the Java MCP SDK 1.0.0
Installation
Add to your **build.sbt (defaulting to Scala 3.7.2**):
libraryDependencies += "com.tjclp" %% "fast-mcp-scala" % "0.2.3"Quickstart
//> using scala 3.7.2
//> using dep com.tjclp::fast-mcp-scala:0.2.3
//> using options "-Xcheck-macros" "-experimental"
import com.tjclp.fastmcp.core.{Tool, Param, Prompt, Resource}
import com.tjclp.fastmcp.server.FastMcpServer
import com.tjclp.fastmcp.macros.RegistrationMacro.*
import zio.*
// Define annotated tools, prompts, and resources
object Example:
@Tool(name = Some("add"), description = Some("Add two numbers"))
def add(
@Param("First operand") a: Double,
@Param("Second operand") b: Double
): Double = a + b
@Prompt(name = Some("greet"), description = Some("Generate a greeting message"))
def greet(@Param("Name to greet") name: String): String =
s"Hello, $name!"
@Resource(uri = "file://test", description = Some("Test resource"))
def test(): String = "This is a test"
@Resource(uri = "user://{userId}", description = Some("Test resource"))
def getUser(@Param("The user id") userId: String): String = s"User ID: $userId"
object ExampleServer extends ZIOAppDefault:
override def run =
for
server using dep com.tjclp::fast-mcp-scala:0.2.3' \
--main-class com.tjclp.fastmcp.examples.AnnotatedServerHTTP Transport (Recommended for Remote)
FastMCP-Scala supports the full MCP Streamable HTTP spec with session management and SSE streaming. Just call runHttp():
//> using scala 3.7.2
//> using dep com.tjclp::fast-mcp-scala:0.2.3
//> using options "-Xcheck-macros" "-experimental"
import com.tjclp.fastmcp.core.{Tool, Param}
import com.tjclp.fastmcp.server.{FastMcpServer, FastMcpServerSettings}
import com.tjclp.fastmcp.macros.RegistrationMacro.*
import zio.*
object StreamableExample:
@Tool(name = Some("greet"), description = Some("Greet someone by name"))
def greet(@Param("Name to greet") name: String): String =
s"Hello, $name!"
object StreamableServer extends ZIOAppDefault:
override def run =
val server = FastMcpServer(
name = "StreamableExample",
version = "0.1.0",
settings = FastMcpServerSettings(port = 8090)
)
for
_ " \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"greet","arguments":{"name":"World"}}}'
# Delete session
curl -X DELETE http://localhost:8090/mcp -H "mcp-session-id: "Stateless HTTP Transport
For lightweight servers that don't need sessions or SSE, set stateless = true:
//> using scala 3.7.2
//> using dep com.tjclp::fast-mcp-scala:0.2.3
//> using options "-Xcheck-macros" "-experimental"
import com.tjclp.fastmcp.core.{Tool, Param, Resource, Prompt, Message, Role, TextContent}
import com.tjclp.fastmcp.server.{FastMcpServer, FastMcpServerSettings}
import com.tjclp.fastmcp.macros.RegistrationMacro.*
import zio.*
object HttpExample:
@Tool(name = Some("greet"), description = Some("Greet someone by name"))
def greet(@Param("Name to greet") name: String): String =
s"Hello, $name!"
object HttpServer extends ZIOAppDefault:
override def run =
val server = FastMcpServer(
name = "HttpExample",
version = "0.1.0",
settings = FastMcpServerSettings(port = 8090, stateless = true)
)
for
_ using dep com.tjclp::fast-mcp-scala:0.2.3",
"--main-class",
"com.tjclp.fastmcp.examples.AnnotatedServer"
]
}
}
}Note: FastMCP-Scala example servers are for demo purposes only and don't do anything useful
For additional examples and in‑depth docs, see **docs/guide.md**.
License
---
Development Documentation
Developing Locally
When hacking on *FastMCP‑Scala* itself, you can consume a local build in any project.
🔨 Build Commands (Mill)
FastMCP-Scala uses Mill as its build tool.
# Compile the library
./mill fast-mcp-scala.compile
# Run tests
./mill fast-mcp-scala.test
# Check code formatting
./mill fast-mcp-scala.checkFormat
# Auto-format code
./mill fast-mcp-scala.reformat
# Generate test coverage report
./mill fast-mcp-scala.scoverage.htmlReport🔨 Publish to the Local Ivy Repository
# From the fast-mcp-scala root
./mill fast-mcp-scala.publishLocalThen, in your consuming sbt project:
libraryDependencies += "com.tjclp" %% "fast-mcp-scala" % "0.2.4-SNAPSHOT"Or in Mill:
def ivyDeps = Agg(
ivy"com.tjclp::fast-mcp-scala:0.2.4-SNAPSHOT"
)
publishLocalinstalls the artifact under~/.ivy2/local.
📦 Use the JAR Directly (Unmanaged Dependencies)
# Build the JAR
./mill fast-mcp-scala.jar
# The JAR is located at:
# out/fast-mcp-scala/jar.dest/out.jar🚀 Using with scala‑cli
You can use fast-mcp-scala in another scala‑cli project:
//> using scala 3.7.2
//> using dep com.tjclp::fast-mcp-scala:0.2.3
//> using options "-Xcheck-macros" "-experimental"You can also point directly at the local JAR:
//> using scala 3.7.2
//> using jar "/absolute/path/to/out/fast-mcp-scala/jar.dest/out.jar"
//> using options "-Xcheck-macros" "-experimental"Similar MCP
Based on tags & features
Trending MCP
Most active this week