Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Sources/MCP/Server/Server.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
26 changes: 26 additions & 0 deletions Tests/MCPTests/ServerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down