From 77f12751e4de073e9acab79594c228a816c7b710 Mon Sep 17 00:00:00 2001 From: EhsanAzish80 Date: Thu, 24 Sep 2026 18:52:34 +0300 Subject: [PATCH] Support server experimental and extension capabilities --- Sources/MCP/Server/Server.swift | 10 +++++++++- Tests/MCPTests/ServerTests.swift | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Sources/MCP/Server/Server.swift b/Sources/MCP/Server/Server.swift index 060b51f8..3a9869c8 100644 --- a/Sources/MCP/Server/Server.swift +++ b/Sources/MCP/Server/Server.swift @@ -108,6 +108,10 @@ public actor Server { /// Completions capabilities public var completions: Completions? + /// Experimental capabilities supported by the server + public var experimental: [String: Value]? + /// MCP extensions supported by the server + public var extensions: [String: Value]? /// Logging capabilities public var logging: Logging? /// Prompts capabilities @@ -122,9 +126,13 @@ public actor Server { logging: Logging? = nil, prompts: Prompts? = nil, resources: Resources? = nil, - tools: Tools? = nil + tools: Tools? = nil, + experimental: [String: Value]? = nil, + extensions: [String: Value]? = nil ) { self.completions = completions + self.experimental = experimental + self.extensions = extensions self.logging = logging self.prompts = prompts self.resources = resources diff --git a/Tests/MCPTests/ServerTests.swift b/Tests/MCPTests/ServerTests.swift index a7b61667..2e599268 100644 --- a/Tests/MCPTests/ServerTests.swift +++ b/Tests/MCPTests/ServerTests.swift @@ -5,6 +5,32 @@ import Testing @Suite("Server Tests") struct ServerTests { + @Test("Server capabilities preserve experimental and extension objects") + func testServerCapabilityObjects() throws { + let capabilities = Server.Capabilities( + tools: .init(), + experimental: ["example/feature": .object(["enabled": .bool(true)])], + extensions: ["io.modelcontextprotocol/tasks": .object([:])] + ) + let result = Initialize.Result( + protocolVersion: Version.latest, + capabilities: capabilities, + serverInfo: .init(name: "TestServer", version: "1.0") + ) + + let encoded = try JSONEncoder().encode(result) + let decoded = try JSONDecoder().decode(Initialize.Result.self, from: encoded) + #expect(decoded.capabilities == capabilities) + + let json = try #require(JSONSerialization.jsonObject(with: encoded) as? [String: Any]) + let encodedCapabilities = try #require(json["capabilities"] as? [String: Any]) + let experimental = try #require(encodedCapabilities["experimental"] as? [String: Any]) + let feature = try #require(experimental["example/feature"] as? [String: Any]) + #expect(feature["enabled"] as? Bool == true) + let extensions = try #require(encodedCapabilities["extensions"] as? [String: Any]) + #expect(extensions["io.modelcontextprotocol/tasks"] is [String: Any]) + } + @Test("Start and stop server") func testServerStartAndStop() async throws { let transport = MockTransport()