Skip to content

apparata/MCPToolbox

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MCPToolbox

A Swift library for building Model Context Protocol (MCP) servers.

MCPToolbox provides a simple, type-safe API for creating MCP servers that can expose tools, resources, and prompts to AI assistants like Claude.

Features

  • Tools: Define callable functions with JSON Schema input validation
  • Resources: Expose static and dynamic data via URI-based access
  • Resource Templates: Support parameterized URIs with {placeholder} syntax
  • Prompts: Create reusable message templates for AI interactions
  • Elicitation: Request user input from clients during tool execution
  • Streamable HTTP Transport: HTTP/SSE-based communication (MCP 2025-11-25)
  • Actor-based Concurrency: Thread-safe by design with Swift actors
  • Full DocC Documentation: Comprehensive documentation for all public APIs

Requirements

  • Swift 6.0+
  • macOS 14.0+ / Linux

Installation

Add MCPToolbox to your Package.swift:

dependencies: [
    .package(url: "https://github.com/example/MCPToolbox.git", from: "1.0.0")
]

Then add it to your target:

.target(
    name: "YourTarget",
    dependencies: ["MCPToolbox"]
)

Quick Start

Creating a Server

import MCPToolbox

let server = MCPServer(
    name: "my-server",
    version: "1.0.0",
    host: "127.0.0.1",
    port: 8080
)

// Register your tools, resources, and prompts
await server.registerTool(MyTool())
await server.registerResource(MyResource())
await server.registerPrompt(MyPrompt())

// Start the server
try await server.start()

Defining a Tool

struct AddTool: MCPToolHandler {
    let name = "add"
    let description = "Add two numbers together"
    let inputSchema = JSONSchema.object(
        properties: [
            "a": .number(description: "First number"),
            "b": .number(description: "Second number")
        ],
        required: ["a", "b"]
    )

    func execute(arguments: [String: JSONValue]) async throws -> CallToolResult {
        guard let a = arguments["a"]?.doubleValue,
              let b = arguments["b"]?.doubleValue else {
            throw ToolError.invalidArguments("Both 'a' and 'b' must be numbers")
        }
        return .text("Result: \(a + b)")
    }
}

Defining a Resource

struct ConfigResource: MCPResourceHandler {
    let uri = "config://app"
    let name = "Application Configuration"
    let description: String? = "Current app settings"
    let mimeType: String? = "application/json"

    func read() async throws -> [ResourceContents] {
        let config = """
        {"theme": "dark", "language": "en"}
        """
        return [.text(TextResourceContents(uri: uri, mimeType: mimeType, text: config))]
    }
}

Defining a Prompt

struct GreetingPrompt: MCPPromptHandler {
    let name = "greeting"
    let description: String? = "Generate a personalized greeting"
    let arguments: [PromptArgument] = [
        PromptArgument(name: "name", description: "Person to greet", required: true)
    ]

    func get(arguments: [String: String]) async throws -> GetPromptResult {
        let name = arguments["name"] ?? "friend"
        return GetPromptResult(
            messages: [
                PromptMessage(
                    role: .user,
                    content: .text(TextContent(text: "Hello, \(name)!"))
                )
            ]
        )
    }
}

Using Elicitation

Tools can request user input during execution using elicitation:

struct ConfirmTool: MCPContextualToolHandler {
    let name = "confirm"
    let description = "Perform an action with user confirmation"
    let inputSchema = JSONSchema.object(
        properties: ["action": .string(description: "Action to confirm")],
        required: ["action"]
    )

    func execute(
        arguments: [String: JSONValue],
        context: ToolExecutionContext
    ) async throws -> CallToolResult {
        let action = arguments["action"]?.stringValue ?? ""

        let result = try await context.requestInput(
            message: "Do you want to proceed with: \(action)?",
            schema: .object(properties: ["confirmed": .boolean()])
        )

        if result.action == .accept,
           let confirmed = result.content?["confirmed"]?.boolValue,
           confirmed {
            return .text("Action confirmed!")
        }
        return .text("Action cancelled.")
    }
}

Architecture

MCPToolbox/
├── MCPServer.swift              # Main server actor
├── Transport/
│   └── StreamableHTTPTransport  # HTTP/SSE transport
├── Session/
│   └── MCPSession               # Client session management
├── Protocol/
│   ├── MCPTypes                 # MCP message types
│   ├── Capabilities             # Server/client capabilities
│   └── ProtocolVersion          # Protocol versioning
├── JSONRPC/
│   ├── JSONRPCMessage           # JSON-RPC types
│   └── JSONRPCError             # Error handling
├── Handlers/
│   ├── ToolHandler              # Tool protocols
│   ├── ResourceHandler          # Resource protocols
│   └── PromptHandler            # Prompt protocols
└── Utilities/
    ├── JSONValue                # Dynamic JSON handling
    └── Logging                  # Server logging

Reference CLI

The package includes mcptool, a reference MCP server implementation:

swift run mcptool --port 8080 --verbose

Options:

  • --host: Host to bind to (default: 127.0.0.1)
  • --port: Port to listen on (default: 8080)
  • --endpoint: Endpoint path (default: /mcp)
  • --verbose: Enable verbose logging
  • --debug: Enable debug logging
  • --allow-remote: Allow remote connections

Protocol Support

MCPToolbox implements the MCP specification version 2025-11-25 with support for:

  • Streamable HTTP Transport (POST/GET/DELETE on single endpoint)
  • Server-Sent Events for server-to-client messages
  • Session management with MCP-Session-Id headers
  • Tools, Resources, Resource Templates, and Prompts
  • Elicitation for server-initiated user input requests

License

See LICENSE file for license information.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages