swift-context-protocol
Categories
Language:
Swift
Stars:
0
Forks:
0
swift-context-protocol
A distributed context protocol implementation for Swift.
swift-context-protocol is a Swift-based implementation of the Model Context Protocol (MCP) for AI contexts. It leverages Swift’s distributed actor model to enable type-safe, asynchronous remote invocation of tools, resources, and prompts.
Features
-
Distributed Context Protocol
Define a common interface (ContextProtocol
) for operations like ping, initialize, complete, set logging level, resource reading, tool calling, and prompt execution. -
Tool, Resource, and Prompt Protocols
Provide standardized protocols for:- Tool: Executes a specific operation using JSON schema validated inputs.
- Resource: Represents a resource identified by a URI, supporting asynchronous read operations.
- Prompt: Generates prompt templates or responses based on input parameters.
-
JSON Schema Support
Input and output formats can be validated and described using JSONSchema. -
Distributed Actors
Leverages Swift’s new distributed actor model (withWebSocketActorSystem
) to allow remote invocation of protocol methods. -
Capability Negotiation & Initialization
Exchange client and server information along with supported capabilities during the initialization handshake.
Installation
Add the following dependency to your Package.swift
:
dependencies: [
.package(url: "https://github.com/1amageek/swift-context-protocol.git", from: "1.0.0")
]
Then add "swift-context-protocol"
to your target dependencies.
Usage
Creating a Custom Tool
Implement the Tool
protocol to create a custom tool. For example, here's a simple echo tool that returns the input string:
import Foundation
import JSONSchema
import ContextProtocol
/// A simple tool that echoes the provided input.
public struct EchoTool: Tool {
public typealias Input = Envelop
public typealias Output = String
public var name: String = "echo"
public var description: String = "A tool that echoes the provided input."
public var inputSchema: JSONSchema? = .string()
public var guide: String? = """
# Tool Name
EchoTool
## Description
This tool echoes back the input string provided to it.
## Parameters
- `input`: The string to be echoed.
- **Type**: `String`
- **Description**: The input text that will be returned as output.
## Usage
Provide a valid string as input.
## Example
```swift
let input = "Hello, world!"
// EchoTool returns: "Hello, world!"
```
"""
public func run(_ input: Envelop) async throws -> String {
return input.data
}
}
Registering Components and Starting the Server
Create a distributed actor (e.g., ContextActor
) that implements the ContextProtocol
and registers your tools, resources, and prompts.
import Foundation
import Distributed
import WebSocketActors
import ContextProtocol
@main
struct Boot {
static func main() async throws {
let server = ContextServer()
server.setTools([ EchoTool() ])
try await server.start()
}
}
Connecting a Client
You can connect to the server using a client wrapper like ContextClient
:
import Foundation
import Distributed
import ContextProtocol
@main
struct ClientBoot {
static func main() async throws {
let client = try await ContextClient.connectServer()
let data = Envelop(data: "Hello, World!")
let parameters = try JSONEncoder().encode(data)
let toolResponse = try await client.session.callTool(
name: "echo",
parameters: parameters
)
print(toolResponse)
}
}
During connection, the client performs an initialization handshake where it sends its information and capabilities and receives server details and instructions. A cool connection banner is printed on success.
API Overview
ContextProtocol
The distributed actor protocol defines methods for:
- initialize: Handshake with client info and capabilities.
- ping: Simple connectivity check.
- complete: Trigger completion logic.
- setLoggingLevel: Adjust logging level.
- getPrompt: Request a prompt.
- listPrompts: List available prompt templates.
- listResources: Retrieve a list of resources.
- readResource: Read resource content (returns a
ResourceContentData
enum). - subscribeResource / unsubscribeResource: Manage resource subscriptions.
- callTool: Call a tool and receive its output as a
ResourceContentData
enum. - listTools: Retrieve a list of tools.
- sendRootsListChanged: Notify changes in the root resource list.
Domain Types
- ServerInfo / ClientInfo: Exchange basic identity and versioning information.
- CapabilityConfig: Key-value settings indicating supported capabilities.
- ResourceContentData: An enum (e.g.,
.text(String)
or.binary(Data)
) to represent resource contents. - ToolResponse / PromptResponse / ResourceResponse: DTOs used to list available tools, prompts, and resources.
- **ListResponse**: A generic wrapper for lists.
Contributing
Contributions are welcome! Please open issues or pull requests on GitHub.
License
This project is licensed under the MIT License.