Skip to content

Commit b5692ff

Browse files
update mcp
1 parent 3a260a5 commit b5692ff

6 files changed

Lines changed: 1683 additions & 154 deletions

File tree

Package.swift

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ let package = Package(
1010
.visionOS(.v2)
1111
],
1212
products: [
13+
.library(name: "MCP", targets: ["MCP"]),
1314
.library(name: "AdaMCPCore", targets: ["AdaMCPCore"]),
1415
.library(name: "AdaMCPServer", targets: ["AdaMCPServer"]),
1516
.library(name: "AdaMCPPlugin", targets: ["AdaMCPPlugin"])
@@ -18,30 +19,32 @@ let package = Package(
1819
.package(url: "https://github.com/AdaEngine/AdaEngine", branch: "main"),
1920
.package(url: "https://github.com/apple/swift-distributed-tracing", from: "1.0.0"),
2021
.package(url: "https://github.com/apple/swift-system.git", from: "1.0.0"),
21-
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.0"),
22-
.package(url: "https://github.com/apple/swift-nio.git", from: "2.74.0"),
23-
.package(url: "https://github.com/modelcontextprotocol/swift-sdk.git", from: "0.11.0")
22+
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.0")
2423
],
2524
targets: [
25+
.target(
26+
name: "MCP",
27+
dependencies: [
28+
.product(name: "Logging", package: "swift-log"),
29+
.product(name: "SystemPackage", package: "swift-system")
30+
]
31+
),
2632
.target(
2733
name: "AdaMCPCore",
2834
dependencies: [
2935
.product(name: "AdaEngine", package: "AdaEngine"),
3036
.product(name: "InMemoryTracing", package: "swift-distributed-tracing"),
3137
.product(name: "Tracing", package: "swift-distributed-tracing"),
32-
.product(name: "MCP", package: "swift-sdk"),
38+
"MCP",
3339
.product(name: "Logging", package: "swift-log")
3440
]
3541
),
3642
.target(
3743
name: "AdaMCPServer",
3844
dependencies: [
3945
"AdaMCPCore",
40-
.product(name: "MCP", package: "swift-sdk"),
41-
.product(name: "Logging", package: "swift-log"),
42-
.product(name: "NIOCore", package: "swift-nio"),
43-
.product(name: "NIOPosix", package: "swift-nio"),
44-
.product(name: "NIOHTTP1", package: "swift-nio")
46+
"MCP",
47+
.product(name: "Logging", package: "swift-log")
4548
]
4649
),
4750
.target(
@@ -62,7 +65,7 @@ let package = Package(
6265
.product(name: "AdaEngine", package: "AdaEngine"),
6366
.product(name: "InMemoryTracing", package: "swift-distributed-tracing"),
6467
.product(name: "Tracing", package: "swift-distributed-tracing"),
65-
.product(name: "MCP", package: "swift-sdk"),
68+
"MCP",
6669
.product(name: "SystemPackage", package: "swift-system")
6770
],
6871
path: "Tests/AdaMCPTests"

Sources/AdaMCPCore/AdaMCPRuntime.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,11 @@ public final class AdaMCPRuntime {
610610
?? .init(content: [.text(text: mcpError.localizedDescription, annotations: nil, _meta: nil)], isError: true)
611611
}
612612

613-
return .init(content: [.text(text: error.localizedDescription, annotations: nil, _meta: nil)], isError: true)
613+
return (try? self.jsonToolResult([
614+
"code": "internal_error",
615+
"message": .string(error.localizedDescription)
616+
], isError: true))
617+
?? .init(content: [.text(text: error.localizedDescription, annotations: nil, _meta: nil)], isError: true)
614618
}
615619
}
616620

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#if !(canImport(CoreGraphics) && canImport(ImageIO))
2+
import AdaEngine
3+
import Foundation
4+
5+
private enum AdaMCPPNGEncodingError: LocalizedError {
6+
case unsupportedFormat(Image.Format)
7+
8+
var errorDescription: String? {
9+
switch self {
10+
case .unsupportedFormat(let format):
11+
"Unsupported image format for PNG encoding: \(format)"
12+
}
13+
}
14+
}
15+
16+
public extension Image {
17+
func writePNG(to url: URL) throws {
18+
let data = try self.adamcpPNGData()
19+
try data.write(to: url, options: .atomic)
20+
}
21+
22+
private func adamcpPNGData() throws -> Data {
23+
let rgbaData = try self.adamcpRGBAData()
24+
var scanlines = Data(capacity: (width * 4 + 1) * height)
25+
for row in 0..<height {
26+
scanlines.append(0)
27+
let start = row * width * 4
28+
scanlines.append(rgbaData.subdata(in: start..<(start + width * 4)))
29+
}
30+
31+
var png = Data([137, 80, 78, 71, 13, 10, 26, 10])
32+
png.append(Self.adamcpPNGChunk(type: "IHDR", data: Self.adamcpIHDR(width: width, height: height)))
33+
png.append(Self.adamcpPNGChunk(type: "IDAT", data: Self.adamcpZlibStoredData(scanlines)))
34+
png.append(Self.adamcpPNGChunk(type: "IEND", data: Data()))
35+
return png
36+
}
37+
38+
private func adamcpRGBAData() throws -> Data {
39+
switch format {
40+
case .rgba8:
41+
return data
42+
case .bgra8, .bgra8_sRGB:
43+
var result = data
44+
result.withUnsafeMutableBytes { bytes in
45+
guard let base = bytes.baseAddress?.assumingMemoryBound(to: UInt8.self) else {
46+
return
47+
}
48+
for offset in stride(from: 0, to: bytes.count, by: 4) {
49+
let blue = base[offset]
50+
base[offset] = base[offset + 2]
51+
base[offset + 2] = blue
52+
}
53+
}
54+
return result
55+
case .rgb8:
56+
var result = Data(capacity: width * height * 4)
57+
for offset in stride(from: 0, to: data.count, by: 3) {
58+
result.append(data[offset])
59+
result.append(data[offset + 1])
60+
result.append(data[offset + 2])
61+
result.append(255)
62+
}
63+
return result
64+
case .gray:
65+
var result = Data(capacity: width * height * 4)
66+
for value in data {
67+
result.append(value)
68+
result.append(value)
69+
result.append(value)
70+
result.append(255)
71+
}
72+
return result
73+
}
74+
}
75+
76+
private static func adamcpIHDR(width: Int, height: Int) -> Data {
77+
var data = Data()
78+
data.appendUInt32BE(UInt32(width))
79+
data.appendUInt32BE(UInt32(height))
80+
data.append(contentsOf: [8, 6, 0, 0, 0])
81+
return data
82+
}
83+
84+
private static func adamcpPNGChunk(type: String, data: Data) -> Data {
85+
var chunk = Data()
86+
chunk.appendUInt32BE(UInt32(data.count))
87+
let typeData = Data(type.utf8)
88+
chunk.append(typeData)
89+
chunk.append(data)
90+
91+
var crcInput = Data()
92+
crcInput.append(typeData)
93+
crcInput.append(data)
94+
chunk.appendUInt32BE(crcInput.crc32())
95+
return chunk
96+
}
97+
98+
private static func adamcpZlibStoredData(_ data: Data) -> Data {
99+
var result = Data([0x78, 0x01])
100+
var offset = 0
101+
while offset < data.count {
102+
let remaining = data.count - offset
103+
let length = min(remaining, 65_535)
104+
let isFinal = offset + length == data.count
105+
result.append(isFinal ? 0x01 : 0x00)
106+
let len = UInt16(length)
107+
let nlen = ~len
108+
result.append(UInt8(len & 0xff))
109+
result.append(UInt8((len >> 8) & 0xff))
110+
result.append(UInt8(nlen & 0xff))
111+
result.append(UInt8((nlen >> 8) & 0xff))
112+
result.append(data.subdata(in: offset..<(offset + length)))
113+
offset += length
114+
}
115+
result.appendUInt32BE(data.adler32())
116+
return result
117+
}
118+
}
119+
120+
private extension Data {
121+
mutating func appendUInt32BE(_ value: UInt32) {
122+
append(UInt8((value >> 24) & 0xff))
123+
append(UInt8((value >> 16) & 0xff))
124+
append(UInt8((value >> 8) & 0xff))
125+
append(UInt8(value & 0xff))
126+
}
127+
128+
func adler32() -> UInt32 {
129+
var a: UInt32 = 1
130+
var b: UInt32 = 0
131+
for byte in self {
132+
a = (a + UInt32(byte)) % 65_521
133+
b = (b + a) % 65_521
134+
}
135+
return (b << 16) | a
136+
}
137+
138+
func crc32() -> UInt32 {
139+
var crc: UInt32 = 0xffff_ffff
140+
for byte in self {
141+
crc ^= UInt32(byte)
142+
for _ in 0..<8 {
143+
let mask = 0 &- (crc & 1)
144+
crc = (crc >> 1) ^ (0xedb8_8320 & mask)
145+
}
146+
}
147+
return ~crc
148+
}
149+
}
150+
#endif

0 commit comments

Comments
 (0)