Add Swift MCP Server Development collection (#328)
- Add Swift MCP server best practices instruction - Add Swift MCP server project generator prompt - Add Swift MCP expert chat mode - Add Swift MCP development collection manifest - Update category READMEs Features: - Server setup with official Swift SDK package - Tool/resource/prompt handlers with withMethodHandler - Async/await and actor-based concurrency patterns - ServiceLifecycle integration for graceful shutdown - Stdio, HTTP, and network transport support - JSON schema construction with Value type - Swift 6.0+ with modern concurrency features - Platform support: macOS 13+, iOS 16+, Linux
This commit is contained in:
parent
f10bc70ce5
commit
616d8f14a7
@ -74,6 +74,7 @@ Custom chat modes define specific behaviors and tools for GitHub Copilot Chat, e
|
||||
| [Semantic Kernel Python mode instructions](chatmodes/semantic-kernel-python.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fsemantic-kernel-python.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fsemantic-kernel-python.chatmode.md) | Create, update, refactor, explain or work with code using the Python version of Semantic Kernel. |
|
||||
| [Software Engineer Agent v1](chatmodes/software-engineer-agent-v1.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fsoftware-engineer-agent-v1.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fsoftware-engineer-agent-v1.chatmode.md) | Expert-level software engineering agent. Deliver production-ready, maintainable code. Execute systematically and specification-driven. Document comprehensively. Operate autonomously and adaptively. |
|
||||
| [Specification mode instructions](chatmodes/specification.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fspecification.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fspecification.chatmode.md) | Generate or update specification documents for new or existing functionality. |
|
||||
| [Swift MCP Expert](chatmodes/swift-mcp-expert.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fswift-mcp-expert.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fswift-mcp-expert.chatmode.md) | Expert assistance for building Model Context Protocol servers in Swift using modern concurrency features and the official MCP Swift SDK. |
|
||||
| [Task Planner Instructions](chatmodes/task-planner.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Ftask-planner.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Ftask-planner.chatmode.md) | Task planner for creating actionable implementation plans - Brought to you by microsoft/edge-ai |
|
||||
| [Task Researcher Instructions](chatmodes/task-researcher.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Ftask-researcher.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Ftask-researcher.chatmode.md) | Task research specialist for comprehensive project analysis - Brought to you by microsoft/edge-ai |
|
||||
| [TDD Green Phase - Make Tests Pass Quickly](chatmodes/tdd-green.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Ftdd-green.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Ftdd-green.chatmode.md) | Implement minimal code to satisfy GitHub issue requirements and make failing tests pass without over-engineering. |
|
||||
|
||||
@ -31,6 +31,7 @@ Curated collections of related prompts, instructions, and chat modes organized a
|
||||
| [Project Planning & Management](collections/project-planning.md) | Tools and guidance for software project planning, feature breakdown, epic management, implementation planning, and task organization for development teams. | 17 items | planning, project-management, epic, feature, implementation, task, architecture, technical-spike |
|
||||
| [Python MCP Server Development](collections/python-mcp-development.md) | Complete toolkit for building Model Context Protocol (MCP) servers in Python using the official SDK with FastMCP. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 3 items | python, mcp, model-context-protocol, fastmcp, server-development |
|
||||
| [Security & Code Quality](collections/security-best-practices.md) | Security frameworks, accessibility guidelines, performance optimization, and code quality best practices for building secure, maintainable, and high-performance applications. | 6 items | security, accessibility, performance, code-quality, owasp, a11y, optimization, best-practices |
|
||||
| [Swift MCP Server Development](collections/swift-mcp-development.md) | 'Comprehensive collection for building Model Context Protocol servers in Swift using the official MCP Swift SDK with modern concurrency features.' | 3 items | swift, mcp, model-context-protocol, server-development, sdk, ios, macos, concurrency, actor, async-await |
|
||||
| [Tasks by microsoft/edge-ai](collections/edge-ai-tasks.md) | Task Researcher and Task Planner for intermediate to expert users and large codebases - Brought to you by microsoft/edge-ai | 3 items | architecture, planning, research, tasks, implementation |
|
||||
| [Technical Spike](collections/technical-spike.md) | Tools for creation, management and research of technical spikes to reduce unknowns and assumptions before proceeding to specification and implementation of solutions. | 2 items | technical-spike, assumption-testing, validation, research |
|
||||
| [Testing & Test Automation](collections/testing-automation.md) | Comprehensive collection for writing tests, test automation, and test-driven development including unit tests, integration tests, and end-to-end testing strategies. | 11 items | testing, tdd, automation, unit-tests, integration, playwright, jest, nunit |
|
||||
|
||||
@ -104,6 +104,7 @@ Team and project-specific instructions to enhance GitHub Copilot's behavior for
|
||||
| [Spring Boot Development](instructions/springboot.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fspringboot.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fspringboot.instructions.md) | Guidelines for building Spring Boot base applications |
|
||||
| [SQL Development](instructions/sql-sp-generation.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fsql-sp-generation.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fsql-sp-generation.instructions.md) | Guidelines for generating SQL statements and stored procedures |
|
||||
| [Svelte 5 and SvelteKit Development Instructions](instructions/svelte.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fsvelte.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fsvelte.instructions.md) | Svelte 5 and SvelteKit development standards and best practices for component-based user interfaces and full-stack applications |
|
||||
| [Swift MCP Server Development Guidelines](instructions/swift-mcp-server.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fswift-mcp-server.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fswift-mcp-server.instructions.md) | Best practices and patterns for building Model Context Protocol (MCP) servers in Swift using the official MCP Swift SDK package. |
|
||||
| [Taming Copilot](instructions/taming-copilot.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Ftaming-copilot.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Ftaming-copilot.instructions.md) | Prevent Copilot from wreaking havoc across your codebase, keeping it under control. |
|
||||
| [TanStack Start with Shadcn/ui Development Guide](instructions/tanstack-start-shadcn-tailwind.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Ftanstack-start-shadcn-tailwind.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Ftanstack-start-shadcn-tailwind.instructions.md) | Guidelines for building TanStack Start applications |
|
||||
| [Task Plan Implementation Instructions](instructions/task-implementation.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Ftask-implementation.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Ftask-implementation.instructions.md) | Instructions for implementing task plans with progressive tracking and change record - Brought to you by microsoft/edge-ai |
|
||||
|
||||
@ -106,6 +106,7 @@ Ready-to-use prompt templates for specific development scenarios and tasks, defi
|
||||
| [Suggest Awesome GitHub Copilot Custom Chat Modes](prompts/suggest-awesome-github-copilot-chatmodes.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fsuggest-awesome-github-copilot-chatmodes.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fsuggest-awesome-github-copilot-chatmodes.prompt.md) | Suggest relevant GitHub Copilot Custom Chat Modes files from the awesome-copilot repository based on current repository context and chat history, avoiding duplicates with existing custom chat modes in this repository. |
|
||||
| [Suggest Awesome GitHub Copilot Instructions](prompts/suggest-awesome-github-copilot-instructions.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fsuggest-awesome-github-copilot-instructions.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fsuggest-awesome-github-copilot-instructions.prompt.md) | Suggest relevant GitHub Copilot instruction files from the awesome-copilot repository based on current repository context and chat history, avoiding duplicates with existing instructions in this repository. |
|
||||
| [Suggest Awesome GitHub Copilot Prompts](prompts/suggest-awesome-github-copilot-prompts.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fsuggest-awesome-github-copilot-prompts.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fsuggest-awesome-github-copilot-prompts.prompt.md) | Suggest relevant GitHub Copilot prompt files from the awesome-copilot repository based on current repository context and chat history, avoiding duplicates with existing prompts in this repository. |
|
||||
| [Swift MCP Server Generator](prompts/swift-mcp-server-generator.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fswift-mcp-server-generator.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fswift-mcp-server-generator.prompt.md) | Generate a complete Model Context Protocol server project in Swift using the official MCP Swift SDK package. |
|
||||
| [Test Generation with Playwright MCP](prompts/playwright-generate-test.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fplaywright-generate-test.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fplaywright-generate-test.prompt.md) | Generate a Playwright test based on a scenario using Playwright MCP |
|
||||
| [Test Planning & Quality Assurance Prompt](prompts/breakdown-test.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fbreakdown-test.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fbreakdown-test.prompt.md) | Test Planning and Quality Assurance prompt that generates comprehensive test strategies, task breakdowns, and quality validation plans for GitHub projects. |
|
||||
| [TUnit Best Practices](prompts/csharp-tunit.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fcsharp-tunit.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fcsharp-tunit.prompt.md) | Get best practices for TUnit unit testing, including data-driven tests |
|
||||
|
||||
240
chatmodes/swift-mcp-expert.chatmode.md
Normal file
240
chatmodes/swift-mcp-expert.chatmode.md
Normal file
@ -0,0 +1,240 @@
|
||||
---
|
||||
description: 'Expert assistance for building Model Context Protocol servers in Swift using modern concurrency features and the official MCP Swift SDK.'
|
||||
model: GPT-4.1
|
||||
---
|
||||
|
||||
# Swift MCP Expert
|
||||
|
||||
I'm specialized in helping you build robust, production-ready MCP servers in Swift using the official Swift SDK. I can assist with:
|
||||
|
||||
## Core Capabilities
|
||||
|
||||
### Server Architecture
|
||||
- Setting up Server instances with proper capabilities
|
||||
- Configuring transport layers (Stdio, HTTP, Network, InMemory)
|
||||
- Implementing graceful shutdown with ServiceLifecycle
|
||||
- Actor-based state management for thread safety
|
||||
- Async/await patterns and structured concurrency
|
||||
|
||||
### Tool Development
|
||||
- Creating tool definitions with JSON schemas using Value type
|
||||
- Implementing tool handlers with CallTool
|
||||
- Parameter validation and error handling
|
||||
- Async tool execution patterns
|
||||
- Tool list changed notifications
|
||||
|
||||
### Resource Management
|
||||
- Defining resource URIs and metadata
|
||||
- Implementing ReadResource handlers
|
||||
- Managing resource subscriptions
|
||||
- Resource changed notifications
|
||||
- Multi-content responses (text, image, binary)
|
||||
|
||||
### Prompt Engineering
|
||||
- Creating prompt templates with arguments
|
||||
- Implementing GetPrompt handlers
|
||||
- Multi-turn conversation patterns
|
||||
- Dynamic prompt generation
|
||||
- Prompt list changed notifications
|
||||
|
||||
### Swift Concurrency
|
||||
- Actor isolation for thread-safe state
|
||||
- Async/await patterns
|
||||
- Task groups and structured concurrency
|
||||
- Cancellation handling
|
||||
- Error propagation
|
||||
|
||||
## Code Assistance
|
||||
|
||||
I can help you with:
|
||||
|
||||
### Project Setup
|
||||
```swift
|
||||
// Package.swift with MCP SDK
|
||||
.package(
|
||||
url: "https://github.com/modelcontextprotocol/swift-sdk.git",
|
||||
from: "0.10.0"
|
||||
)
|
||||
```
|
||||
|
||||
### Server Creation
|
||||
```swift
|
||||
let server = Server(
|
||||
name: "MyServer",
|
||||
version: "1.0.0",
|
||||
capabilities: .init(
|
||||
prompts: .init(listChanged: true),
|
||||
resources: .init(subscribe: true, listChanged: true),
|
||||
tools: .init(listChanged: true)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Handler Registration
|
||||
```swift
|
||||
await server.withMethodHandler(CallTool.self) { params in
|
||||
// Tool implementation
|
||||
}
|
||||
```
|
||||
|
||||
### Transport Configuration
|
||||
```swift
|
||||
let transport = StdioTransport(logger: logger)
|
||||
try await server.start(transport: transport)
|
||||
```
|
||||
|
||||
### ServiceLifecycle Integration
|
||||
```swift
|
||||
struct MCPService: Service {
|
||||
func run() async throws {
|
||||
try await server.start(transport: transport)
|
||||
}
|
||||
|
||||
func shutdown() async throws {
|
||||
await server.stop()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Actor-Based State
|
||||
Always use actors for shared mutable state:
|
||||
```swift
|
||||
actor ServerState {
|
||||
private var subscriptions: Set<String> = []
|
||||
|
||||
func addSubscription(_ uri: String) {
|
||||
subscriptions.insert(uri)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
Use proper Swift error handling:
|
||||
```swift
|
||||
do {
|
||||
let result = try performOperation()
|
||||
return .init(content: [.text(result)], isError: false)
|
||||
} catch let error as MCPError {
|
||||
return .init(content: [.text(error.localizedDescription)], isError: true)
|
||||
}
|
||||
```
|
||||
|
||||
### Logging
|
||||
Use structured logging with swift-log:
|
||||
```swift
|
||||
logger.info("Tool called", metadata: [
|
||||
"name": .string(params.name),
|
||||
"args": .string("\(params.arguments ?? [:])")
|
||||
])
|
||||
```
|
||||
|
||||
### JSON Schemas
|
||||
Use the Value type for schemas:
|
||||
```swift
|
||||
.object([
|
||||
"type": .string("object"),
|
||||
"properties": .object([
|
||||
"name": .object([
|
||||
"type": .string("string")
|
||||
])
|
||||
]),
|
||||
"required": .array([.string("name")])
|
||||
])
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Request/Response Handler
|
||||
```swift
|
||||
await server.withMethodHandler(CallTool.self) { params in
|
||||
guard let arg = params.arguments?["key"]?.stringValue else {
|
||||
throw MCPError.invalidParams("Missing key")
|
||||
}
|
||||
|
||||
let result = await processAsync(arg)
|
||||
|
||||
return .init(
|
||||
content: [.text(result)],
|
||||
isError: false
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Resource Subscription
|
||||
```swift
|
||||
await server.withMethodHandler(ResourceSubscribe.self) { params in
|
||||
await state.addSubscription(params.uri)
|
||||
logger.info("Subscribed to \(params.uri)")
|
||||
return .init()
|
||||
}
|
||||
```
|
||||
|
||||
### Concurrent Operations
|
||||
```swift
|
||||
async let result1 = fetchData1()
|
||||
async let result2 = fetchData2()
|
||||
let combined = await "\(result1) and \(result2)"
|
||||
```
|
||||
|
||||
### Initialize Hook
|
||||
```swift
|
||||
try await server.start(transport: transport) { clientInfo, capabilities in
|
||||
logger.info("Client: \(clientInfo.name) v\(clientInfo.version)")
|
||||
|
||||
if capabilities.sampling != nil {
|
||||
logger.info("Client supports sampling")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Platform Support
|
||||
|
||||
The Swift SDK supports:
|
||||
- macOS 13.0+
|
||||
- iOS 16.0+
|
||||
- watchOS 9.0+
|
||||
- tvOS 16.0+
|
||||
- visionOS 1.0+
|
||||
- Linux (glibc and musl)
|
||||
|
||||
## Testing
|
||||
|
||||
Write async tests:
|
||||
```swift
|
||||
func testTool() async throws {
|
||||
let params = CallTool.Params(
|
||||
name: "test",
|
||||
arguments: ["key": .string("value")]
|
||||
)
|
||||
|
||||
let result = await handleTool(params)
|
||||
XCTAssertFalse(result.isError ?? true)
|
||||
}
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
Enable debug logging:
|
||||
```swift
|
||||
var logger = Logger(label: "com.example.mcp-server")
|
||||
logger.logLevel = .debug
|
||||
```
|
||||
|
||||
## Ask Me About
|
||||
|
||||
- Server setup and configuration
|
||||
- Tool, resource, and prompt implementations
|
||||
- Swift concurrency patterns
|
||||
- Actor-based state management
|
||||
- ServiceLifecycle integration
|
||||
- Transport configuration (Stdio, HTTP, Network)
|
||||
- JSON schema construction
|
||||
- Error handling strategies
|
||||
- Testing async code
|
||||
- Platform-specific considerations
|
||||
- Performance optimization
|
||||
- Deployment strategies
|
||||
|
||||
I'm here to help you build efficient, safe, and idiomatic Swift MCP servers. What would you like to work on?
|
||||
35
collections/swift-mcp-development.collection.yml
Normal file
35
collections/swift-mcp-development.collection.yml
Normal file
@ -0,0 +1,35 @@
|
||||
id: swift-mcp-development
|
||||
name: Swift MCP Server Development
|
||||
description: 'Comprehensive collection for building Model Context Protocol servers in Swift using the official MCP Swift SDK with modern concurrency features.'
|
||||
tags: [swift, mcp, model-context-protocol, server-development, sdk, ios, macos, concurrency, actor, async-await]
|
||||
items:
|
||||
- path: instructions/swift-mcp-server.instructions.md
|
||||
kind: instruction
|
||||
- path: prompts/swift-mcp-server-generator.prompt.md
|
||||
kind: prompt
|
||||
- path: chatmodes/swift-mcp-expert.chatmode.md
|
||||
kind: chat-mode
|
||||
usage: |
|
||||
recommended
|
||||
|
||||
This chat mode provides expert guidance for building MCP servers in Swift.
|
||||
|
||||
This chat mode is ideal for:
|
||||
- Creating new MCP server projects with Swift
|
||||
- Implementing async/await patterns and actor-based concurrency
|
||||
- Setting up stdio, HTTP, or network transports
|
||||
- Debugging Swift concurrency and ServiceLifecycle integration
|
||||
- Learning Swift MCP best practices with the official SDK
|
||||
- Optimizing server performance for iOS/macOS platforms
|
||||
|
||||
To get the best results, consider:
|
||||
- Using the instruction file to set context for Swift MCP development
|
||||
- Using the prompt to generate initial project structure
|
||||
- Switching to the expert chat mode for detailed implementation help
|
||||
- Specifying whether you need stdio, HTTP, or network transport
|
||||
- Providing details about what tools or functionality you need
|
||||
- Mentioning if you need resources, prompts, or special capabilities
|
||||
|
||||
display:
|
||||
ordering: manual
|
||||
show_badge: true
|
||||
41
collections/swift-mcp-development.md
Normal file
41
collections/swift-mcp-development.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Swift MCP Server Development
|
||||
|
||||
'Comprehensive collection for building Model Context Protocol servers in Swift using the official MCP Swift SDK with modern concurrency features.'
|
||||
|
||||
**Tags:** swift, mcp, model-context-protocol, server-development, sdk, ios, macos, concurrency, actor, async-await
|
||||
|
||||
## Items in this Collection
|
||||
|
||||
| Title | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| [Swift MCP Server Development Guidelines](../instructions/swift-mcp-server.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fswift-mcp-server.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fswift-mcp-server.instructions.md) | Instruction | Best practices and patterns for building Model Context Protocol (MCP) servers in Swift using the official MCP Swift SDK package. |
|
||||
| [Swift MCP Server Generator](../prompts/swift-mcp-server-generator.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fswift-mcp-server-generator.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fswift-mcp-server-generator.prompt.md) | Prompt | Generate a complete Model Context Protocol server project in Swift using the official MCP Swift SDK package. |
|
||||
| [Swift MCP Expert](../chatmodes/swift-mcp-expert.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fswift-mcp-expert.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fswift-mcp-expert.chatmode.md) | Chat Mode | Expert assistance for building Model Context Protocol servers in Swift using modern concurrency features and the official MCP Swift SDK. [see usage](#swift-mcp-expert) |
|
||||
|
||||
## Collection Usage
|
||||
|
||||
### Swift MCP Expert
|
||||
|
||||
recommended
|
||||
|
||||
This chat mode provides expert guidance for building MCP servers in Swift.
|
||||
|
||||
This chat mode is ideal for:
|
||||
- Creating new MCP server projects with Swift
|
||||
- Implementing async/await patterns and actor-based concurrency
|
||||
- Setting up stdio, HTTP, or network transports
|
||||
- Debugging Swift concurrency and ServiceLifecycle integration
|
||||
- Learning Swift MCP best practices with the official SDK
|
||||
- Optimizing server performance for iOS/macOS platforms
|
||||
|
||||
To get the best results, consider:
|
||||
- Using the instruction file to set context for Swift MCP development
|
||||
- Using the prompt to generate initial project structure
|
||||
- Switching to the expert chat mode for detailed implementation help
|
||||
- Specifying whether you need stdio, HTTP, or network transport
|
||||
- Providing details about what tools or functionality you need
|
||||
- Mentioning if you need resources, prompts, or special capabilities
|
||||
|
||||
---
|
||||
|
||||
*This collection includes 3 curated items for swift mcp server development.*
|
||||
498
instructions/swift-mcp-server.instructions.md
Normal file
498
instructions/swift-mcp-server.instructions.md
Normal file
@ -0,0 +1,498 @@
|
||||
---
|
||||
description: 'Best practices and patterns for building Model Context Protocol (MCP) servers in Swift using the official MCP Swift SDK package.'
|
||||
applyTo: "**/*.swift, **/Package.swift, **/Package.resolved"
|
||||
---
|
||||
|
||||
# Swift MCP Server Development Guidelines
|
||||
|
||||
When building MCP servers in Swift, follow these best practices and patterns using the official Swift SDK.
|
||||
|
||||
## Server Setup
|
||||
|
||||
Create an MCP server using the `Server` class with capabilities:
|
||||
|
||||
```swift
|
||||
import MCP
|
||||
|
||||
let server = Server(
|
||||
name: "MyServer",
|
||||
version: "1.0.0",
|
||||
capabilities: .init(
|
||||
prompts: .init(listChanged: true),
|
||||
resources: .init(subscribe: true, listChanged: true),
|
||||
tools: .init(listChanged: true)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Adding Tools
|
||||
|
||||
Use `withMethodHandler` to register tool handlers:
|
||||
|
||||
```swift
|
||||
// Register tool list handler
|
||||
await server.withMethodHandler(ListTools.self) { _ in
|
||||
let tools = [
|
||||
Tool(
|
||||
name: "search",
|
||||
description: "Search for information",
|
||||
inputSchema: .object([
|
||||
"properties": .object([
|
||||
"query": .string("Search query"),
|
||||
"limit": .number("Maximum results")
|
||||
]),
|
||||
"required": .array([.string("query")])
|
||||
])
|
||||
)
|
||||
]
|
||||
return .init(tools: tools)
|
||||
}
|
||||
|
||||
// Register tool call handler
|
||||
await server.withMethodHandler(CallTool.self) { params in
|
||||
switch params.name {
|
||||
case "search":
|
||||
let query = params.arguments?["query"]?.stringValue ?? ""
|
||||
let limit = params.arguments?["limit"]?.intValue ?? 10
|
||||
|
||||
// Perform search
|
||||
let results = performSearch(query: query, limit: limit)
|
||||
|
||||
return .init(
|
||||
content: [.text("Found \(results.count) results")],
|
||||
isError: false
|
||||
)
|
||||
|
||||
default:
|
||||
return .init(
|
||||
content: [.text("Unknown tool")],
|
||||
isError: true
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Adding Resources
|
||||
|
||||
Implement resource handlers for data access:
|
||||
|
||||
```swift
|
||||
// Register resource list handler
|
||||
await server.withMethodHandler(ListResources.self) { params in
|
||||
let resources = [
|
||||
Resource(
|
||||
name: "Data File",
|
||||
uri: "resource://data/example.txt",
|
||||
description: "Example data file",
|
||||
mimeType: "text/plain"
|
||||
)
|
||||
]
|
||||
return .init(resources: resources, nextCursor: nil)
|
||||
}
|
||||
|
||||
// Register resource read handler
|
||||
await server.withMethodHandler(ReadResource.self) { params in
|
||||
switch params.uri {
|
||||
case "resource://data/example.txt":
|
||||
let content = loadResourceContent(uri: params.uri)
|
||||
return .init(contents: [
|
||||
Resource.Content.text(
|
||||
content,
|
||||
uri: params.uri,
|
||||
mimeType: "text/plain"
|
||||
)
|
||||
])
|
||||
|
||||
default:
|
||||
throw MCPError.invalidParams("Unknown resource URI: \(params.uri)")
|
||||
}
|
||||
}
|
||||
|
||||
// Register resource subscribe handler
|
||||
await server.withMethodHandler(ResourceSubscribe.self) { params in
|
||||
// Track subscription for notifications
|
||||
subscriptions.insert(params.uri)
|
||||
print("Client subscribed to \(params.uri)")
|
||||
return .init()
|
||||
}
|
||||
```
|
||||
|
||||
## Adding Prompts
|
||||
|
||||
Implement prompt handlers for templated conversations:
|
||||
|
||||
```swift
|
||||
// Register prompt list handler
|
||||
await server.withMethodHandler(ListPrompts.self) { params in
|
||||
let prompts = [
|
||||
Prompt(
|
||||
name: "analyze",
|
||||
description: "Analyze a topic",
|
||||
arguments: [
|
||||
.init(name: "topic", description: "Topic to analyze", required: true),
|
||||
.init(name: "depth", description: "Analysis depth", required: false)
|
||||
]
|
||||
)
|
||||
]
|
||||
return .init(prompts: prompts, nextCursor: nil)
|
||||
}
|
||||
|
||||
// Register prompt get handler
|
||||
await server.withMethodHandler(GetPrompt.self) { params in
|
||||
switch params.name {
|
||||
case "analyze":
|
||||
let topic = params.arguments?["topic"]?.stringValue ?? "general"
|
||||
let depth = params.arguments?["depth"]?.stringValue ?? "basic"
|
||||
|
||||
let description = "Analysis of \(topic) at \(depth) level"
|
||||
let messages: [Prompt.Message] = [
|
||||
.user("Please analyze this topic: \(topic)"),
|
||||
.assistant("I'll provide a \(depth) analysis of \(topic)")
|
||||
]
|
||||
|
||||
return .init(description: description, messages: messages)
|
||||
|
||||
default:
|
||||
throw MCPError.invalidParams("Unknown prompt: \(params.name)")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Transport Configuration
|
||||
|
||||
### Stdio Transport
|
||||
|
||||
For local subprocess communication:
|
||||
|
||||
```swift
|
||||
import MCP
|
||||
import Logging
|
||||
|
||||
let logger = Logger(label: "com.example.mcp-server")
|
||||
let transport = StdioTransport(logger: logger)
|
||||
|
||||
try await server.start(transport: transport)
|
||||
```
|
||||
|
||||
### HTTP Transport (Client Side)
|
||||
|
||||
For remote server connections:
|
||||
|
||||
```swift
|
||||
let transport = HTTPClientTransport(
|
||||
endpoint: URL(string: "http://localhost:8080")!,
|
||||
streaming: true // Enable Server-Sent Events
|
||||
)
|
||||
|
||||
try await client.connect(transport: transport)
|
||||
```
|
||||
|
||||
## Concurrency and Actors
|
||||
|
||||
The server is an actor, ensuring thread-safe access:
|
||||
|
||||
```swift
|
||||
actor ServerState {
|
||||
private var subscriptions: Set<String> = []
|
||||
private var cache: [String: Any] = [:]
|
||||
|
||||
func addSubscription(_ uri: String) {
|
||||
subscriptions.insert(uri)
|
||||
}
|
||||
|
||||
func getSubscriptions() -> Set<String> {
|
||||
return subscriptions
|
||||
}
|
||||
}
|
||||
|
||||
let state = ServerState()
|
||||
|
||||
await server.withMethodHandler(ResourceSubscribe.self) { params in
|
||||
await state.addSubscription(params.uri)
|
||||
return .init()
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
Use Swift's error handling with `MCPError`:
|
||||
|
||||
```swift
|
||||
await server.withMethodHandler(CallTool.self) { params in
|
||||
do {
|
||||
guard let query = params.arguments?["query"]?.stringValue else {
|
||||
throw MCPError.invalidParams("Missing query parameter")
|
||||
}
|
||||
|
||||
let result = try performOperation(query: query)
|
||||
|
||||
return .init(
|
||||
content: [.text(result)],
|
||||
isError: false
|
||||
)
|
||||
} catch let error as MCPError {
|
||||
return .init(
|
||||
content: [.text(error.localizedDescription)],
|
||||
isError: true
|
||||
)
|
||||
} catch {
|
||||
return .init(
|
||||
content: [.text("Unexpected error: \(error.localizedDescription)")],
|
||||
isError: true
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## JSON Schema with Value Type
|
||||
|
||||
Use the `Value` type for JSON schemas:
|
||||
|
||||
```swift
|
||||
let schema = Value.object([
|
||||
"type": .string("object"),
|
||||
"properties": .object([
|
||||
"name": .object([
|
||||
"type": .string("string"),
|
||||
"description": .string("User's name")
|
||||
]),
|
||||
"age": .object([
|
||||
"type": .string("integer"),
|
||||
"minimum": .number(0),
|
||||
"maximum": .number(150)
|
||||
]),
|
||||
"email": .object([
|
||||
"type": .string("string"),
|
||||
"format": .string("email")
|
||||
])
|
||||
]),
|
||||
"required": .array([.string("name")])
|
||||
])
|
||||
```
|
||||
|
||||
## Swift Package Manager Setup
|
||||
|
||||
Create your `Package.swift`:
|
||||
|
||||
```swift
|
||||
// swift-tools-version: 6.0
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "MyMCPServer",
|
||||
platforms: [
|
||||
.macOS(.v13),
|
||||
.iOS(.v16)
|
||||
],
|
||||
dependencies: [
|
||||
.package(
|
||||
url: "https://github.com/modelcontextprotocol/swift-sdk.git",
|
||||
from: "0.10.0"
|
||||
),
|
||||
.package(
|
||||
url: "https://github.com/apple/swift-log.git",
|
||||
from: "1.5.0"
|
||||
)
|
||||
],
|
||||
targets: [
|
||||
.executableTarget(
|
||||
name: "MyMCPServer",
|
||||
dependencies: [
|
||||
.product(name: "MCP", package: "swift-sdk"),
|
||||
.product(name: "Logging", package: "swift-log")
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Graceful Shutdown with ServiceLifecycle
|
||||
|
||||
Use Swift Service Lifecycle for proper shutdown:
|
||||
|
||||
```swift
|
||||
import MCP
|
||||
import ServiceLifecycle
|
||||
import Logging
|
||||
|
||||
struct MCPService: Service {
|
||||
let server: Server
|
||||
let transport: Transport
|
||||
|
||||
func run() async throws {
|
||||
try await server.start(transport: transport)
|
||||
try await Task.sleep(for: .days(365 * 100))
|
||||
}
|
||||
|
||||
func shutdown() async throws {
|
||||
await server.stop()
|
||||
}
|
||||
}
|
||||
|
||||
let logger = Logger(label: "com.example.mcp-server")
|
||||
let transport = StdioTransport(logger: logger)
|
||||
let mcpService = MCPService(server: server, transport: transport)
|
||||
|
||||
let serviceGroup = ServiceGroup(
|
||||
services: [mcpService],
|
||||
configuration: .init(
|
||||
gracefulShutdownSignals: [.sigterm, .sigint]
|
||||
),
|
||||
logger: logger
|
||||
)
|
||||
|
||||
try await serviceGroup.run()
|
||||
```
|
||||
|
||||
## Async/Await Patterns
|
||||
|
||||
All server operations use Swift concurrency:
|
||||
|
||||
```swift
|
||||
await server.withMethodHandler(CallTool.self) { params in
|
||||
async let result1 = fetchData1()
|
||||
async let result2 = fetchData2()
|
||||
|
||||
let combined = await "\(result1) and \(result2)"
|
||||
|
||||
return .init(
|
||||
content: [.text(combined)],
|
||||
isError: false
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Logging
|
||||
|
||||
Use swift-log for structured logging:
|
||||
|
||||
```swift
|
||||
import Logging
|
||||
|
||||
let logger = Logger(label: "com.example.mcp-server")
|
||||
|
||||
await server.withMethodHandler(CallTool.self) { params in
|
||||
logger.info("Tool called", metadata: [
|
||||
"name": .string(params.name),
|
||||
"args": .string("\(params.arguments ?? [:])")
|
||||
])
|
||||
|
||||
// Process tool call
|
||||
|
||||
logger.debug("Tool completed successfully")
|
||||
|
||||
return .init(content: [.text("Result")], isError: false)
|
||||
}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Test your server with async/await:
|
||||
|
||||
```swift
|
||||
import XCTest
|
||||
@testable import MyMCPServer
|
||||
|
||||
final class ServerTests: XCTestCase {
|
||||
func testToolCall() async throws {
|
||||
let server = createTestServer()
|
||||
|
||||
// Test tool call logic
|
||||
let params = CallTool.Params(
|
||||
name: "search",
|
||||
arguments: ["query": .string("test")]
|
||||
)
|
||||
|
||||
// Verify behavior
|
||||
XCTAssertNoThrow(try await processToolCall(params))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Initialize Hook
|
||||
|
||||
Validate client connections with an initialize hook:
|
||||
|
||||
```swift
|
||||
try await server.start(transport: transport) { clientInfo, clientCapabilities in
|
||||
// Validate client
|
||||
guard clientInfo.name != "BlockedClient" else {
|
||||
throw MCPError.invalidRequest("Client not allowed")
|
||||
}
|
||||
|
||||
// Check capabilities
|
||||
if clientCapabilities.sampling == nil {
|
||||
logger.warning("Client doesn't support sampling")
|
||||
}
|
||||
|
||||
logger.info("Client connected", metadata: [
|
||||
"name": .string(clientInfo.name),
|
||||
"version": .string(clientInfo.version)
|
||||
])
|
||||
}
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Content Types
|
||||
|
||||
Handle different content types:
|
||||
|
||||
```swift
|
||||
return .init(
|
||||
content: [
|
||||
.text("Plain text response"),
|
||||
.image(imageData, mimeType: "image/png", metadata: [
|
||||
"width": 1024,
|
||||
"height": 768
|
||||
]),
|
||||
.resource(
|
||||
uri: "resource://data",
|
||||
mimeType: "application/json",
|
||||
text: jsonString
|
||||
)
|
||||
],
|
||||
isError: false
|
||||
)
|
||||
```
|
||||
|
||||
### Strict Configuration
|
||||
|
||||
Use strict mode to fail fast on missing capabilities:
|
||||
|
||||
```swift
|
||||
let client = Client(
|
||||
name: "StrictClient",
|
||||
version: "1.0.0",
|
||||
configuration: .strict
|
||||
)
|
||||
|
||||
// Will throw immediately if capability not available
|
||||
try await client.listTools()
|
||||
```
|
||||
|
||||
### Request Batching
|
||||
|
||||
Send multiple requests efficiently:
|
||||
|
||||
```swift
|
||||
var tasks: [Task<CallTool.Result, Error>] = []
|
||||
|
||||
try await client.withBatch { batch in
|
||||
for i in 0..<10 {
|
||||
tasks.append(
|
||||
try await batch.addRequest(
|
||||
CallTool.request(.init(
|
||||
name: "process",
|
||||
arguments: ["id": .number(Double(i))]
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
for (index, task) in tasks.enumerated() {
|
||||
let result = try await task.value
|
||||
print("\(index): \(result.content)")
|
||||
}
|
||||
```
|
||||
669
prompts/swift-mcp-server-generator.prompt.md
Normal file
669
prompts/swift-mcp-server-generator.prompt.md
Normal file
@ -0,0 +1,669 @@
|
||||
---
|
||||
description: 'Generate a complete Model Context Protocol server project in Swift using the official MCP Swift SDK package.'
|
||||
mode: agent
|
||||
---
|
||||
|
||||
# Swift MCP Server Generator
|
||||
|
||||
Generate a complete, production-ready MCP server in Swift using the official Swift SDK package.
|
||||
|
||||
## Project Generation
|
||||
|
||||
When asked to create a Swift MCP server, generate a complete project with this structure:
|
||||
|
||||
```
|
||||
my-mcp-server/
|
||||
├── Package.swift
|
||||
├── Sources/
|
||||
│ └── MyMCPServer/
|
||||
│ ├── main.swift
|
||||
│ ├── Server.swift
|
||||
│ ├── Tools/
|
||||
│ │ ├── ToolDefinitions.swift
|
||||
│ │ └── ToolHandlers.swift
|
||||
│ ├── Resources/
|
||||
│ │ ├── ResourceDefinitions.swift
|
||||
│ │ └── ResourceHandlers.swift
|
||||
│ └── Prompts/
|
||||
│ ├── PromptDefinitions.swift
|
||||
│ └── PromptHandlers.swift
|
||||
├── Tests/
|
||||
│ └── MyMCPServerTests/
|
||||
│ └── ServerTests.swift
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Package.swift Template
|
||||
|
||||
```swift
|
||||
// swift-tools-version: 6.0
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "MyMCPServer",
|
||||
platforms: [
|
||||
.macOS(.v13),
|
||||
.iOS(.v16),
|
||||
.watchOS(.v9),
|
||||
.tvOS(.v16),
|
||||
.visionOS(.v1)
|
||||
],
|
||||
dependencies: [
|
||||
.package(
|
||||
url: "https://github.com/modelcontextprotocol/swift-sdk.git",
|
||||
from: "0.10.0"
|
||||
),
|
||||
.package(
|
||||
url: "https://github.com/apple/swift-log.git",
|
||||
from: "1.5.0"
|
||||
),
|
||||
.package(
|
||||
url: "https://github.com/swift-server/swift-service-lifecycle.git",
|
||||
from: "2.0.0"
|
||||
)
|
||||
],
|
||||
targets: [
|
||||
.executableTarget(
|
||||
name: "MyMCPServer",
|
||||
dependencies: [
|
||||
.product(name: "MCP", package: "swift-sdk"),
|
||||
.product(name: "Logging", package: "swift-log"),
|
||||
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle")
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
name: "MyMCPServerTests",
|
||||
dependencies: ["MyMCPServer"]
|
||||
)
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## main.swift Template
|
||||
|
||||
```swift
|
||||
import MCP
|
||||
import Logging
|
||||
import ServiceLifecycle
|
||||
|
||||
struct MCPService: Service {
|
||||
let server: Server
|
||||
let transport: Transport
|
||||
|
||||
func run() async throws {
|
||||
try await server.start(transport: transport) { clientInfo, capabilities in
|
||||
logger.info("Client connected", metadata: [
|
||||
"name": .string(clientInfo.name),
|
||||
"version": .string(clientInfo.version)
|
||||
])
|
||||
}
|
||||
|
||||
// Keep service running
|
||||
try await Task.sleep(for: .days(365 * 100))
|
||||
}
|
||||
|
||||
func shutdown() async throws {
|
||||
logger.info("Shutting down MCP server")
|
||||
await server.stop()
|
||||
}
|
||||
}
|
||||
|
||||
var logger = Logger(label: "com.example.mcp-server")
|
||||
logger.logLevel = .info
|
||||
|
||||
do {
|
||||
let server = await createServer()
|
||||
let transport = StdioTransport(logger: logger)
|
||||
let service = MCPService(server: server, transport: transport)
|
||||
|
||||
let serviceGroup = ServiceGroup(
|
||||
services: [service],
|
||||
configuration: .init(
|
||||
gracefulShutdownSignals: [.sigterm, .sigint]
|
||||
),
|
||||
logger: logger
|
||||
)
|
||||
|
||||
try await serviceGroup.run()
|
||||
} catch {
|
||||
logger.error("Fatal error", metadata: ["error": .string("\(error)")])
|
||||
throw error
|
||||
}
|
||||
```
|
||||
|
||||
## Server.swift Template
|
||||
|
||||
```swift
|
||||
import MCP
|
||||
import Logging
|
||||
|
||||
func createServer() async -> Server {
|
||||
let server = Server(
|
||||
name: "MyMCPServer",
|
||||
version: "1.0.0",
|
||||
capabilities: .init(
|
||||
prompts: .init(listChanged: true),
|
||||
resources: .init(subscribe: true, listChanged: true),
|
||||
tools: .init(listChanged: true)
|
||||
)
|
||||
)
|
||||
|
||||
// Register tool handlers
|
||||
await registerToolHandlers(server: server)
|
||||
|
||||
// Register resource handlers
|
||||
await registerResourceHandlers(server: server)
|
||||
|
||||
// Register prompt handlers
|
||||
await registerPromptHandlers(server: server)
|
||||
|
||||
return server
|
||||
}
|
||||
```
|
||||
|
||||
## ToolDefinitions.swift Template
|
||||
|
||||
```swift
|
||||
import MCP
|
||||
|
||||
func getToolDefinitions() -> [Tool] {
|
||||
[
|
||||
Tool(
|
||||
name: "greet",
|
||||
description: "Generate a greeting message",
|
||||
inputSchema: .object([
|
||||
"type": .string("object"),
|
||||
"properties": .object([
|
||||
"name": .object([
|
||||
"type": .string("string"),
|
||||
"description": .string("Name to greet")
|
||||
])
|
||||
]),
|
||||
"required": .array([.string("name")])
|
||||
])
|
||||
),
|
||||
Tool(
|
||||
name: "calculate",
|
||||
description: "Perform mathematical calculations",
|
||||
inputSchema: .object([
|
||||
"type": .string("object"),
|
||||
"properties": .object([
|
||||
"operation": .object([
|
||||
"type": .string("string"),
|
||||
"enum": .array([
|
||||
.string("add"),
|
||||
.string("subtract"),
|
||||
.string("multiply"),
|
||||
.string("divide")
|
||||
]),
|
||||
"description": .string("Operation to perform")
|
||||
]),
|
||||
"a": .object([
|
||||
"type": .string("number"),
|
||||
"description": .string("First operand")
|
||||
]),
|
||||
"b": .object([
|
||||
"type": .string("number"),
|
||||
"description": .string("Second operand")
|
||||
])
|
||||
]),
|
||||
"required": .array([
|
||||
.string("operation"),
|
||||
.string("a"),
|
||||
.string("b")
|
||||
])
|
||||
])
|
||||
)
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## ToolHandlers.swift Template
|
||||
|
||||
```swift
|
||||
import MCP
|
||||
import Logging
|
||||
|
||||
private let logger = Logger(label: "com.example.mcp-server.tools")
|
||||
|
||||
func registerToolHandlers(server: Server) async {
|
||||
await server.withMethodHandler(ListTools.self) { _ in
|
||||
logger.debug("Listing available tools")
|
||||
return .init(tools: getToolDefinitions())
|
||||
}
|
||||
|
||||
await server.withMethodHandler(CallTool.self) { params in
|
||||
logger.info("Tool called", metadata: ["name": .string(params.name)])
|
||||
|
||||
switch params.name {
|
||||
case "greet":
|
||||
return handleGreet(params: params)
|
||||
|
||||
case "calculate":
|
||||
return handleCalculate(params: params)
|
||||
|
||||
default:
|
||||
logger.warning("Unknown tool requested", metadata: ["name": .string(params.name)])
|
||||
return .init(
|
||||
content: [.text("Unknown tool: \(params.name)")],
|
||||
isError: true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleGreet(params: CallTool.Params) -> CallTool.Result {
|
||||
guard let name = params.arguments?["name"]?.stringValue else {
|
||||
return .init(
|
||||
content: [.text("Missing 'name' parameter")],
|
||||
isError: true
|
||||
)
|
||||
}
|
||||
|
||||
let greeting = "Hello, \(name)! Welcome to MCP."
|
||||
logger.debug("Generated greeting", metadata: ["name": .string(name)])
|
||||
|
||||
return .init(
|
||||
content: [.text(greeting)],
|
||||
isError: false
|
||||
)
|
||||
}
|
||||
|
||||
private func handleCalculate(params: CallTool.Params) -> CallTool.Result {
|
||||
guard let operation = params.arguments?["operation"]?.stringValue,
|
||||
let a = params.arguments?["a"]?.doubleValue,
|
||||
let b = params.arguments?["b"]?.doubleValue else {
|
||||
return .init(
|
||||
content: [.text("Missing or invalid parameters")],
|
||||
isError: true
|
||||
)
|
||||
}
|
||||
|
||||
let result: Double
|
||||
switch operation {
|
||||
case "add":
|
||||
result = a + b
|
||||
case "subtract":
|
||||
result = a - b
|
||||
case "multiply":
|
||||
result = a * b
|
||||
case "divide":
|
||||
guard b != 0 else {
|
||||
return .init(
|
||||
content: [.text("Division by zero")],
|
||||
isError: true
|
||||
)
|
||||
}
|
||||
result = a / b
|
||||
default:
|
||||
return .init(
|
||||
content: [.text("Unknown operation: \(operation)")],
|
||||
isError: true
|
||||
)
|
||||
}
|
||||
|
||||
logger.debug("Calculation performed", metadata: [
|
||||
"operation": .string(operation),
|
||||
"result": .string("\(result)")
|
||||
])
|
||||
|
||||
return .init(
|
||||
content: [.text("Result: \(result)")],
|
||||
isError: false
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## ResourceDefinitions.swift Template
|
||||
|
||||
```swift
|
||||
import MCP
|
||||
|
||||
func getResourceDefinitions() -> [Resource] {
|
||||
[
|
||||
Resource(
|
||||
name: "Example Data",
|
||||
uri: "resource://data/example",
|
||||
description: "Example resource data",
|
||||
mimeType: "application/json"
|
||||
),
|
||||
Resource(
|
||||
name: "Configuration",
|
||||
uri: "resource://config",
|
||||
description: "Server configuration",
|
||||
mimeType: "application/json"
|
||||
)
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## ResourceHandlers.swift Template
|
||||
|
||||
```swift
|
||||
import MCP
|
||||
import Logging
|
||||
import Foundation
|
||||
|
||||
private let logger = Logger(label: "com.example.mcp-server.resources")
|
||||
|
||||
actor ResourceState {
|
||||
private var subscriptions: Set<String> = []
|
||||
|
||||
func addSubscription(_ uri: String) {
|
||||
subscriptions.insert(uri)
|
||||
}
|
||||
|
||||
func removeSubscription(_ uri: String) {
|
||||
subscriptions.remove(uri)
|
||||
}
|
||||
|
||||
func isSubscribed(_ uri: String) -> Bool {
|
||||
subscriptions.contains(uri)
|
||||
}
|
||||
}
|
||||
|
||||
private let state = ResourceState()
|
||||
|
||||
func registerResourceHandlers(server: Server) async {
|
||||
await server.withMethodHandler(ListResources.self) { params in
|
||||
logger.debug("Listing available resources")
|
||||
return .init(resources: getResourceDefinitions(), nextCursor: nil)
|
||||
}
|
||||
|
||||
await server.withMethodHandler(ReadResource.self) { params in
|
||||
logger.info("Reading resource", metadata: ["uri": .string(params.uri)])
|
||||
|
||||
switch params.uri {
|
||||
case "resource://data/example":
|
||||
let jsonData = """
|
||||
{
|
||||
"message": "Example resource data",
|
||||
"timestamp": "\(Date())"
|
||||
}
|
||||
"""
|
||||
return .init(contents: [
|
||||
.text(jsonData, uri: params.uri, mimeType: "application/json")
|
||||
])
|
||||
|
||||
case "resource://config":
|
||||
let config = """
|
||||
{
|
||||
"serverName": "MyMCPServer",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
"""
|
||||
return .init(contents: [
|
||||
.text(config, uri: params.uri, mimeType: "application/json")
|
||||
])
|
||||
|
||||
default:
|
||||
logger.warning("Unknown resource requested", metadata: ["uri": .string(params.uri)])
|
||||
throw MCPError.invalidParams("Unknown resource URI: \(params.uri)")
|
||||
}
|
||||
}
|
||||
|
||||
await server.withMethodHandler(ResourceSubscribe.self) { params in
|
||||
logger.info("Client subscribed to resource", metadata: ["uri": .string(params.uri)])
|
||||
await state.addSubscription(params.uri)
|
||||
return .init()
|
||||
}
|
||||
|
||||
await server.withMethodHandler(ResourceUnsubscribe.self) { params in
|
||||
logger.info("Client unsubscribed from resource", metadata: ["uri": .string(params.uri)])
|
||||
await state.removeSubscription(params.uri)
|
||||
return .init()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## PromptDefinitions.swift Template
|
||||
|
||||
```swift
|
||||
import MCP
|
||||
|
||||
func getPromptDefinitions() -> [Prompt] {
|
||||
[
|
||||
Prompt(
|
||||
name: "code-review",
|
||||
description: "Generate a code review prompt",
|
||||
arguments: [
|
||||
.init(name: "language", description: "Programming language", required: true),
|
||||
.init(name: "focus", description: "Review focus area", required: false)
|
||||
]
|
||||
)
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## PromptHandlers.swift Template
|
||||
|
||||
```swift
|
||||
import MCP
|
||||
import Logging
|
||||
|
||||
private let logger = Logger(label: "com.example.mcp-server.prompts")
|
||||
|
||||
func registerPromptHandlers(server: Server) async {
|
||||
await server.withMethodHandler(ListPrompts.self) { params in
|
||||
logger.debug("Listing available prompts")
|
||||
return .init(prompts: getPromptDefinitions(), nextCursor: nil)
|
||||
}
|
||||
|
||||
await server.withMethodHandler(GetPrompt.self) { params in
|
||||
logger.info("Getting prompt", metadata: ["name": .string(params.name)])
|
||||
|
||||
switch params.name {
|
||||
case "code-review":
|
||||
return handleCodeReviewPrompt(params: params)
|
||||
|
||||
default:
|
||||
logger.warning("Unknown prompt requested", metadata: ["name": .string(params.name)])
|
||||
throw MCPError.invalidParams("Unknown prompt: \(params.name)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleCodeReviewPrompt(params: GetPrompt.Params) -> GetPrompt.Result {
|
||||
guard let language = params.arguments?["language"]?.stringValue else {
|
||||
return .init(
|
||||
description: "Missing language parameter",
|
||||
messages: []
|
||||
)
|
||||
}
|
||||
|
||||
let focus = params.arguments?["focus"]?.stringValue ?? "general quality"
|
||||
|
||||
let description = "Code review for \(language) with focus on \(focus)"
|
||||
let messages: [Prompt.Message] = [
|
||||
.user("Please review this \(language) code with focus on \(focus)."),
|
||||
.assistant("I'll review the code focusing on \(focus). Please share the code."),
|
||||
.user("Here's the code to review: [paste code here]")
|
||||
]
|
||||
|
||||
logger.debug("Generated code review prompt", metadata: [
|
||||
"language": .string(language),
|
||||
"focus": .string(focus)
|
||||
])
|
||||
|
||||
return .init(description: description, messages: messages)
|
||||
}
|
||||
```
|
||||
|
||||
## ServerTests.swift Template
|
||||
|
||||
```swift
|
||||
import XCTest
|
||||
@testable import MyMCPServer
|
||||
|
||||
final class ServerTests: XCTestCase {
|
||||
func testGreetTool() async throws {
|
||||
let params = CallTool.Params(
|
||||
name: "greet",
|
||||
arguments: ["name": .string("Swift")]
|
||||
)
|
||||
|
||||
let result = handleGreet(params: params)
|
||||
|
||||
XCTAssertFalse(result.isError ?? true)
|
||||
XCTAssertEqual(result.content.count, 1)
|
||||
|
||||
if case .text(let message) = result.content[0] {
|
||||
XCTAssertTrue(message.contains("Swift"))
|
||||
} else {
|
||||
XCTFail("Expected text content")
|
||||
}
|
||||
}
|
||||
|
||||
func testCalculateTool() async throws {
|
||||
let params = CallTool.Params(
|
||||
name: "calculate",
|
||||
arguments: [
|
||||
"operation": .string("add"),
|
||||
"a": .number(5),
|
||||
"b": .number(3)
|
||||
]
|
||||
)
|
||||
|
||||
let result = handleCalculate(params: params)
|
||||
|
||||
XCTAssertFalse(result.isError ?? true)
|
||||
XCTAssertEqual(result.content.count, 1)
|
||||
|
||||
if case .text(let message) = result.content[0] {
|
||||
XCTAssertTrue(message.contains("8"))
|
||||
} else {
|
||||
XCTFail("Expected text content")
|
||||
}
|
||||
}
|
||||
|
||||
func testDivideByZero() async throws {
|
||||
let params = CallTool.Params(
|
||||
name: "calculate",
|
||||
arguments: [
|
||||
"operation": .string("divide"),
|
||||
"a": .number(10),
|
||||
"b": .number(0)
|
||||
]
|
||||
)
|
||||
|
||||
let result = handleCalculate(params: params)
|
||||
|
||||
XCTAssertTrue(result.isError ?? false)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## README.md Template
|
||||
|
||||
```markdown
|
||||
# MyMCPServer
|
||||
|
||||
A Model Context Protocol server built with Swift.
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ Tools: greet, calculate
|
||||
- ✅ Resources: example data, configuration
|
||||
- ✅ Prompts: code-review
|
||||
- ✅ Graceful shutdown with ServiceLifecycle
|
||||
- ✅ Structured logging with swift-log
|
||||
- ✅ Full test coverage
|
||||
|
||||
## Requirements
|
||||
|
||||
- Swift 6.0+
|
||||
- macOS 13+, iOS 16+, or Linux
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
swift build -c release
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Run the server:
|
||||
|
||||
```bash
|
||||
swift run
|
||||
```
|
||||
|
||||
Or with logging:
|
||||
|
||||
```bash
|
||||
LOG_LEVEL=debug swift run
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
swift test
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
The server uses:
|
||||
- [MCP Swift SDK](https://github.com/modelcontextprotocol/swift-sdk) - MCP protocol implementation
|
||||
- [swift-log](https://github.com/apple/swift-log) - Structured logging
|
||||
- [swift-service-lifecycle](https://github.com/swift-server/swift-service-lifecycle) - Graceful shutdown
|
||||
|
||||
## Project Structure
|
||||
|
||||
- `Sources/MyMCPServer/main.swift` - Entry point with ServiceLifecycle
|
||||
- `Sources/MyMCPServer/Server.swift` - Server configuration
|
||||
- `Sources/MyMCPServer/Tools/` - Tool definitions and handlers
|
||||
- `Sources/MyMCPServer/Resources/` - Resource definitions and handlers
|
||||
- `Sources/MyMCPServer/Prompts/` - Prompt definitions and handlers
|
||||
- `Tests/` - Unit tests
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
```
|
||||
|
||||
## Generation Instructions
|
||||
|
||||
1. **Ask for project name and description**
|
||||
2. **Generate all files** with proper naming
|
||||
3. **Use actor-based state** for thread safety
|
||||
4. **Include comprehensive logging** with swift-log
|
||||
5. **Implement graceful shutdown** with ServiceLifecycle
|
||||
6. **Add tests** for all handlers
|
||||
7. **Use modern Swift concurrency** (async/await)
|
||||
8. **Follow Swift naming conventions** (camelCase, PascalCase)
|
||||
9. **Include error handling** with proper MCPError usage
|
||||
10. **Document public APIs** with doc comments
|
||||
|
||||
## Build and Run
|
||||
|
||||
```bash
|
||||
# Build
|
||||
swift build
|
||||
|
||||
# Run
|
||||
swift run
|
||||
|
||||
# Test
|
||||
swift test
|
||||
|
||||
# Release build
|
||||
swift build -c release
|
||||
|
||||
# Install
|
||||
swift build -c release
|
||||
cp .build/release/MyMCPServer /usr/local/bin/
|
||||
```
|
||||
|
||||
## Integration with Claude Desktop
|
||||
|
||||
Add to `claude_desktop_config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"my-mcp-server": {
|
||||
"command": "/path/to/MyMCPServer"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Loading…
x
Reference in New Issue
Block a user