Skip to content

Instantly share code, notes, and snippets.

@monotykamary
Created January 4, 2025 20:15
Show Gist options
  • Save monotykamary/9ad2c60f4e33b4063418f0c925c3bffb to your computer and use it in GitHub Desktop.
Save monotykamary/9ad2c60f4e33b4063418f0c925c3bffb to your computer and use it in GitHub Desktop.
MCP Schema as a TypedStruct in Elixir
defmodule MCP.Types do
@moduledoc """
Core types for the Model Context Protocol (MCP).
"""
use TypedStruct
defmodule RequestId do
@type t :: String.t() | integer()
end
defmodule Cursor do
@type t :: String.t()
end
defmodule ProgressToken do
@type t :: String.t() | integer()
end
typedstruct module: Implementation do
@moduledoc "Describes the name and version of an MCP implementation"
field :name, String.t(), enforce: true
field :version, String.t(), enforce: true
end
typedstruct module: ClientCapabilities do
@moduledoc "Capabilities a client may support"
field :experimental, map(), default: %{}
field :roots, map()
field :sampling, map()
end
typedstruct module: ServerCapabilities do
@moduledoc "Capabilities that a server may support"
field :experimental, map(), default: %{}
field :logging, map(), default: %{}
field :prompts, %{
listChanged: boolean()
}
field :resources, %{
listChanged: boolean(),
subscribe: boolean()
}
field :tools, %{
listChanged: boolean()
}
end
# Core types
defmodule LogLevel do
@type t :: :emergency | :alert | :critical | :error | :warning | :notice | :info | :debug
end
defmodule Role do
@type t :: :assistant | :user
end
typedstruct module: TextContent do
@moduledoc "Text provided to or from an LLM"
field :type, String.t(), default: "text", enforce: true
field :text, String.t(), enforce: true
field :annotations, map()
end
typedstruct module: ImageContent do
@moduledoc "An image provided to or from an LLM"
field :type, String.t(), default: "image", enforce: true
field :data, String.t(), enforce: true
field :mimeType, String.t(), enforce: true
field :annotations, map()
end
typedstruct module: Annotations do
@moduledoc "Base for objects that include optional annotations for the client"
field :audience, list(Role.t()), default: []
field :priority, float()
end
typedstruct module: Resource do
@moduledoc "A known resource that the server is capable of reading"
field :name, String.t(), enforce: true
field :uri, String.t(), enforce: true
field :description, String.t()
field :mimeType, String.t()
field :annotations, Annotations.t()
field :handler, (map() -> any()), enforce: true
end
typedstruct module: ResourceTemplate do
@moduledoc "A template description for resources available on the server"
field :name, String.t(), enforce: true
field :uriTemplate, String.t(), enforce: true
field :description, String.t()
field :mimeType, String.t()
field :annotations, Annotations.t()
end
typedstruct module: Tool do
@moduledoc "Definition for a tool the client can call"
field :name, String.t(), enforce: true
field :description, String.t()
field :inputSchema, %{
type: String.t(),
properties: map(),
required: list(String.t())
}, enforce: true
field :handler, (map() -> any()), enforce: true
end
typedstruct module: PromptArgument do
@moduledoc "Describes an argument that a prompt can accept"
field :name, String.t(), enforce: true
field :description, String.t()
field :required, boolean(), default: false
end
typedstruct module: Prompt do
@moduledoc "A prompt or prompt template that the server offers"
field :name, String.t(), enforce: true
field :description, String.t()
field :arguments, list(PromptArgument.t()), default: []
field :handler, (map() -> any()), enforce: true
end
typedstruct module: TextResourceContents do
@moduledoc "Text contents of a resource"
field :uri, String.t(), enforce: true
field :text, String.t(), enforce: true
field :mimeType, String.t()
end
typedstruct module: BlobResourceContents do
@moduledoc "Binary contents of a resource"
field :uri, String.t(), enforce: true
field :blob, String.t(), enforce: true
field :mimeType, String.t()
end
typedstruct module: EmbeddedResource do
@moduledoc "The contents of a resource, embedded into a prompt or tool call result"
field :type, String.t(), default: "resource", enforce: true
field :resource, TextResourceContents.t() | BlobResourceContents.t(), enforce: true
field :annotations, Annotations.t()
end
typedstruct module: PromptMessage do
@moduledoc "Describes a message returned as part of a prompt"
field :role, Role.t(), enforce: true
field :content, TextContent.t() | ImageContent.t() | EmbeddedResource.t(), enforce: true
end
typedstruct module: ModelPreferences do
@moduledoc "The server's preferences for model selection during sampling"
field :costPriority, float()
field :intelligencePriority, float()
field :speedPriority, float()
field :hints, list(map())
end
# Request/Response types
typedstruct module: Root do
@moduledoc "Represents a root directory or file that the server can operate on"
field :name, String.t()
field :uri, String.t(), enforce: true
end
typedstruct module: ListRootsRequest do
@moduledoc "Request to list root directories"
field :method, String.t(), default: "roots/list", enforce: true
field :params, map(), default: %{}
end
typedstruct module: ListRootsResult do
@moduledoc "Result containing root directories"
field :roots, list(Root.t()), enforce: true
field :_meta, map()
end
typedstruct module: ListResourcesRequest do
@moduledoc "Request to list available resources"
field :method, String.t(), default: "resources/list", enforce: true
field :params, %{cursor: String.t()}
end
typedstruct module: ListResourcesResult do
@moduledoc "Result containing available resources"
field :resources, list(Resource.t()), enforce: true
field :nextCursor, String.t()
field :_meta, map()
end
typedstruct module: ListPromptsRequest do
@moduledoc "Request to list available prompts"
field :method, String.t(), default: "prompts/list", enforce: true
field :params, %{cursor: String.t()}
end
typedstruct module: ListPromptsResult do
@moduledoc "Result containing available prompts"
field :prompts, list(Prompt.t()), enforce: true
field :nextCursor, String.t()
field :_meta, map()
end
typedstruct module: ListToolsRequest do
@moduledoc "Request to list available tools"
field :method, String.t(), default: "tools/list", enforce: true
field :params, %{cursor: String.t()}
end
typedstruct module: ListToolsResult do
@moduledoc "Result containing available tools"
field :tools, list(Tool.t()), enforce: true
field :nextCursor, String.t()
field :_meta, map()
end
typedstruct module: ProgressNotification do
@moduledoc "Notification of progress for a long-running request"
field :method, String.t(), default: "notifications/progress", enforce: true
field :params, %{
progressToken: ProgressToken.t(),
progress: number(),
total: number()
}, enforce: true
end
typedstruct module: CancelledNotification do
@moduledoc "Notification that a request has been cancelled"
field :method, String.t(), default: "notifications/cancelled", enforce: true
field :params, %{
requestId: RequestId.t(),
reason: String.t()
}, enforce: true
end
# Sampling types
typedstruct module: SamplingMessage do
@moduledoc "Describes a message issued to or received from an LLM API"
field :role, Role.t(), enforce: true
field :content, TextContent.t() | ImageContent.t(), enforce: true
end
typedstruct module: CreateMessageRequest do
@moduledoc "Request to sample from an LLM via the client"
field :method, String.t(), default: "sampling/createMessage", enforce: true
field :params, %{
messages: list(SamplingMessage.t()),
maxTokens: integer(),
temperature: float(),
stopSequences: list(String.t()),
systemPrompt: String.t(),
includeContext: String.t(),
modelPreferences: ModelPreferences.t(),
metadata: map()
}, enforce: true
end
typedstruct module: CreateMessageResult do
@moduledoc "Result from sampling an LLM"
field :content, TextContent.t() | ImageContent.t(), enforce: true
field :model, String.t(), enforce: true
field :role, Role.t(), enforce: true
field :stopReason, String.t()
field :_meta, map()
end
# Resource request types
typedstruct module: ReadResourceRequest do
@moduledoc "Request to read a specific resource"
field :method, String.t(), default: "resources/read", enforce: true
field :params, %{uri: String.t()}, enforce: true
end
typedstruct module: ReadResourceResult do
@moduledoc "Result containing resource contents"
field :contents, list(TextResourceContents.t() | BlobResourceContents.t()), enforce: true
field :_meta, map()
end
typedstruct module: SubscribeRequest do
@moduledoc "Request to subscribe to resource updates"
field :method, String.t(), default: "resources/subscribe", enforce: true
field :params, %{uri: String.t()}, enforce: true
end
typedstruct module: UnsubscribeRequest do
@moduledoc "Request to unsubscribe from resource updates"
field :method, String.t(), default: "resources/unsubscribe", enforce: true
field :params, %{uri: String.t()}, enforce: true
end
# Completion types
typedstruct module: PromptReference do
@moduledoc "Reference to a prompt"
field :type, String.t(), default: "ref/prompt", enforce: true
field :name, String.t(), enforce: true
end
typedstruct module: ResourceReference do
@moduledoc "Reference to a resource"
field :type, String.t(), default: "ref/resource", enforce: true
field :uri, String.t(), enforce: true
end
typedstruct module: CompleteRequest do
@moduledoc "Request for completion options"
field :method, String.t(), default: "completion/complete", enforce: true
field :params, %{
argument: %{
name: String.t(),
value: String.t()
},
ref: PromptReference.t() | ResourceReference.t()
}, enforce: true
end
typedstruct module: CompleteResult do
@moduledoc "Result containing completion options"
field :completion, %{
values: list(String.t()),
hasMore: boolean(),
total: integer()
}, enforce: true
field :_meta, map()
end
typedstruct module: InitializeRequest do
@moduledoc "Initial request sent from client to server"
field :method, String.t(), default: "initialize", enforce: true
field :params, %{
capabilities: ClientCapabilities.t(),
clientInfo: Implementation.t(),
protocolVersion: String.t()
}, enforce: true
end
typedstruct module: InitializeResult do
@moduledoc "Server's response to initialization request"
field :capabilities, ServerCapabilities.t(), enforce: true
field :protocolVersion, String.t(), enforce: true
field :serverInfo, Implementation.t(), enforce: true
field :instructions, String.t()
end
typedstruct module: GetPromptResult do
@moduledoc "The server's response to a prompts/get request from the client"
field :messages, list(PromptMessage.t()), enforce: true
field :_meta, map()
end
typedstruct module: CallToolRequest do
@moduledoc "Request to invoke a tool"
field :method, String.t(), default: "tools/call", enforce: true
field :params, %{
name: String.t(),
arguments: map()
}, enforce: true
end
typedstruct module: CallToolResult do
@moduledoc "Result from a tool invocation"
field :content, list(TextContent.t() | ImageContent.t() | EmbeddedResource.t()), enforce: true
field :isError, boolean(), default: false
field :_meta, map()
end
typedstruct module: Result do
@moduledoc "A generic result type"
field :_meta, map()
end
# JSON-RPC types
typedstruct module: JSONRPCRequest do
@moduledoc "A request that expects a response"
field :jsonrpc, String.t(), default: "2.0", enforce: true
field :id, RequestId.t(), enforce: true
field :method, String.t(), enforce: true
field :params, map()
end
typedstruct module: JSONRPCResponse do
@moduledoc "A successful response to a request"
field :jsonrpc, String.t(), default: "2.0", enforce: true
field :id, RequestId.t(), enforce: true
field :result, Result.t(), enforce: true
end
typedstruct module: JSONRPCError do
@moduledoc "A response indicating an error occurred"
field :jsonrpc, String.t(), default: "2.0", enforce: true
field :id, RequestId.t(), enforce: true
field :error, %{
code: integer(),
message: String.t(),
data: any()
}, enforce: true
end
typedstruct module: JSONRPCNotification do
@moduledoc "A notification which does not expect a response"
field :jsonrpc, String.t(), default: "2.0", enforce: true
field :method, String.t(), enforce: true
field :params, map()
end
# Notification types
typedstruct module: ResourceListChangedNotification do
@moduledoc "Notification that the list of resources has changed"
field :method, String.t(), default: "notifications/resources/listChanged", enforce: true
field :params, map(), default: %{}
end
typedstruct module: ResourceUpdatedNotification do
@moduledoc "Notification that a resource has been updated"
field :method, String.t(), default: "notifications/resources/updated", enforce: true
field :params, %{uri: String.t()}, enforce: true
end
typedstruct module: PromptListChangedNotification do
@moduledoc "Notification that the list of prompts has changed"
field :method, String.t(), default: "notifications/prompts/listChanged", enforce: true
field :params, map(), default: %{}
end
typedstruct module: ToolListChangedNotification do
@moduledoc "Notification that the list of tools has changed"
field :method, String.t(), default: "notifications/tools/listChanged", enforce: true
field :params, map(), default: %{}
end
typedstruct module: LoggingMessageNotification do
@moduledoc "A log message from the server"
field :method, String.t(), default: "notifications/message", enforce: true
field :params, %{
level: LogLevel.t(),
data: any(),
logger: String.t()
}, enforce: true
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment