ModelContextProtocol.jl

Julia implementation of the Model Context Protocol (MCP), enabling seamless integration between AI applications and external data sources, tools, and services.

Features

  • MCP 2025-11-25 Protocol - server-side implementation with version negotiation back to 2024-11-05
  • Multiple Transports - stdio (default) and Streamable HTTP with Server-Sent Events and session management
  • All Content Types - text, images, audio, embedded resources, and resource_link references
  • Structured Tool Output - output_schema declarations with structuredContent results
  • Tool Annotations - behavioral hints (readOnlyHint, destructiveHint, …) for client trust decisions
  • Progress Notifications - long-running tools report progress through context-aware handlers
  • Tasks (experimental) - background tool execution with status polling, blocking result retrieval, and cancellation (SEP-1686)
  • OAuth Resource Server - bearer-token validation for HTTP (GitHub tokens, JWT claims, RFC 7662 introspection) with RFC 9728 discovery
  • Logging Control - runtime logging/setLevel plus opt-in per-request lifecycle logs
  • Auto-Registration - automatic component discovery from directory structure
  • Type-Safe - leverages Julia's type system for robust implementations

Note: This is a server-side implementation. Client features (roots, sampling), elicitation, and the OAuth Authorization Server (token issuance) are not yet implemented.

Installation

using Pkg
Pkg.add("ModelContextProtocol")

Quick Start

Create a simple MCP server with a tool:

using ModelContextProtocol

# Create a server with a simple echo tool
server = mcp_server(
    name = "echo-server",
    version = "1.0.0",
    tools = [
        MCPTool(
            name = "echo",
            description = "Echo back the input message",
            parameters = [
                ToolParameter(
                    name = "message",
                    type = "string",
                    description = "Message to echo",
                    required = true
                )
            ],
            handler = (params) -> TextContent(text = params["message"])
        )
    ]
)

# Start the server (stdio transport by default)
start!(server)

Using HTTP Transport

For web-based integrations, use the HTTP transport:

# Create server, then attach an HTTP transport
server = mcp_server(
    name = "http-server",
    version = "1.0.0",
    tools = [...]  # Your tools here
)

server.transport = HttpTransport(host = "127.0.0.1", port = 3000)
connect(server.transport)
start!(server)

# Test with curl
# curl -X POST http://127.0.0.1:3000/ \
#   -H "Content-Type: application/json" \
#   -d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":1}'

Documentation Structure

Protocol Compliance

ModelContextProtocol.jl implements the MCP specification version 2025-11-25 and negotiates with clients speaking 2025-06-18, 2025-03-26, or 2024-11-05. This includes:

  • JSON-RPC 2.0 message protocol (batching rejected per spec)
  • Tool discovery and invocation, structured output, annotations, _meta
  • Resource management with subscriptions and resource_link references
  • Prompt templates with arguments and media content
  • Progress notifications (notifications/progress) and logging (logging/setLevel)
  • Session management and OAuth Resource Server authentication for HTTP transport

Basic Concepts

Tools

Tools are functions that can be invoked by the LLM:

tool = MCPTool(
    name = "calculate",
    description = "Perform basic arithmetic",
    parameters = [
        ToolParameter(name = "a", type = "number", required = true),
        ToolParameter(name = "b", type = "number", required = true),
        ToolParameter(name = "op", type = "string", required = true)
    ],
    handler = function(params)
        a, b = params["a"], params["b"]
        result = if params["op"] == "+"
            a + b
        elseif params["op"] == "-"
            a - b
        elseif params["op"] == "*"
            a * b
        elseif params["op"] == "/"
            a / b
        else
            error("Unknown operation")
        end
        return TextContent(text = string(result))
    end
)

Resources

Resources provide data access to the LLM:

resource = MCPResource(
    uri = "file:///data/config.json",
    name = "Application Config",
    description = "Current application configuration",
    mime_type = "application/json",
    data_provider = () -> JSON3.read(read("config.json", String), Dict{String,Any})
)

Prompts

Prompts are templates for generating conversations:

prompt = MCPPrompt(
    name = "code_review",
    description = "Request a code review",
    arguments = [
        PromptArgument(
            name = "language",
            description = "Programming language",
            required = true
        )
    ],
    messages = [
        PromptMessage(
            content = TextContent(
                text = "Please review this {language} code for best practices."
            )
        )
    ]
)

Template placeholders like {language} are substituted from the arguments supplied in prompts/get.

Testing Your Server

With MCP Inspector

Test your server using the official MCP Inspector:

# For stdio transport (Inspector spawns the server command directly)
npx @modelcontextprotocol/inspector julia --project=. server.jl

# For HTTP transport
npx @modelcontextprotocol/inspector http://127.0.0.1:3000/

# Quick smoke test without the browser UI (CLI mode)
npx @modelcontextprotocol/inspector --cli julia --project=. server.jl --method tools/list

With curl (HTTP only)

# Initialize connection
curl -X POST http://127.0.0.1:3000/ \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'

# List available tools
curl -X POST http://127.0.0.1:3000/ \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: <session-id-from-init>" \
  -d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":2}'

Next Steps

Contributing

ModelContextProtocol.jl is part of the JuliaSMLM organization. Contributions are welcome! Please see our GitHub repository for issues and pull requests.

License

This project is licensed under the MIT License.