Skip to content

Commit 693a6c9

Browse files
committed
Added license, updated readme
1 parent 1a7a632 commit 693a6c9

File tree

2 files changed

+105
-128
lines changed

2 files changed

+105
-128
lines changed

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Copyright (c) 2025, Oliver Drobnik All rights reserved.
2+
3+
Redistribution and use in source and binary forms, with or without
4+
modification, are permitted provided that the following conditions are met:
5+
6+
- Redistributions of source code must retain the above copyright notice, this
7+
list of conditions and the following disclaimer.
8+
9+
- Redistributions in binary form must reproduce the above copyright notice,
10+
this list of conditions and the following disclaimer in the documentation
11+
and/or other materials provided with the distribution.
12+
13+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
17+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 83 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,175 +1,130 @@
11
# SwiftMCP
22

3-
SwiftMCP is a Swift package that provides a way to generate JSON descriptions of functions for use in a Multi-Call Protocol (MCP) system. It uses Swift macros to extract function metadata at compile time.
3+
SwiftMCP is a Swift library that makes supporting the Model Context Protocol (MCP) easy. It uses Swift macros to automatically extract function metadata and generate the necessary JSON-RPC interface for MCP communication.
4+
5+
## What is MCP?
6+
7+
The Model Context Protocol (MCP) is a standardized way for AI models to interact with external tools and services. SwiftMCP makes it simple to expose your Swift functions as MCP-compatible tools that can be called by AI models.
8+
9+
## MCP Transport Modes
10+
11+
MCP supports two transport modes:
12+
13+
- **stdio mode** ✅ - Fully implemented in SwiftMCP
14+
- Communication happens over standard input/output
15+
- Simple to implement and use for command-line tools
16+
- Perfect for local development and testing
17+
18+
- **HTTP+SSE mode** ⏳ - Not yet implemented
19+
- Communication over HTTP with Server-Sent Events
20+
- Better for networked applications and services
21+
- Coming in a future release
422

523
## Features
624

7-
- Automatically extracts function parameter types and return types
8-
- Generates JSON descriptions of functions with proper type information
9-
- Supports parameters with default values
10-
- Handles numeric default values correctly in JSON output
11-
- Simple to use with Swift macros
12-
- Command-line interface for one-off testing and interactive mode
25+
- **Simple Macro-Based API**: Just add `@MCPServer` and `@MCPTool` annotations to your code
26+
- **Automatic Documentation Extraction**: Parameter names, types, and descriptions are extracted from your Swift documentation
27+
- **JSON-RPC Interface**: Fully compliant with the MCP specification
28+
- **Type Safety**: Leverages Swift's type system for safe parameter handling
29+
- **Default Values Support**: Handles parameters with default values
30+
- **Command-Line Interface**: Ready-to-use CLI for testing and integration
31+
32+
## Quick Start
1333

14-
## Usage
34+
Here's how to create an MCP-compatible server in just a few lines of code:
1535

1636
```swift
1737
import SwiftMCP
1838

19-
@MCPServer
39+
// 1. Annotate your class with @MCPServer
40+
@MCPServer(name: "MyCalculator", version: "1.0.0")
2041
class Calculator {
42+
// 2. Add documentation comments that describe your function and parameters
2143
/// Adds two integers and returns their sum
2244
/// - Parameter a: First number to add
2345
/// - Parameter b: Second number to add
2446
/// - Returns: The sum of a and b
47+
// 3. Annotate your function with @MCPTool
2548
@MCPTool
2649
func add(a: Int, b: Int) -> Int {
2750
return a + b
2851
}
2952

30-
/// Subtracts the second integer from the first and returns the difference
31-
/// - Parameter a: Number to subtract from
32-
/// - Parameter b: Number to subtract (defaults to 3)
33-
/// - Returns: The difference between a and b
53+
/// Divides the numerator by the denominator
54+
/// - Parameter numerator: Number to be divided
55+
/// - Parameter denominator: Number to divide by (defaults to 1.0)
56+
/// - Returns: The quotient of numerator divided by denominator
3457
@MCPTool
35-
func subtract(a: Int, b: Int = 3) -> Int {
36-
return a - b
58+
func divide(numerator: Double, denominator: Double = 1.0) -> Double {
59+
return numerator / denominator
3760
}
3861
}
3962

40-
// Get JSON descriptions of all functions
41-
let tools = calculator.mcpTools
42-
let json = MCPTool.encodeToJSON(tools)
43-
print(json)
63+
// 4. That's it! Your class now has MCP capabilities
64+
let calculator = Calculator()
65+
66+
// Process MCP requests
67+
let request = JSONRPCRequest(
68+
jsonrpc: "2.0",
69+
id: 1,
70+
method: "tools/call",
71+
params: [
72+
"name": AnyCodable("add"),
73+
"arguments": AnyCodable(["a": 5, "b": 3])
74+
]
75+
)
76+
77+
// The response will be a properly formatted MCP response
78+
let response = calculator.handleRequest(request)
4479
```
4580

46-
The `MCPTool` macro automatically:
47-
- Extracts parameter names and types from the function declaration
48-
- Captures documentation comments for descriptions
49-
- Detects default parameter values
50-
- Generates metadata at compile time
51-
52-
The `@MCPTool` macro adds a `mcpTools` computed property that collects all the function metadata and converts it to a format suitable for JSON encoding.
53-
54-
## JSON Output
55-
56-
The generated JSON includes detailed information about each function, including parameter types, descriptions, and default values:
57-
58-
```json
59-
[
60-
{
61-
"description": "Adds two integers and returns their sum",
62-
"inputSchema": {
63-
"properties": {
64-
"a": {
65-
"description": "First number to add",
66-
"type": "number"
67-
},
68-
"b": {
69-
"description": "Second number to add",
70-
"type": "number"
71-
}
72-
},
73-
"required": [
74-
"a",
75-
"b"
76-
],
77-
"type": "object"
78-
},
79-
"name": "add"
80-
},
81-
{
82-
"description": "Subtracts the second integer from the first and returns the difference",
83-
"inputSchema": {
84-
"properties": {
85-
"a": {
86-
"description": "Number to subtract from",
87-
"type": "number"
88-
},
89-
"b": {
90-
"default": 3,
91-
"description": "Number to subtract (defaults to 3)",
92-
"type": "number"
93-
}
94-
},
95-
"required": [
96-
"a"
97-
],
98-
"type": "object"
99-
},
100-
"name": "subtract"
101-
}
102-
]
103-
```
81+
## How It Works
10482

105-
## Command-Line Interface
83+
SwiftMCP uses Swift macros to analyze your code at compile time:
10684

107-
SwiftMCP includes a command-line interface for testing and interacting with your MCP tools. The CLI supports one-off requests, interactive mode, and continuous mode.
85+
1. **Documentation Extraction**: The `@MCPTool` macro extracts parameter names, types, and descriptions from your documentation comments
86+
2. **Schema Generation**: It automatically generates JSON Schema for your function parameters
87+
3. **Server Configuration**: The `@MCPServer` macro adds the necessary infrastructure to handle JSON-RPC requests
10888

109-
### One-Off Mode
89+
## JSON-RPC Interface
11090

111-
Process a single JSON-RPC request and exit:
91+
SwiftMCP implements the standard MCP JSON-RPC interface:
11292

113-
```bash
114-
# Process a single request
115-
echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "divide", "arguments": {"numerator": "10"}}}' | ./.build/debug/SwiftMCPDemo
116-
117-
# With verbose logging
118-
echo '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "add", "arguments": {"a": "5", "b": "7"}}}' | ./.build/debug/SwiftMCPDemo -v
119-
```
93+
- `initialize`: Sets up the connection and returns server capabilities
94+
- `tools/list`: Returns a list of available tools with their schemas
95+
- `tools/call`: Calls a specific tool with the provided arguments
12096

121-
### Interactive Mode
97+
## Command-Line Interface
12298

123-
Process multiple requests until EOF:
99+
SwiftMCP includes a ready-to-use command-line interface for stdio mode:
124100

125101
```bash
126-
# Start in interactive mode
127-
./.build/debug/SwiftMCPDemo --interactive
128-
129-
# Then input JSON-RPC requests one per line
130-
{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "divide", "arguments": {"numerator": "10"}}}
131-
{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "add", "arguments": {"a": "5", "b": "7"}}}
102+
# Process a single request
103+
echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "divide", "arguments": {"numerator": 10}}}' | swift run SwiftMCPDemo
132104
```
133105

134-
### Continuous Mode
135-
136-
Run indefinitely, processing requests as they arrive:
137-
138-
```bash
139-
# Start in continuous mode
140-
./.build/debug/SwiftMCPDemo --continuous
141-
142-
# The server will run indefinitely, waiting for input
143-
# You can send requests to it from another terminal or process
144-
```
106+
## Advanced Usage
145107

146-
For more reliable communication in continuous mode, you can use a named pipe:
108+
### Custom Tool Descriptions
147109

148-
```bash
149-
# In terminal 1 (create a named pipe and start the server)
150-
mkfifo /tmp/mcp_pipe
151-
cat /tmp/mcp_pipe | ./.build/debug/SwiftMCPDemo --continuous --verbose
110+
You can provide a custom description for a tool:
152111

153-
# In terminal 2 (send requests to the pipe)
154-
echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "divide", "arguments": {"numerator": "10"}}}' > /tmp/mcp_pipe
112+
```swift
113+
@MCPTool(description: "Custom description for this tool")
114+
func myFunction(param: String) -> String {
115+
// ...
116+
}
155117
```
156118

157-
This mode is useful for long-running services that need to process requests continuously without exiting.
119+
### Server Name and Version
158120

159-
### Command-Line Options
121+
Customize your server's name and version:
160122

161-
```
162-
USAGE: mcp [--interactive] [--continuous] [--input-file <input-file>] [--output-file <output-file>] [--verbose]
163-
164-
OPTIONS:
165-
--interactive Run in interactive mode, processing multiple requests until EOF
166-
--continuous Run in continuous mode, processing requests indefinitely without exiting
167-
-i, --input-file <input-file>
168-
The input file to read from (defaults to stdin)
169-
-o, --output-file <output-file>
170-
The output file to write to (defaults to stdout)
171-
-v, --verbose Enable verbose logging
172-
-h, --help Show help information.
123+
```swift
124+
@MCPServer(name: "MyCustomServer", version: "2.5.0")
125+
class MyServer {
126+
// ...
127+
}
173128
```
174129

175130
## Requirements

0 commit comments

Comments
 (0)