Skip to content
Open
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
43 changes: 23 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,38 +20,41 @@ libraryDependencies += "com.tjclp" %% "fast-mcp-scala" % "0.1.1"

```scala
//> using scala 3.6.4
//> using dep com.tjclp::fast-mcp-scala:0.1.1
//> using dep com.tjclp::fast-mcp-scala:0.1.2-SNAPSHOT
//> using options "-Xcheck-macros" "-experimental"

import com.tjclp.fastmcp.core.{Tool, ToolParam, Prompt, PromptParam, Resource}
import com.tjclp.fastmcp.core.{Tool, ToolParam, Prompt, PromptParam, Resource, ResourceParam}
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(
@ToolParam("First operand") a: Double,
@ToolParam("Second operand") b: Double
): Double = a + b

@Prompt(name = Some("greet"), description = Some("Generate a greeting message"))
def greet(@PromptParam("Name to greet") name: String): String =
s"Hello, $name!"
@Tool(name = Some("add"), description = Some("Add two numbers"))
def add(
@ToolParam("First operand") a: Double,
@ToolParam("Second operand") b: Double
): Double = a + b

@Prompt(name = Some("greet"), description = Some("Generate a greeting message"))
def greet(@PromptParam("Name to greet") name: String): String =
s"Hello, $name!"

// Note: resource templates (templated URIs) are not yet supported;
// coming soon when the MCP java‑sdk adds template support.
@Resource(uri = "file://test", description = Some("Test resource"))
def test(): String = "This is a test"
@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(@ResourceParam("The user id") userId: String): String = s"User ID: $userId"

object ExampleServer extends ZIOAppDefault:
override def run =
for
server <- ZIO.succeed(FastMcpServer("ExampleServer"))
_ <- ZIO.attempt(server.scanAnnotations[Example.type])
_ <- server.runStdio()
yield ()

override def run =
for
server <- ZIO.succeed(FastMcpServer("ExampleServer", "0.1.1"))
_ <- ZIO.attempt(server.scanAnnotations[Example.type])
_ <- server.runStdio()
yield ()
```

### Running Examples
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ lazy val Versions = new {
val jackson = "2.18.3"
val tapir = "1.11.25"
val jsonSchemaCirce = "0.11.9"
val mcpSdk = "0.9.0"
val mcpSdk = "0.10.0"
val scalaTest = "3.2.19"
}

Expand Down
9 changes: 5 additions & 4 deletions scripts/quickstart.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//> using scala 3.6.4
//> using dep com.tjclp::fast-mcp-scala:0.1.1
//> using dep com.tjclp::fast-mcp-scala:0.1.2-SNAPSHOT
//> using options "-Xcheck-macros" "-experimental"

import com.tjclp.fastmcp.core.{Tool, ToolParam, Prompt, PromptParam, Resource}
import com.tjclp.fastmcp.core.{Tool, ToolParam, Prompt, PromptParam, Resource, ResourceParam}
import com.tjclp.fastmcp.server.FastMcpServer
import com.tjclp.fastmcp.macros.RegistrationMacro.*
import zio.*
Expand All @@ -20,11 +20,12 @@ object Example:
def greet(@PromptParam("Name to greet") name: String): String =
s"Hello, $name!"

// Note: resource templates (templated URIs) are not yet supported;
// coming soon when the MCP java‑sdk adds template support.
@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(@ResourceParam("The user id") userId: String): String = s"User ID: $userId"

object ExampleServer extends ZIOAppDefault:

override def run =
Expand Down
52 changes: 45 additions & 7 deletions src/main/scala/com/tjclp/fastmcp/examples/AnnotatedServer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,62 @@ object AnnotatedServer extends ZIOAppDefault:
def welcomeResource(): String =
"Welcome to the FastMCP-Scala Annotated Server!"

/** A template resource that takes a user ID from the URI. Annotated with @Resource. The URI
* pattern {userId} matches the parameter name.
/** A template resource that takes a user ID from the URI. The URI pattern {userId} matches the
* parameter name.
*/
@Resource(
uri = "users://profile",
uri = "users://{userId}/profile",
name = Some("UserProfile"),
description = Some("Dynamically generated user profile."),
description = Some("Dynamically generated user profile based on user ID."),
mimeType = Some("application/json")
)
def userProfileResource(): String =
def userProfileResource(
@ResourceParam("The unique identifier of the user") userId: String
): String =
// In a real app, fetch user data based on userId
val userId = "123"
Map(
"userId" -> userId,
"name" -> s"User $userId",
"email" -> s"[email protected]"
"email" -> s"[email protected]",
"joined" -> "2024-01-15"
).toJsonPretty

/** A template resource demonstrating multiple path parameters.
*/
@Resource(
uri = "repos://{owner}/{repo}/issues/{id}",
name = Some("RepoIssue"),
description = Some("Get a specific issue from a repository."),
mimeType = Some("application/json")
)
def getRepositoryIssue(
@ResourceParam("Repository owner") owner: String,
@ResourceParam("Repository name") repo: String,
@ResourceParam("Issue ID") id: String
): String =
Map(
"owner" -> owner,
"repo" -> repo,
"id" -> id,
"title" -> s"Issue #$id in $owner/$repo",
"status" -> "open",
"created" -> "2024-06-01"
).toJsonPretty

/** A template resource for file access with custom MIME type detection.
*/
@Resource(
uri = "files://{path}",
name = Some("FileContent"),
description = Some("Read file content from a specific path.")
)
def readFileResource(
@ResourceParam("File path relative to the server root") path: String
): String =
// In a real implementation, you would read the actual file
// For demo purposes, we'll return mock content
s"Content of file: $path\n\nThis is a demo file content."

/** A simple prompt with no arguments. Annotated with @Prompt.
*/
@Prompt(
Expand Down
Loading