moonbit_mcp

    A MoonBit SDK for the Model Context Protocol (MCP). Build MCP servers and clients in MoonBit.

    mcp
    model-context-protocol
    llm
    agent
    sdk
    Download zip
    Version
    0.1.0
    License
    MIT
    Last updated
    last month
    Downloads
    5

    #MoonBit MCP SDK

    CI MoonBit License

    A MoonBit SDK for the Model Context Protocol (MCP).

    Build MCP servers and clients in MoonBit — connect to Claude, Cursor, and any MCP-compatible AI agent.

    #30-Second Quick Start

    #Install

    moon add 123123213weqw/moonbit_mcp

    #Minimal Echo Server

    import {
    "123123213weqw/moonbit_mcp" @mcp,
    }

    ///|
    fn main {
    let server = @mcp.McpServer::new("echo-server", "1.0.0")
    server.tool(
    "echo",
    @mcp.JsonSchema::object() |> @mcp.JsonSchema::string("message"),
    fn(args) {
    let msg = @mcp.ContentBlock::as_text(
    @mcp.ContentBlock::TextContent("echo: " + args.stringify(), None)
    ).or_else(fn() { "no args" })
    @mcp.CallToolResult::text(msg)
    },
    )
    // In a real server, you'd drive server.process_message(raw) from a transport.
    }

    #What This Provides

    LayerModules
    ProtocolJSON-RPC 2.0 parsing/encoding, MCP message types (Request/Response/Notification)
    TypesContentBlock (text/image/audio/resource), Tool, Resource, Prompt, LogMessage
    ServerLow-level Server (handler registry + dispatch) + high-level McpServer builder
    SchemaJSON Schema builder for tool input/output schemas
    Transporttrait Transport abstraction + InMemoryTransport (tests) + BufferedTransport

    #Architecture

    ┌─────────────────────────────────┐ │ McpServer (high-level builder) │ │ .tool() / .resource() / ... │ └──────────────┬──────────────────┘ │ registers handlers ┌──────────────▼──────────────────┐ │ Server (low-level dispatcher) │ │ initialize / tools/list / call │ │ + capability negotiation │ └──────────────┬──────────────────┘ │ uses ┌──────────────▼──────────────────┐ │ JSON-RPC 2.0 parse_message() │ │ + message_to_string() │ └──────────────┬──────────────────┘ │ drives any ┌──────────────▼──────────────────┐ │ trait Transport │ │ InMemoryTransport | Buffered │ └─────────────────────────────────┘

    #Relationship to moon_proto

    • moon_proto: static .proto schema validation + protobuf wire codec
    • moonbit_mcp: dynamic AI Agent tool protocol (JSON-RPC over stdio/HTTP)

    Zero overlap. The two can coexist: parse .proto with moon_proto, expose as MCP resources with moonbit_mcp.

    #Development

    moon fmt --check # format check moon check --deny-warn # type check (warnings as errors) moon test --deny-warn # run tests moon test --target all # wasm / wasm-gc / js / native moon info # regenerate public interface snapshot

    #Test Results

    • moon test --target all: 21/21 passed on all 4 targets
    • moon check --deny-warn: 0 warnings, 0 errors

    #License

    MIT

    MessageHandler

    type MessageHandler = (String) -> Unit

    The callback invoked when a complete JSON-RPC message line arrives.

    MethodHandler

    type MethodHandler = (Json, ServerContext) -> Result[Json, McpError]

    A handler function for a specific MCP method on a server.

    Receives the raw JSON params (or Null) and returns either a result Json or an [McpError].

    ToolCallback

    type ToolCallback = (Json) -> CallToolResult

    Tool handler callback type: receives the arguments JSON and returns a result.

    Transport

    pub trait Transport {
    fn send(Self, String) -> Unit
    }

    Transport abstraction: how JSON-RPC messages enter and leave a server/client.

    The trait only requires [send]. [start] and [close] are provided as default no-ops so transports that do not need them (e.g. in-memory) incur no boilerplate.

    Audience

    pub(all) enum Audience {
    AudienceUser
    AudienceAssistant
    } derive(Eq,
    Debug
    )

    Audience for a content block annotation.

    BufferedTransport

    pub(all) struct BufferedTransport {
    sent : Array[String]
    closed : Bool
    }

    A buffered transport that collects sent messages in an array (useful for testing).

    BufferedTransport::close

    fn BufferedTransport::close(self : BufferedTransport) -> Unit

    BufferedTransport::messages

    fn BufferedTransport::messages(self : BufferedTransport) -> Array[String]

    Messages collected so far (in send order).

    BufferedTransport::new

    CallToolResult

    pub(all) struct CallToolResult {
    content : Array[ContentBlock]
    structured_content : Json?
    is_error : Bool
    } derive(Eq,
    Debug
    )

    Result of calling a tool.

    CallToolResult::error

    fn CallToolResult::error(text : String) -> CallToolResult

    Construct an error result (business error — the tool ran but failed).

    CallToolResult::text

    fn CallToolResult::text(text : String) -> CallToolResult

    Construct a successful text result.

    CallToolResult::to_json

    fn CallToolResult::to_json(self : CallToolResult) -> Json

    Encode [CallToolResult] to JSON.

    ContentAnnotations

    pub(all) struct ContentAnnotations {
    audience : Array[Audience]
    priority : Double?
    last_modified : String?
    } derive(Eq,
    Debug
    )

    Annotations providing hints about a content block's role.

    ContentBlock

    pub(all) enum ContentBlock {
    TextContent(String, ContentAnnotations?)
    ImageContent(String, String, ContentAnnotations?)
    AudioContent(String, String, ContentAnnotations?)
    ResourceLink(String, String, String?, String?, String?, ContentAnnotations?)
    EmbeddedResource(ResourceContents, ContentAnnotations?)
    } derive(Eq,
    Debug
    )

    A content block — the universal payload type shared by tools, resources, and prompts.

    ContentBlock::as_text

    fn ContentBlock::as_text(self : ContentBlock) -> String?

    Extract the text from a [ContentBlock] if it is a text block.

    ContentBlock::to_json

    fn ContentBlock::to_json(self : ContentBlock) -> Json

    Encode a [ContentBlock] to JSON.

    GetPromptResult

    pub(all) struct GetPromptResult {
    description : String?
    messages : Array[PromptMessage]
    } derive(Eq,
    Debug
    )

    Result of getting a prompt.

    GetPromptResult::to_json

    fn GetPromptResult::to_json(self : GetPromptResult) -> Json

    Encode [GetPromptResult] to JSON.

    Implementation

    pub(all) struct Implementation {
    name : String
    title : String?
    version : String
    } derive(Eq,
    Debug
    )

    Name and version of a client or server implementation.

    Implementation::to_json

    fn Implementation::to_json(self : Implementation) -> Json

    Encode [Implementation] to JSON.

    InMemoryTransport

    pub(all) struct InMemoryTransport {
    handler : (String) -> Unit?
    closed : Bool
    peer : InMemoryTransport?
    }

    An in-memory transport pair for tests and same-process use.

    Create a linked pair with [InMemoryTransport::pair]; messages sent on one end are delivered to the handler of the other.

    InMemoryTransport::close

    fn InMemoryTransport::close(self : InMemoryTransport) -> Unit

    Close the transport (subsequent sends are dropped).

    InMemoryTransport::on_message

    fn InMemoryTransport::on_message(self : InMemoryTransport, h : (String) -> Unit) -> Unit

    Set the message handler for this transport.

    InMemoryTransport::pair

    Create a linked pair of in-memory transports. Messages sent on one are delivered to the other's handler.

    JsonSchema

    pub(all) struct JsonSchema {
    typ : SchemaType
    description : String?
    properties : Map[String, SchemaProperty]
    required : Array[String]
    } derive(Eq,
    Debug
    )

    A builder for constructing a JSON Schema (the subset used by MCP tools).

    JsonSchema::boolean

    fn JsonSchema::boolean(self : JsonSchema, name : String) -> JsonSchema

    Add a required boolean property.

    JsonSchema::describe

    fn JsonSchema::describe(self : JsonSchema, desc : String) -> JsonSchema

    Set a human-readable description for the schema.

    JsonSchema::integer

    fn JsonSchema::integer(self : JsonSchema, name : String) -> JsonSchema

    Add a required integer property.

    JsonSchema::number

    fn JsonSchema::number(self : JsonSchema, name : String) -> JsonSchema

    Add a required number property.

    JsonSchema::object

    fn JsonSchema::object() -> JsonSchema

    Create a new object schema (the root of every tool input/output schema).

    JsonSchema::optional_string

    fn JsonSchema::optional_string(self : JsonSchema, name : String) -> JsonSchema

    Add an optional string property (not added to required).

    JsonSchema::string

    fn JsonSchema::string(self : JsonSchema, name : String) -> JsonSchema

    Add a required string property to an object schema.

    JsonSchema::string_desc

    fn JsonSchema::string_desc(self : JsonSchema, name : String, desc : String) -> JsonSchema

    Add a required string property with a description.

    JsonSchema::to_json

    fn JsonSchema::to_json(self : JsonSchema) -> Json

    Encode a [JsonSchema] to a JSON value.

    LogLevel

    pub(all) enum LogLevel {
    LevelDebug
    LevelInfo
    LevelNotice
    LevelWarning
    LevelError
    LevelCritical
    LevelAlert
    LevelEmergency
    } derive(Eq,
    Debug
    )

    Log severity level (RFC 5424 syslog ordering, low to high).

    LogLevel::to_string

    fn LogLevel::to_string(self : LogLevel) -> String

    Convert a [LogLevel] to its JSON string representation.

    LogMessage

    pub(all) struct LogMessage {
    level : LogLevel
    logger : String?
    data : Json
    } derive(Eq,
    Debug
    )

    A log message notification sent from server to client.

    LogMessage::to_json

    fn LogMessage::to_json(self : LogMessage) -> Json

    Encode a [LogMessage] to a JSON notification params object.

    McpError

    pub(all) enum McpError {
    RpcError(Int, String)
    ParseError(String)
    TransportError(String)
    ProtocolError(String)
    UnknownMethod(String)
    UnknownTarget(String)
    InvalidArguments(String)
    } derive(Eq,
    Debug
    )

    Error type returned by all MCP SDK operations that can fail.

    McpError::to_code

    fn McpError::to_code(self : McpError) -> Int

    Convert an [McpError] to a JSON-RPC error code.

    McpError::to_message

    fn McpError::to_message(self : McpError) -> String

    Human-readable message for an [McpError].

    McpServer

    pub(all) struct McpServer {
    server : Server
    tools : Array[Tool]
    tool_callbacks : Map[String, (Json) -> CallToolResult]
    }

    High-level MCP server builder with ergonomic tool/resource/prompt registration.

    McpServer::inner

    fn McpServer::inner(self : McpServer) -> Server

    Access the underlying low-level server.

    McpServer::new

    fn McpServer::new(name : String, version : String) -> McpServer

    Create a new high-level server builder.

    McpServer::process_message

    fn McpServer::process_message(self : McpServer, raw : String) -> String?

    Process an incoming message (delegate to the inner server).

    McpServer::tool

    fn McpServer::tool(self : McpServer, name : String, schema : JsonSchema, cb : (Json) -> CallToolResult) -> McpServer

    Register a tool with its input schema and callback.

    McpServer::tool_desc

    fn McpServer::tool_desc(self : McpServer, name : String, desc : String, schema : JsonSchema, cb : (Json) -> CallToolResult) -> McpServer

    Register a tool with description.

    Paginated

    pub(all) struct Paginated[T] {
    items : Array[T]
    next_cursor : String?
    } derive(Eq,
    Debug
    )

    A paginated result carrying an optional cursor for the next page.

    Paginated::new

    fn[T] Paginated::new(items : Array[T]) -> Paginated[T]

    Construct a paginated result with no next cursor.

    Paginated::with_cursor

    fn[T] Paginated::with_cursor(items : Array[T], cursor : String) -> Paginated[T]

    Construct a paginated result with a next cursor.

    Prompt

    pub(all) struct Prompt {
    name : String
    title : String?
    description : String?
    arguments : Array[PromptArgument]
    } derive(Eq,
    Debug
    )

    A prompt definition registered on an MCP server.

    Prompt::arg

    fn Prompt::arg(self : Prompt, name : String, required : Bool) -> Prompt

    Add an argument to a prompt.

    Prompt::new

    fn Prompt::new(name : String) -> Prompt

    Create a new prompt with the given name.

    Prompt::to_json

    fn Prompt::to_json(self : Prompt) -> Json

    Encode a [Prompt] to JSON.

    PromptArgument

    pub(all) struct PromptArgument {
    name : String
    description : String?
    required : Bool
    } derive(Eq,
    Debug
    )

    A named argument accepted by a prompt.

    PromptMessage

    pub(all) struct PromptMessage {
    role : PromptRole
    content : ContentBlock
    } derive(Eq,
    Debug
    )

    A single message in a prompt result.

    PromptRole

    pub(all) enum PromptRole {
    RoleUser
    RoleAssistant
    } derive(Eq,
    Debug
    )

    Role of a prompt message sender.

    ReadResourceResult

    pub(all) struct ReadResourceResult {
    contents : Array[ResourceContents]
    } derive(Eq,
    Debug
    )

    Result of reading a resource.

    ReadResourceResult::text

    fn ReadResourceResult::text(uri : String, text : String) -> ReadResourceResult

    Construct a read result from a single text resource.

    ReadResourceResult::to_json

    Encode [ReadResourceResult] to JSON.

    RequestId

    pub(all) enum RequestId {
    IdInt(Int)
    IdString(String)
    } derive(Eq,
    Debug
    )

    A JSON-RPC request id. Per MCP spec, id must be string or integer, never null.

    Resource

    pub(all) struct Resource {
    uri : String
    name : String
    title : String?
    description : String?
    mime_type : String?
    } derive(Eq,
    Debug
    )

    A resource exposed by an MCP server.

    Resource::new

    fn Resource::new(uri : String, name : String) -> Resource

    Create a new resource with a URI and display name.

    Resource::to_json

    fn Resource::to_json(self : Resource) -> Json

    Encode a [Resource] to JSON.

    ResourceContents

    pub(all) enum ResourceContents {
    TextResourceContents(String, String?, String)
    BlobResourceContents(String, String?, String)
    } derive(Eq,
    Debug
    )

    Contents of a resource — either text or base64 blob.

    ResourceContents::to_json

    fn ResourceContents::to_json(self : ResourceContents) -> Json

    Encode [ResourceContents] to JSON.

    ResourceTemplate

    pub(all) struct ResourceTemplate {
    uri_template : String
    name : String
    title : String?
    description : String?
    mime_type : String?
    } derive(Eq,
    Debug
    )

    A parameterized resource template (URI Template RFC 6570).

    RpcErrorObject

    pub(all) struct RpcErrorObject {
    code : Int
    message : String
    data : Json?
    } derive(Eq,
    Debug
    )

    JSON-RPC error object.

    RpcMessage

    pub(all) enum RpcMessage {
    MsgRequest(RpcRequest)
    MsgResponse(RpcResponse)
    MsgNotification(RpcNotification)
    } derive(Eq,
    Debug
    )

    Sum type for any inbound JSON-RPC message.

    RpcNotification

    pub(all) struct RpcNotification {
    method_name : String
    params : Json?
    } derive(Eq,
    Debug
    )

    A JSON-RPC notification (no id, no response expected).

    RpcNotification::method_str

    fn RpcNotification::method_str(self : RpcNotification) -> String

    The method string of a notification.

    RpcNotification::to_json

    fn RpcNotification::to_json(self : RpcNotification) -> Json

    Encode an [RpcNotification] to a JSON object.

    RpcRequest

    pub(all) struct RpcRequest {
    id : RequestId
    method_name : String
    params : Json?
    } derive(Eq,
    Debug
    )

    A JSON-RPC request.

    RpcRequest::method_str

    fn RpcRequest::method_str(self : RpcRequest) -> String

    The method string of a request.

    RpcRequest::to_json

    fn RpcRequest::to_json(self : RpcRequest) -> Json

    Encode an [RpcRequest] to a JSON object.

    RpcResponse

    pub(all) enum RpcResponse {
    RpcResult(RequestId, Json)
    RpcErrorResp(RequestId, RpcErrorObject)
    } derive(Eq,
    Debug
    )

    A JSON-RPC response (result or error, mutually exclusive).

    RpcResponse::to_json

    fn RpcResponse::to_json(self : RpcResponse) -> Json

    Encode an [RpcResponse] to a JSON object.

    SchemaProperty

    pub(all) struct SchemaProperty {
    typ : SchemaType
    description : String?
    } derive(Eq,
    Debug
    )

    A property definition inside an object schema.

    SchemaType

    pub(all) enum SchemaType {
    SchemaObject
    SchemaString
    SchemaNumber
    SchemaInteger
    SchemaBoolean
    SchemaArray
    } derive(Eq,
    Debug
    )

    JSON Schema types supported by MCP tool input/output schemas.

    Server

    pub(all) struct Server {
    server_info : Implementation
    capabilities : ServerCapabilities
    handlers : Map[String, (Json, ServerContext) -> Result[Json, McpError]]
    initialized : Bool
    }

    The low-level MCP server: dispatches JSON-RPC messages to registered handlers and manages the initialize handshake.

    Server::handle_method

    fn Server::handle_method(self : Server, m : String, h : (Json, ServerContext) -> Result[Json, McpError]) -> Server

    Register a handler for a specific MCP method.

    Server::new

    fn Server::new(name : String, version : String) -> Server

    Create a new server with the given name/version and default (empty) capabilities.

    Server::process_message

    fn Server::process_message(self : Server, raw : String) -> String?

    Process a single incoming JSON-RPC message string and return the response string (if any — notifications produce no response).

    Server::with_tools

    fn Server::with_tools(self : Server) -> Server

    Enable tools capability with list-changed notifications.

    ServerCapabilities

    pub(all) struct ServerCapabilities {
    tools_list_changed : Bool
    resources_subscribe : Bool
    resources_list_changed : Bool
    prompts_list_changed : Bool
    logging : Bool
    } derive(Eq,
    Debug
    )

    Server-side capability flags (each optional; advertised in initialize response).

    ServerCapabilities::new

    Default capabilities: everything off. Use the builder methods to enable.

    ServerCapabilities::to_json

    Encode [ServerCapabilities] to the JSON capabilities object.

    ServerContext

    pub(all) struct ServerContext {
    server_info : Implementation
    capabilities : ServerCapabilities
    initialized : Bool
    }

    Mutable server state passed to method handlers.

    Tool

    pub(all) struct Tool {
    name : String
    title : String?
    description : String?
    input_schema : JsonSchema
    output_schema : JsonSchema?
    annotations : ToolAnnotations?
    } derive(Eq,
    Debug
    )

    A tool definition registered on an MCP server.

    Tool::describe

    fn Tool::describe(self : Tool, desc : String) -> Tool

    Set the tool's human-readable description.

    Tool::new

    fn Tool::new(name : String, schema : JsonSchema) -> Tool

    Create a new tool with the given name and input schema.

    Tool::to_json

    fn Tool::to_json(self : Tool) -> Json

    Encode a [Tool] to its JSON representation (for tools/list responses).

    ToolAnnotations

    pub(all) struct ToolAnnotations {
    title : String?
    read_only_hint : Bool
    destructive_hint : Bool
    idempotent_hint : Bool
    open_world_hint : Bool
    } derive(Eq,
    Debug
    )

    Behavioral hints about a tool (all are advisory, not enforced).

    ToolAnnotations::new

    Default tool annotations.

    content_blocks_to_json

    fn content_blocks_to_json(blocks : Array[ContentBlock]) -> Json

    Encode an array of content blocks to a JSON array.

    implementation_error_start

    let implementation_error_start : Int

    Start of the implementation-defined error range.

    internal_error_code

    let internal_error_code : Int

    JSON-RPC 2.0 standard error code: internal error.

    invalid_params_code

    let invalid_params_code : Int

    JSON-RPC 2.0 standard error code: invalid params.

    invalid_request_code

    let invalid_request_code : Int

    JSON-RPC 2.0 standard error code: invalid request.

    json_rpc_version

    let json_rpc_version : String

    JSON-RPC 2.0 protocol version string.

    latest_protocol_version

    let latest_protocol_version : String

    The latest MCP protocol version this SDK targets.

    message_to_string

    fn message_to_string(msg : RpcMessage) -> String

    Serialize any [RpcMessage] to a JSON string.

    method_cancelled

    let method_cancelled : String

    method_initialize

    let method_initialize : String

    MCP method name constants.

    method_initialized

    let method_initialized : String

    method_logging_message

    let method_logging_message : String

    method_logging_set_level

    let method_logging_set_level : String

    method_not_found_code

    let method_not_found_code : Int

    JSON-RPC 2.0 standard error code: method not found.

    method_ping

    let method_ping : String

    method_progress

    let method_progress : String

    method_prompts_get

    let method_prompts_get : String

    method_prompts_list

    let method_prompts_list : String

    method_prompts_list_changed

    let method_prompts_list_changed : String

    method_resources_list

    let method_resources_list : String

    method_resources_list_changed

    let method_resources_list_changed : String

    method_resources_read

    let method_resources_read : String

    method_resources_subscribe

    let method_resources_subscribe : String

    method_resources_templates_list

    let method_resources_templates_list : String

    method_resources_updated

    let method_resources_updated : String

    method_tools_call

    let method_tools_call : String

    method_tools_list

    let method_tools_list : String

    method_tools_list_changed

    let method_tools_list_changed : String

    parse_error_code

    let parse_error_code : Int

    JSON-RPC 2.0 standard error code: parse error.

    parse_message

    fn parse_message(raw : String) -> Result[RpcMessage, McpError]

    Parse an [RpcMessage] from a raw JSON string.

    resource_not_found_code

    let resource_not_found_code : Int

    Resource not found error code (de-facto standard in MCP ecosystem).

    send_and_return

    fn[T : Transport] send_and_return(t : T, msg : String) -> T

    Send a message through any transport and return the transport (for chaining).

    send_message

    fn[T : Transport] send_message(t : T, msg : String) -> Unit

    Send a message through any transport (generic helper for trait dispatch).

    text_content

    fn text_content(text : String) -> ContentBlock

    Convenience constructor: create a text content block with no annotations.

    tools_to_json

    fn tools_to_json(tools : Array[Tool]) -> Json

    Encode an array of tools for a tools/list response.