V0.11.x (#199)
* Support 2025-06-18 Spec (#167) * Support OpenAI _meta for Tool * Update init * Add title and outputSchema * Concurreny issue * General fields * Add Generate Fields to Server elements * 4 tab spacing * Update Version * Elicitation * Format * More tests and inits * Elicitation in README * Fix orphaned test * Add title to more structs * Public init * Fix meta validation and make tests more generic * Format and make Result properties public again * Revert more visibility changes * feat: 2025-11-25 phase 1, includes Version, Icon, Progress (#181) * chore: fixed unit tests * feat: added icon and progess base structs * feat: added progress notification and meta to callTool * feat: added tests * feat: simplified RequestMeta encoding/decoding * tests: added unit test to track progress * chore: rebased v0.11.x * feat: implemented cancellation * feat: added overloaded callTool method * fix: encoding Response _meta fix * chore: added old version to the versions list * feat: 2025-11-25 phase 2; added Logging and Completions (#196) * feat: added Logging and Completions * feat: updated EmbeddedResource for the latest spec * chore: changed encoding of meta in Prompts to encodeIfPresent * feat: compliance tests + http server transport (#197) * feat: http server transport * feat: added http server transport * feat: removed unused files * feat: added conformance tests * feat: improved conformace testing * chore: removed redundant files * feat/2025-11-25: sampling, elicitation, roots (#198) * feat: Roots implementation * feat: added unit testing * feat: improved unit tests and fixed NetworkTransport crash * feat: implemented sampling and elicitation * feat: improved sampling tests * feat: improved elicitation tests * feat: improved confirmance tests * feat: improved Prompts unit tests * feat: removed test code * feat: updated conformance tests * chore: removed redundant commas * chore: removed 6.0.3 swift version from ci * chore: improved unit tests a little bit * chore: update README.md * chore: add server progress tracking example to README.md * chore: updated README.md * chore: updated transports table formatting * chore: updated MockNetworkConnection --------- Co-authored-by: Austin Evans <austinjevans@me.com> Co-authored-by: yehorsobko <yehorsobko@macpaw.com>
This commit is contained in:
parent
6fa1a97b41
commit
6112a3995a
1 changed files with 11854 additions and 828 deletions
|
|
@ -209,12 +209,12 @@ import Testing
|
|||
|
||||
await MockURLProtocol.requestHandlerStorage.setHandler {
|
||||
[testEndpoint] (request: URLRequest) in
|
||||
#expect(request.value(forHTTPHeaderField: "Mcp-Session-Id") == nil)
|
||||
#expect(request.value(forHTTPHeaderField: "MCP-Session-Id") == nil)
|
||||
let response = HTTPURLResponse(
|
||||
url: testEndpoint, statusCode: 200, httpVersion: "HTTP/1.1",
|
||||
headerFields: [
|
||||
"Content-Type": "application/json",
|
||||
"Mcp-Session-Id": newSessionID,
|
||||
"MCP-Session-Id": newSessionID,
|
||||
])!
|
||||
return (response, Data())
|
||||
}
|
||||
|
|
@ -247,12 +247,12 @@ import Testing
|
|||
await MockURLProtocol.requestHandlerStorage.setHandler {
|
||||
[testEndpoint] (request: URLRequest) in
|
||||
#expect(request.readBody() == firstMessageData)
|
||||
#expect(request.value(forHTTPHeaderField: "Mcp-Session-Id") == nil)
|
||||
#expect(request.value(forHTTPHeaderField: "MCP-Session-Id") == nil)
|
||||
let response = HTTPURLResponse(
|
||||
url: testEndpoint, statusCode: 200, httpVersion: "HTTP/1.1",
|
||||
headerFields: [
|
||||
"Content-Type": "application/json",
|
||||
"Mcp-Session-Id": initialSessionID,
|
||||
"MCP-Session-Id": initialSessionID,
|
||||
])!
|
||||
return (response, Data())
|
||||
}
|
||||
|
|
@ -262,7 +262,7 @@ import Testing
|
|||
await MockURLProtocol.requestHandlerStorage.setHandler {
|
||||
[testEndpoint] (request: URLRequest) in
|
||||
#expect(request.readBody() == secondMessageData)
|
||||
#expect(request.value(forHTTPHeaderField: "Mcp-Session-Id") == initialSessionID)
|
||||
#expect(request.value(forHTTPHeaderField: "MCP-Session-Id") == initialSessionID)
|
||||
|
||||
let response = HTTPURLResponse(
|
||||
url: testEndpoint, statusCode: 200, httpVersion: "HTTP/1.1",
|
||||
|
|
@ -368,7 +368,7 @@ import Testing
|
|||
url: testEndpoint, statusCode: 200, httpVersion: "HTTP/1.1",
|
||||
headerFields: [
|
||||
"Content-Type": "application/json",
|
||||
"Mcp-Session-Id": initialSessionID,
|
||||
"MCP-Session-Id": initialSessionID,
|
||||
])!
|
||||
return (response, Data())
|
||||
}
|
||||
|
|
@ -387,7 +387,7 @@ import Testing
|
|||
// Set up the second handler for the 404 response
|
||||
await MockURLProtocol.requestHandlerStorage.setHandler {
|
||||
[testEndpoint, initialSessionID] (request: URLRequest) in
|
||||
#expect(request.value(forHTTPHeaderField: "Mcp-Session-Id") == initialSessionID)
|
||||
#expect(request.value(forHTTPHeaderField: "MCP-Session-Id") == initialSessionID)
|
||||
let response = HTTPURLResponse(
|
||||
url: testEndpoint, statusCode: 404, httpVersion: "HTTP/1.1", headerFields: nil)!
|
||||
return (response, Data("Not Found".utf8))
|
||||
|
|
@ -450,7 +450,7 @@ import Testing
|
|||
#expect(request.httpMethod == "GET")
|
||||
#expect(request.value(forHTTPHeaderField: "Accept") == "text/event-stream")
|
||||
#expect(
|
||||
request.value(forHTTPHeaderField: "Mcp-Session-Id") == "test-session-123")
|
||||
request.value(forHTTPHeaderField: "MCP-Session-Id") == "test-session-123")
|
||||
|
||||
let response = HTTPURLResponse(
|
||||
url: testEndpoint, statusCode: 200, httpVersion: "HTTP/1.1",
|
||||
|
|
@ -512,7 +512,7 @@ import Testing
|
|||
#expect(request.httpMethod == "GET")
|
||||
#expect(request.value(forHTTPHeaderField: "Accept") == "text/event-stream")
|
||||
#expect(
|
||||
request.value(forHTTPHeaderField: "Mcp-Session-Id") == "test-session-123")
|
||||
request.value(forHTTPHeaderField: "MCP-Session-Id") == "test-session-123")
|
||||
|
||||
let response = HTTPURLResponse(
|
||||
url: testEndpoint, statusCode: 200, httpVersion: "HTTP/1.1",
|
||||
|
|
@ -724,6 +724,40 @@ import Testing
|
|||
try await transport.send(messageData)
|
||||
await transport.disconnect()
|
||||
}
|
||||
|
||||
@Test("Send With Protocol Version Header", .httpClientTransportSetup)
|
||||
func testProtocolVersionHeader() async throws {
|
||||
let configuration = URLSessionConfiguration.ephemeral
|
||||
configuration.protocolClasses = [MockURLProtocol.self]
|
||||
|
||||
let protocolVersion = "2025-11-25"
|
||||
let transport = HTTPClientTransport(
|
||||
endpoint: testEndpoint,
|
||||
configuration: configuration,
|
||||
streaming: false,
|
||||
protocolVersion: protocolVersion,
|
||||
logger: nil
|
||||
)
|
||||
try await transport.connect()
|
||||
|
||||
let messageData = #"{"jsonrpc":"2.0","method":"test","id":6}"#.data(using: .utf8)!
|
||||
|
||||
await MockURLProtocol.requestHandlerStorage.setHandler {
|
||||
[testEndpoint, protocolVersion] (request: URLRequest) in
|
||||
// Verify the protocol version header is present
|
||||
#expect(
|
||||
request.value(forHTTPHeaderField: "MCP-Protocol-Version")
|
||||
== protocolVersion)
|
||||
|
||||
let response = HTTPURLResponse(
|
||||
url: testEndpoint, statusCode: 200, httpVersion: "HTTP/1.1",
|
||||
headerFields: ["Content-Type": "application/json"])!
|
||||
return (response, Data())
|
||||
}
|
||||
|
||||
try await transport.send(messageData)
|
||||
await transport.disconnect()
|
||||
}
|
||||
#endif // !canImport(FoundationNetworking)
|
||||
}
|
||||
#endif // swift(>=6.1)
|
||||
|
|
|
|||
Loading…
Reference in a new issue