freshcrate
Skin:/
Home > Infrastructure > SwiftMCP

SwiftMCP

Model Context Protocol Server for Swift

Why this rank:Strong adoptionRecent releaseHealthy release cadence

Description

Model Context Protocol Server for Swift

README

SwiftMCP

A Swift implementation of the MCP (Model Context Protocol) for JSON-RPC over various transports.

Features

  • Multiple transport options
    • Standard I/O (stdio) for command-line usage
    • HTTP+SSE (Server-Sent Events) for web applications
    • TCP+Bonjour for local discovery over raw TCP
  • JSON-RPC 2.0 compliant with OpenAPI generation
  • Built-in authorization and optional OAuth validation
  • Transparent OAuth proxy mode for MCP and OpenAPI
  • Cross-platform compatibility

Server Features

  • Tools – expose functions with @MCPTool
  • Resources – publish data with @MCPResource
  • Prompts – build prompts using @MCPPrompt
  • Utilities
    • Progress notifications via RequestContext.current
    • Structured logging streamed through Session.current
    • Completion suggestions for parameters (defaults for Bool and CaseIterable)

Client Features

  • Roots – dynamic filesystem roots announced by the client
  • Sampling – request small previews of client files

Installation

Add SwiftMCP as a dependency in your Package.swift:

dependencies: [
    .package(url: "https://github.com/Cocoanetics/SwiftMCP.git", branch: "main")
]

Usage

Command Line Demo

The included demo application shows how to use SwiftMCP with different transport options:

# Using stdio transport
SwiftMCPDemo stdio

# Using HTTP+SSE transport
SwiftMCPDemo httpsse --port 8080

# Using HTTP+SSE with authorization
SwiftMCPDemo httpsse --port 8080 --token your-secret-token

# Using HTTP+SSE with OpenAPI support
SwiftMCPDemo httpsse --port 8080 --openapi

# Using HTTP+SSE with authorization and OpenAPI support
SwiftMCPDemo httpsse --port 8080 --token your-secret-token --openapi

# Using HTTP+SSE with OAuth (JSON config)
SwiftMCPDemo httpsse --port 8080 --oauth oauth-config-example.json

# Using TCP+Bonjour transport
SwiftMCPDemo tcp --name "SwiftMCP Demo"

# Using HTTP+SSE plus TCP+Bonjour in parallel
SwiftMCPDemo httpsse --port 8080 --tcp

When using HTTP+SSE transport with the --token option, clients must include an Authorization header with their requests:

Authorization: Bearer your-secret-token

OpenAPI support

The --openapi option enables OpenAPI endpoints for AI plugin integration. When this option is used, the server will provide an OpenAPI specification at /openapi.json and an AI plugin manifest at /.well-known/ai-plugin.json. This allows for easy integration with AI models and other tools that support OpenAPI.

OAuth support

When HTTPSSETransport is configured with OAuthConfiguration, the transport validates incoming bearer tokens through the configured OAuth provider. Validation can use an introspection endpoint or by checking JWT claims against the provider's JWKS when introspection is not available. The transport also serves metadata at /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource for discovery by clients.

Progress, Logging, Roots and Sampling

SwiftMCP can send progress updates while a tool is running, stream structured log messages to connected clients, handle dynamic filesystem roots announced by the client and request small data samples for preview. See the demo server for simple implementations of these features. The doc:ServerCapabilities and doc:Sampling articles describe the APIs in detail.

Custom Server Implementation

To implement your own MCP server:

  1. Attach the @MCPServer macro to a reference type like class or actor
  2. Define your tools using @MCPTool attribute
  3. Choose and configure a transport (stdio, HTTP+SSE, or TCP+Bonjour)

Example:

@MCPServer
class MyServer {
    @MCPTool
    func add(a: Int, b: Int) -> Int {
        return a + b
    }
}

// Using HTTP+SSE transport with authorization
let server = MyServer()
let transport = HTTPSSETransport(server: server, port: 8080)

// Optional: Add authorization
transport.authorizationHandler = { token in
    guard let token = token, token == "your-secret-token" else {
        return .unauthorized("Invalid token")
    }
    return .authorized
}

// Or configure OAuth validation
transport.oauthConfiguration = OAuthConfiguration(
    issuer: URL(string: "https://example.com")!,
    authorizationEndpoint: URL(string: "https://example.com/authorize")!,
    tokenEndpoint: URL(string: "https://example.com/oauth/token")!,
    introspectionEndpoint: URL(string: "https://example.com/oauth/introspect")!,
    jwksEndpoint: URL(string: "https://example.com/.well-known/jwks.json")!,
    audience: "your-api-identifier",
    clientID: "client",
    clientSecret: "secret"
)

try transport.run()

To serve TCP+Bonjour instead:

let server = MyServer()
let tcpTransport = TCPBonjourTransport(server: server)
try await tcpTransport.run()

Typed Client Proxy

SwiftMCP can generate a typed client proxy for any server. This proxy mirrors the @MCPTool, @MCPResource, and @MCPPrompt signatures and forwards calls through MCPServerProxy. Enable it with generateClient: true on the server macro.

@MCPServer(generateClient: true)
actor Calculator {
    @MCPTool
    func add(a: Int, b: Int) -> Int {
        a + b
    }
}

let url = URL(string: "http://localhost:8080/sse")!
let config = MCPServerConfig.sse(config: MCPServerSseConfig(url: url))
let proxy = MCPServerProxy(config: config)
try await proxy.connect()

let client = Calculator.Client(proxy: proxy)
let result = try await client.add(a: 2, b: 3)

For TCP+Bonjour discovery:

let config = MCPServerConfig.tcp(config: MCPServerTcpConfig(serviceName: "SwiftMCP Demo"))
let proxy = MCPServerProxy(config: config)
try await proxy.connect()

Notes:

  • Client generation is opt-in (generateClient defaults to false).
  • Client methods always throw to surface transport or server errors.

Client Notification Handlers

MCPServerProxy can also surface typed JSON-RPC notifications from the server. Use setNotificationHandler(_:as:handler:) for custom app/domain events and use setLogNotificationHandler(_:) / setProgressNotificationHandler(_:) for the built-in convenience paths.

struct RunStatusUpdate: Codable, Sendable {
    let runID: String
    let status: String
}

await proxy.setNotificationHandler("notifications/runStatusChanged", as: RunStatusUpdate.self) { update in
    print("Run \(update.runID) is now \(update.status)")
}

SwiftMCPUtility Proxy Generation

Use SwiftMCPUtility generate-proxy to create a client proxy for any MCP server, including non-SwiftMCP servers. The generated proxy calls MCPServerProxy under the hood, generates typed tool methods from MCP tool schemas, and adds first-class resource/prompt convenience APIs when the server advertises those capabilities. Input parameters are inferred from the server's tool schemas, and only string formats such as date-time, uri, uuid, and byte can be mapped to native types (Date, URL, UUID, Data).

SwiftMCPUtility generate-proxy --sse http://localhost:8080/sse -o ToolsProxy.swift

All generated methods are async throws so transport and server errors are surfaced.

OpenAPI Return Types

If the MCP server exposes an OpenAPI JSON document, pass its URL (or file path) to --openapi to enrich return types. The generator overlays OpenAPI response schemas onto the MCP tool list, produces Codable structs/enums for structured responses, and uses those types in the proxy's return signatures.

SwiftMCPUtility generate-proxy \
  --sse http://localhost:8080/sse \
  --openapi http://localhost:8080/openapi.json \
  -o ToolsProxy.swift

The generated Codable types can be used as-is or replaced with your own models later if you have local definitions.

Documentation Extraction

The @MCPServer and @MCPTool macros extract documentation comments to describe class, parameters and return value.

Macros Functionality

The macros in this repository provide functionality for defining and exposing tools and servers in the SwiftMCP framework. Here are the main functionalities of the macros:

  • @MCPServer: This macro is used to define a class or actor as an MCP server. It extracts the server description from documentation comments (or the optional description: override). An example of its usage can be seen in the Demos/SwiftMCPDemo/Calculator.swift file, where the Calculator actor is annotated with @MCPServer(name: "SwiftMCP Demo").
  • @MCPTool: This macro is used to define functions within an MCP server that can be called as tools. It also extracts documentation comments to describe the function, parameters, and return values. Examples of its usage can be seen in the Demos/SwiftMCPDemo/Calculator.swift file, where various functions such as add, subtract, testArray, multiply, divide, greet, ping, and noop are annotated with @MCPTool.
  • @MCPResource: This macro is used to expose read-only data through URI templates. Resources allow clients to access data using structured URIs with path and query parameters. The macro automatically generates the necessary infrastructure to match URIs against templates and extract parameters.

Using @MCPResource

The @MCPResource macro allows you to expose functions as resources that can be accessed via URI patterns:

@MCPServer(name: "ResourceServer")
actor ResourceServer {
    /// Get user profile by ID
    @MCPResource("users://{user_id}/profile")
    func getUserProfile(user_id: Int) -> String {
        return "Profile for user \(user_id)"
    }
    
    /// Search users with pagination
    @MCPResource("users://search?q={query}&page={page}", mimeType: "application/json")
    func searchUsers(query: String, page: Int = 1) -> String {
        return """
        {"query": "\(query)", "page": \(page), "results": [...]}
        """
    }
}

Key features:

  • URI Templates: Define patterns with placeholders in curly braces {param}
  • Path Parameters: Extract values from the URI path (e.g., /users/{id})
  • Query Parameters: Extract values from query strings (e.g., ?page={page})
  • Optional Parameters: Support default values for optional parameters
  • MIME Types: Optionally specify content type with mimeType parameter
  • Type Safety: Parameters are automatically converted to the correct Swift types

The server automatically provides:

  • Resource discovery through mcpResourceTemplates
  • URI matching and parameter extraction
  • Type conversion and validation
  • Error handling for missing or invalid parameters

These macros help in automatically generating the necessary metadata and documentation for the MCP server and its tools, making it easier to expose them for JSON-RPC communication and integration with AI models.

License

This project is licensed under the BSD 2-clause License - see the LICENSE file for details.

Release History

VersionChangesUrgencyDate
v1.4.7This release brings SwiftMCP to Windows and Android, extracts a standalone `JSONValue` product, lets `@MCPExtension` attach to actor hosts, and hardens the streamable-HTTP client against session loss. ## Highlights **`@MCPExtension` on actor hosts (#124)** `@MCPExtension` now works when the host type is an `actor`, not just a class. Actor hosts get actor-isolated storage and metadata accessors (the executor serializes register / register-while-dispatch); class hosts keep their original non-isoHigh6/2/2026
v1.4.6Widen the swift-syntax dependency range from `from: "602.0.0-latest"` (capped at `<603.0.0`) to `"602.0.0-latest"..<"604.0.0"` so SwiftMCP coexists with consumers on either major — notably SwiftScript, which requires swift-syntax 603.x. ## Full Changelog https://github.com/Cocoanetics/SwiftMCP/compare/v1.4.5...v1.4.6High5/19/2026
v1.4.5## SwiftMCP 1.4.5 SwiftMCP 1.4.5 ships the `@MCPExtension` macro for splitting tools, resources, and prompts across files and targets, fixes a `@MCPServer` macro-expansion regression that broke any tool whose doc comments contained `*/` (re-tag of v1.4.5 — see below), and broadens platform reach. ### Highlights - **`@MCPExtension` — split a server across files and modules** - Annotate an `extension <YourServer>` in any module with `@MCPExtension` to contribute tools, resources, and prompts High5/16/2026
v1.4.4## SwiftMCP 1.4.4 SwiftMCP 1.4.4 is a transport and protocol correctness release, with one deliberate cleanup: the experimental binary upload path has been removed now that custom HTTP routes cover that use case more cleanly. ### Highlights - **Removed the experimental binary upload feature** - removed `MCPFileUploadHandling` - removed the built-in `/mcp/uploads/:cid` route and `cid:` placeholder flow - removed `experimental.uploads`, proxy upload helpers, and related client-side argumenHigh4/30/2026
v1.4.3## SwiftMCP 1.4.3 SwiftMCP 1.4.3 is a focused follow-up release centered on HTTP transport internals and session metadata. ### Highlights - **Refactored HTTP transport into routable units** - split the previous monolithic HTTP handler into logical route-focused components - introduced typed route request/response primitives - clarified separation between MCP routes, legacy SSE, uploads, OpenAPI, and OAuth handling - **Improved HTTP-layer testability** - route behavior is easier to valHigh4/2/2026
v1.4.2## SwiftMCP 1.4.2 ### 🔄 Early-Arrival Upload Support (#103) - **Race-safe uploads**: binary `POST /mcp/uploads/{cid}` can now arrive *before* the tool call registers the CID expectation — the file is buffered and delivered when the tool call catches up - **`FulfillResult` enum**: `fulfill()` now returns `.fulfilled`, `.earlyArrival`, or `.missed` — callers only delete temp files on `.missed`, preserving early arrivals - **Expiry cleanup**: early arrivals older than 60 seconds are automaticallyMedium3/24/2026
v1.4.1## SwiftMCP 1.4.1 Binary upload enhancements — zero-copy data delivery, streaming HTTP uploads, and a new file-based transport for local connections. ### 🚀 Zero-Copy Binary Side Channel - **`ResolvedUploads` task-local**: uploaded `Data` is now delivered directly to tool functions via a side channel, **bypassing the base64 encode → JSON → decode round-trip entirely** - `extractData(named:)` checks the side channel first, falls back to base64 only for legacy paths - Applies to both local file Low3/22/2026
v1.4.0## SwiftMCP 1.4.0 A major feature release adding binary file upload, client notifications & subscriptions, Xcode MCP compatibility, a naming system, and proxy generator improvements. ### 🆕 Binary File Upload (#73, #87) - **CID-based upload architecture**: clients send `cid:` placeholders in tool call arguments, upload files to `POST /mcp/uploads/{cid}` concurrently, and the server delivers data to the tool function transparently - **MCP progress notifications** during upload — uses the tool cLow3/17/2026
v1.2.1## Bug Fixes - #77: Fixed Bonjour listener retry with generation-based lifecycle to prevent mDNSResponder crashes - Restored bound port update on listener ready ## Improvements - More resilient Bonjour discovery under network changesLow3/15/2026
1.2.0## SwiftMCP 1.2.0 This release expands the SwiftMCP client surface and tightens the core JSON/sendability model. ### Highlights - **Client proxy improvements** - Added proxy support for MCP **resources** and **prompts** - Utility-generated proxies now emit the standard MCP resource/prompt APIs when supported - **Typed client notification pipeline** - Added typed notification handling in `MCPServerProxy` - Added first-class **progress notification** support - Unified log handling withLow3/11/2026
1.1.0## What's New ### Linux SSE Client Support (#63) The SSE/Streamable HTTP **client** (`MCPServerProxy`) now works on Linux. Previously it threw `unsupportedPlatform` at runtime because `URLSession.bytes(for:)` isn't available in `FoundationNetworking`. The new implementation uses a `URLSessionDataDelegate` that streams incoming bytes into an `AsyncStream<String>`, feeding the same `SSEMessageSequence` parser used on Apple platforms — so behavior is identical across platforms. ### Broadcast LogLow3/7/2026
1.0.0First stable release of SwiftMCP — a Swift implementation of the Model Context Protocol (MCP). **Highlights:** - Macro-driven API: `@MCPServer`, `@MCPTool`, `@MCPPrompt`, `@MCPResource` - Transports: stdio, HTTP+SSE/Streamable HTTP, TCP+Bonjour - JSON-RPC 2.0 with OpenAPI schema generation - Built-in OAuth validation and transparent proxy mode - SSE client support on both macOS and Linux - Swift 6 strict concurrency compatible - Platforms: macOS, iOS, tvOS, watchOS, LinuxLow3/6/2026

Dependencies & License Audit

Loading dependencies...

Similar Packages

Bedrock-Addon-WranglerđŸ› ī¸ Manage Minecraft Bedrock addons easily with Bedrock-Addon-Wrangler. Simplify formats, resolve UUID issues, and streamline your server experience.main@2026-06-07
CodexSkillManager🛠 Manage Codex and Claude Code skills on macOS with this SwiftUI app. Browse, import, and delete skills effortlessly while viewing detailed info.main@2026-06-07
KirođŸ› ī¸ Streamline your development with Kiro, an agentic IDE that transforms prototypes into production using spec-driven methods and AI-powered coding support.main@2026-06-07
aio-coding-hub🚀 Streamline your AI CLI interactions with AIO Coding Hub, a unified gateway for Claude, Codex, and Gemini requests. Simplify setup and enhance stability.master@2026-06-07
che-apple-mail-mcp📧 Unlock Apple Mail's potential with 42 powerful tools for full scripting control, enabling advanced mailbox and email management.main@2026-06-07

More in Infrastructure

tensorzeroTensorZero is an open-source LLMOps platform that unifies an LLM gateway, observability, evaluation, optimization, and experimentation.
modelsThis repository contains comprehensive pricing and configuration data for LLMs. It powers cost attribution for 200+ enterprises running 400B+ tokens through Portkey AI Gateway every day.
edgeeOpen-source AI gateway written in Rust, with token compression for Claude Code, Codex... and any other LLM client.
patent_mcp_serverFastMCP Server for USPTO data