FastMCP-Scala
A Scala 3 library for building Model Context Protocol (MCP) servers.
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 <- ZIO.succeed(FastMcpServer("ExampleServer", "0.2.0"))
_ <- ZIO.attempt(server.scanAnnotations[Example.type])
_ <- server.runStdio()
yield ()
Running Examples
The above example can be run using scala-cli README.md or scala-cli scripts/quickstart.sc from the repo root. You can run the server via the MCP inspector by running:
npx @modelcontextprotocol/inspector scala-cli README.md
or
npx @modelcontextprotocol/inspector scala-cli scripts/quickstart.sc
You can also run examples directly from the command line:
scala-cli \
-e '//> using dep com.tjclp::fast-mcp-scala:0.2.3' \
--main-class com.tjclp.fastmcp.examples.AnnotatedServer
HTTP 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
_ <- ZIO.attempt(server.scanAnnotations[StreamableExample.type])
_ <- server.runHttp()
yield ()
Then test with curl:
# Initialize (returns mcp-session-id header)
curl -s -D- -X POST http://localhost:8090/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
# Call tool (SSE stream response)
curl -N -X POST http://localhost:8090/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "mcp-session-id: <session-id>" \
-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: <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
_ <- ZIO.attempt(server.scanAnnotations[HttpExample.type])
_ <- server.runHttp()
yield ()
Then test with curl:
# Initialize
curl -s -X POST http://localhost:8090/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl-test","version":"1.0"}}}'
# Call tool
curl -s -X POST http://localhost:8090/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"greet","arguments":{"name":"World"}}}'
The HTTP transport settings are configured via FastMcpServerSettings:
| Setting | Default | Description |
|---|---|---|
host | 0.0.0.0 | Bind address |
port | 8000 | Listen port |
httpEndpoint | /mcp | JSON-RPC endpoint path |
stateless | false | When true, disables sessions and SSE (stateless mode) |
Integration with Claude Desktop
In Claude desktop, you can add the following to your claude_desktop_config.json:
{
"mcpServers": {
"example-fast-mcp-server": {
"command": "scala-cli",
"args": [
"-e",
"//> 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.publishLocal
Then, 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"
Похожие серверы
Scout Monitoring MCP
спонсорPut performance and error data directly in the hands of your AI assistant.
Alpha Vantage MCP Server
спонсорAccess financial market data: realtime & historical stock, ETF, options, forex, crypto, commodities, fundamentals, technical indicators, & more
MCP Gateway
A gateway to translate MCP tool calls into HTTP API requests, configurable via YAML.
CAD-MCP
Control CAD software with natural language instructions to perform drawing operations.
Reloaderoo
A local MCP server for developers that mirrors your in-development MCP server, allowing seamless restarts and tool updates so you can build, test, and iterate on your MCP server within the same AI session without interruption.
Remote MCP Server on Cloudflare
A template for deploying a remote MCP server on Cloudflare Workers, customizable by defining tools in the source code.
Android MCP
An MCP server that provides control over Android devices through ADB. Offers device screenshot capture, UI layout analysis, package management, and ADB command execution capabilities.
vHAL MCP Server
Search Android Vehicle Hardware Abstraction Layer (vHAL) documentation and source code from a local repository clone.
SimpleLocalize
A MCP server for SimpleLocalize, a translation management system. Requires a SimpleLocalize API key.
RunwayML + Luma AI
Interact with the RunwayML and Luma AI APIs for video and image generation tasks.
webrtcperf
WebRtcPerf is an open-source tool designed for testing WebRTC services with multiple concurrent client connections, measuring the most important RTC statistics and collecting them in an easy way.
VICE MCP
MCP server embedded in the VICE Commodore 64/128/VIC-20/PET emulator, giving AI assistants direct access to read/write memory, set breakpoints, inspect VIC-II/SID/CIA registers, and debug 6502 assembly in real time with 63 tools.