1. Conduid
  2. Developer Tools
  3. Swift Fast MCP
MCP server · Developer Tools

Swift Fast MCP

The fastest way to build MCP servers in Swift.

Unclaimed MIT last commit 6 months ago swiftmodel-context-protocolmacosmcpdevtoolslinux
59Fair

Scored 3 months ago · breakdown

About Swift Fast MCP

Swift Fast MCP is an MCP server published by mehmetbaykar in the Developer Tools category: the fastest way to build MCP servers in Swift. It has been installed 0 times through Conduid.

The repository has 5 stars and 1 forks, with the last commit 6 months ago. Six months or more without a commit doesn't mean the server is broken, but check the open issues (0) before depending on it in production.

Install

Install
npx swift-fast-mcp

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

Ask AI about Swift Fast MCP

Powered by Claude · Grounded in docs

I know everything about Swift Fast MCP. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

  • ·README presentNot checked yet.
  • ·License declaredNot checked yet.
  • ·Tests presentNot checked yet.
  • ·Dependencies pinnedNot checked yet.
  • ·No dynamic code executionNot checked yet.
  • !Scoped permissionsDoesn't declare a permission scope. Assume it can do anything its process can.

README

FastMCP

The fastest way to build MCP servers in Swift.


try await FastMCP.builder()
    .name("My Server")
    .addTools([WeatherTool()])
    .run()

Three lines to a working MCP server over stdio. Or serve over HTTP:

try await FastMCP.builder()
    .name("My Server")
    .addTools([WeatherTool()])
    .transport(.http(port: 8080))
    .run()

Or aggregate tools from another Streamable HTTP MCP server and expose them beside your local Swift tools:

try await FastMCP.builder()
    .name("Gateway")
    .addTools([WeatherTool()])
    .addUpstreamMCPServers([
        .streamableHTTP(
            name: "firecrawl",
            endpoint: URL(string: "https://mcp.firecrawl.dev/v2/mcp")!,
            headers: ["Authorization": "Bearer <token>"]
        )
    ])
    .run()

Installation

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/mehmetbaykar/swift-fast-mcp", from: "2.7.0")
]

Then add "FastMCP" as a dependency of your target:

.target(
    name: "MyServer",
    dependencies: [
        .product(name: "FastMCP", package: "swift-fast-mcp")
    ]
)

FastMCP pulls in these dependencies automatically:

FastMCPAIBridge is intentionally public and re-exported by FastMCP for advanced bridge testing and custom adapter use. Most applications should still prefer the builder APIs.

Quick Start

Stdio transport (default)

import FastMCP

@Tool("Get weather for a location")
struct WeatherTool {
    @Parameter("City or coordinates")
    var location: String = ""

    func execute() async throws -> String {
        "Weather in \(location): 22°C, Sunny"
    }
}

@main
struct MyServer {
    static func main() async throws {
        try await FastMCP.builder()
            .name("Weather Server")
            .addTools([WeatherTool()])
            .run()
    }
}

Connect it to Claude Desktop by adding to claude_desktop_config.json:

{
    "mcpServers": {
        "weather": {
            "command": "/path/to/my-server"
        }
    }
}

HTTP transport

@main
struct MyServer {
    static func main() async throws {
        try await FastMCP.builder()
            .name("Weather Server")
            .addTools([WeatherTool()])
            .transport(.http(port: 8080))
            .run()
        // Listening on http://127.0.0.1:8080/mcp
    }
}

Transport Options

public enum Transport: Sendable {
    case stdio
    case inMemory
    case http(
        mode: HTTPMode = .stateful,
        host: String = "127.0.0.1",
        port: Int = 3000,
        endpoint: String = "/mcp"
    )
    case custom(MCP.Transport)
}
Transport Use Case
.stdio Claude Desktop, CLI tools. Default.
.inMemory Unit testing.
.http(...) Remote servers, multi-client access, web deployments.
.custom(transport) Provide your own MCP.Transport implementation.

HTTPMode

public enum HTTPMode: Sendable {
    case stateful
    case stateless
}

Stateful (default) -- Full MCP Streamable HTTP. Each client gets a session with SSE streaming, resumability via Last-Event-ID, GET for server-initiated messages, and DELETE for session teardown.

Stateless -- Minimal HTTP. No sessions, direct JSON responses, POST only. Use when session management is handled externally or not needed.

// Stateful (default)
.transport(.http(port: 8080))
.transport(.http(mode: .stateful, host: "0.0.0.0", port: 3000, endpoint: "/mcp"))

// Stateless
.transport(.http(mode: .stateless, port: 8080))

Builder API

All builder methods return a new Builder (value semantics) and can be chained.

Server metadata

.name("My Server")               // Server name (default: process name)
.version("2.7.0")                // Server version (default: "1.0.0")
.title("My Display Name")        // Human-readable display name for UIs
.instructions("Use this server to...") // Instructions for LLM clients
.icons([...])                     // Server icons for display in UIs

Capabilities

try FastMCP.builder()
    .addTools([WeatherTool(), MathTool(), StructuredSearchTool()])   // Register tool implementations
    .addUpstreamMCPServers([                  // Proxy Streamable HTTP upstream tools as docs_*
        .streamableHTTP(name: "docs", endpoint: docsMCPURL)
    ])
    .addResources([ConfigResource()])         // Register resource implementations
    .addPrompts([GreetingPrompt()])           // Register prompt implementations
    .enableCompletions()                      // Advertise completions capability
    .enableLogging()                          // Advertise logging capability

Duplicate upstream server names and tool names fail early. Resources and prompts are deduplicated automatically; the first registration wins.

Deferred SwiftAIHub tool sources resolve asynchronously, so addTools(_:) is also available as an async throws builder call:

import FastMCP

try await FastMCP.builder()
    .addTools(localOrDeferredToolSource)
    .run()

Use addUpstreamMCPServers(...) when you want FastMCP to act as an MCP gateway for remote MCP tools while preserving their MCP descriptors and call results.

Transport and infrastructure

.transport(.stdio)                       // Transport selection (default: .stdio)
.logger(myLogger)                        // Custom swift-log Logger
.shutdownSignals([.sigterm, .sigint])    // Unix signals for graceful shutdown (default: both)

Lifecycle hooks

Under .stdio (the default), stdout carries JSON-RPC frames — do not use print in hooks. Route messages through the injected Logger instead (swift-log's default handler writes to stderr). Under .http, either approach is safe.

.onStart { logger.info("Server started") }
.onShutdown { logger.info("Server stopped") }
.onInitialize { clientInfo, capabilities in
    // Called when a client sends an initialize request.
    // Receives Client.Info and Client.Capabilities.
    // Useful for auth checks, logging, per-client setup.
    // Especially valuable for HTTP where multiple clients connect.
    logger.info("Client: \(clientInfo.name) v\(clientInfo.version)")
}

HTTP-specific configuration

.sessionTimeout(.seconds(1800))          // Idle session timeout (default: 3600s)
                                          // Only applies to .http with .stateful mode.

.httpValidation(
    allowedOrigins: ["https://example.com"],  // Allowed Origin headers (default: localhost only)
    customValidators: [MyAuthValidator()]     // Custom HTTPRequestValidator implementations
)

Running

.run()  // Starts the server and blocks until shutdown

HTTP Transport

Multi-session model

In stateful HTTP mode, each connecting client gets its own independent Server + Transport pair. The server manages session lifecycle automatically.

Session lifecycle (stateful mode)

  1. Client sends POST to /mcp with an initialize JSON-RPC request (no session header).
  2. Server creates a new StatefulHTTPServerTransport + Server pair, registers all tools/resources/prompts.
  3. Transport generates a session ID, returned in the Mcp-Session-Id response header.
  4. Subsequent requests include this header and are routed to the matching session.
  5. Client sends DELETE to terminate the session.
  6. A cleanup loop runs every 60 seconds, removing sessions idle longer than sessionTimeout.

Stateless mode

  1. Client sends POST to /mcp with a JSON-RPC request.
  2. Server responds with direct JSON. No SSE, no session headers, no session tracking.

Validation pipeline

The HTTP server validates incoming requests before processing. By default, only localhost origins are allowed.

To allow remote origins or add custom validation (e.g., bearer token auth), use .httpValidation():

.httpValidation(
    allowedOrigins: ["https://myapp.com", "https://staging.myapp.com"],
    customValidators: [BearerTokenValidator(expectedToken: "...")]
)

Custom validators conform to HTTPRequestValidator from the MCP SDK.

TLS

FastMCP does not handle TLS. Deploy behind a reverse proxy (nginx, Caddy) for HTTPS.

Tools

AI-callable functions with JSON Schema generated from either flat @Parameter stored properties plus execute(), or a nested @Generable Arguments struct plus execute(_:). The tool's name is derived from the struct name (MathToolmath) and its return type from the body of execute:

@Generable
enum Operation: String, CaseIterable {
    case add, subtract, multiply, divide
}

@Tool("Perform math operations")
struct MathTool {
    @Generable
    struct Arguments {
        @Parameter("Operation") var operation: Operation
        @Parameter("First operand") var a: Double
        @Parameter("Second operand") var b: Double
    }

    func execute(_ arguments: Arguments) async throws -> String {
        let result = switch arguments.operation {
        case .add: arguments.a + arguments.b
        case .subtract: arguments.a - arguments.b
        case .multiply: arguments.a * arguments.b
        case .divide: arguments.a / arguments.b
        }
        return "Result: \(result)"
    }
}

Resources

Expose data to AI models:

@MCPResource(
    "config://app/settings",
    name: "App Settings",
    description: "Application configuration",
    mimeType: .applicationJSON
)
struct ConfigResource {
    @ResourceContentBuilder
    var content: Content {
        """
        {"theme": "dark", "version": "1.0.0"}
        """
    }
}

Prompts

Reusable conversation templates with typed arguments via @PromptArgument:

@MCPPrompt("A greeting template")
struct GreetingPrompt {
    @PromptArgument("Who to greet")
    var name: String

    @PromptArgument("Use formal tone")
    var formal: Bool = false

    func getMessages() async throws -> Messages {
        if formal {
            return [
                .user("You are a formal assistant helping \(name)."),
                .assistant("Good day, \(name). How may I assist you?"),
            ]
        } else {
            return [
                .user("You are a friendly assistant helping \(name)."),
                .assistant("Hey \(name)! What can I help you with?"),
            ]
        }
    }
}

Full Example

A complete stdio server with tools, resources, prompts, and lifecycle hooks — the canonical MCP setup for Claude Desktop and CLI clients that spawn the server as a subprocess. This matches the stdio transport/lifecycle pattern used in the shipped Sources/Example/ExampleServer.swift (which wires up its own tools and metadata). For an HTTP-specific variant (with .httpValidation, .sessionTimeout, etc.), see the HTTP transport section above.

import FastMCP
import Logging

@main
struct ExampleServer {
    static func main() async throws {
        let logger: Logger = {
            var log = Logger(label: "my-server")
            log.logLevel = .info
            return log
        }()

        try await FastMCP.builder()
            .name("Example Server")
            .title("Example MCP Server")
            .version("2.7.0")
            .instructions("This server provides weather, math, and structured search tools.")

            .addTools([WeatherTool(), MathTool(), StructuredSearchTool()])
            .addResources([ConfigResource()])
            .addPrompts([GreetingPrompt()])

            .enableCompletions()
            .enableLogging()

            .transport(.stdio)

            .logger(logger)
            .shutdownSignals([.sigterm, .sigint])

            // Stdio owns stdout for JSON-RPC framing — route lifecycle messages
            // through `logger` (stderr) so `print` never corrupts the wire.
            .onInitialize { clientInfo, _ in
                logger.info("Client connected: \(clientInfo.name) v\(clientInfo.version)")
            }
            .onStart {
                logger.info("Server started on stdio")
            }
            .onShutdown {
                logger.info("Server shutting down")
            }

            .run()
    }
}

Platform Support

  • macOS 14+
  • Linux (via #if canImport(FoundationNetworking) guards)
  • Swift 6.2+

Claude Code Integration

FastMCP ships with a Claude Code skill and a subagent that let Claude Code scaffold and build MCP server projects for you.

Setup

Copy the skills/ and .claude/ directories into your project:

# Copy the skill (project scaffolding)
cp -r skills/ .claude/skills/

# Copy the agent (expert assistance)
cp -r .claude/agents/ .claude/agents/

Usage

Scaffold a new project with the skill:

/swift-fast-mcp MyServer tools,resources,prompts

Claude generates a complete project with Package.swift, typed tools/resources/prompts, tests, and Claude Desktop configuration.

Get expert help with the subagent:

Claude automatically delegates to the swift-mcp-expert agent when you ask about @Tool, @MCPResource, @MCPPrompt implementations, the builder API, @Generable types, or testing patterns. You can also invoke it explicitly:

Use the swift-mcp-expert to help me build a weather tool

Documentation

  • docs/Tools.md — exposing @Tool structs from swift-ai-hub through an MCP server
  • docs/PromptsResources.md@MCPPrompt, @MCPResource, @PromptArgument, MCPResourceMimeType
  • docs/Transports.md — stdio, HTTP (stateful / stateless), in-memory, custom; httpValidation; ServiceGroup lifecycle
  • docs/DynamicServers.mdFastMCPServerHandle for adding / removing tools, resources, and prompts after run() starts

The @Tool, @Generable, @Parameter, and @Guide macros come from swift-ai-hub — see its docs/Macros.md for the macro reference.

License

MIT

README mirrored from the source repository 3 months ago. The original is authoritative.

Questions

About Swift Fast MCP

How do I install Swift Fast MCP?

Run npx swift-fast-mcp, then add the server to your MCP client's configuration. Conduid has recorded 0 installs, so the command is known to work with current clients.

Is Swift Fast MCP safe to use with an AI agent?

Its trust score is 59 out of 100 (fair). It passes 0 of 1 static security checks; the failures are listed above. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Swift Fast MCP still maintained?

The last commit was 6 months ago, with 0 open issues. That's long enough that you should check whether the maintainer is responding to issues before depending on it.