All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.9.0] - 2026-03-22

Added

  • MCP Apps support — first-class support for the MCP Apps extension, enabling tools to return interactive UI components rendered as sandboxed iframes in host clients
    • meta/1 macro — attach arbitrary _meta metadata to tool definitions (generic, future-proof)
    • ui/1 macro — shortcut for declaring _meta.ui.resourceUri on a tool
    • app/2 macro — convenience that registers both a tool (with _meta.ui) and its ui:// HTML resource in one declaration
    • raw_resource/2 helper — return raw content with a MIME type from resource handlers
    • Component mode ui: option — use ConduitMcp.Component, type: :tool, ui: "ui://..."
  • MCP Apps guide — new HexDocs guide covering DSL, Component, and app macro usage with client-side build workflow
  • MCP Apps exampleexamples/mcp_apps_demo/ with a server health dashboard demonstrating the full tool → UI resource → iframe pattern

0.8.5 - 2026-03-22

Changed

  • Removed Jason dependency — replaced with Elixir 1.18+ built-in JSON module across all lib, test, and transport code (one fewer dependency)

Performance

  • Pre-compiled URI template regex — resource URI matching regex is now compiled once at compile time instead of rebuilt on every request (2.4x faster resource reads in DSL mode, 1.7x in Endpoint mode)
  • Single-pass constraint validation — merged 4 separate schema traversals (enum, numeric, string length, custom) into a single Enum.reduce_while pass (1.6x faster)
  • Optimized marker removal — replaced 11-iteration Enum.reduce with Keyword.drop/2 (2.2x faster)
  • Single config fetch — validation reads Application.get_env once per call instead of 3 times (1.3x faster)
  • O(1) schema lookup in type coercion — replaced Enum.find per parameter with pre-built Map lookup

Added

  • Benchee benchmark suite (mix bench) with 6 benchmark files:
    • uri_template_bench — dynamic regex vs pre-compiled vs String.split
    • validation_bench — full pipeline, key conversion, constraint passes, marker removal, config lookups
    • handler_bench — method dispatch, function_exported? overhead, telemetry cost
    • json_bench — built-in JSON encode/decode at varying payload sizes
    • protocol_bench — request validation and response construction baseline
    • full_request_bench — DSL vs Manual vs Endpoint mode comparison
  • mix bench task — run all benchmarks, run specific (mix bench validation), or list (mix bench --list)
  • HTML benchmark reports generated in bench/output/

0.8.0 - 2026-03-22

Added

  • Endpoint + Component mode — third way to define MCP servers alongside DSL and Manual modes
    • ConduitMcp.Component behaviour for defining tools, resources, and prompts as individual modules
    • ConduitMcp.Component.Schema DSL (schema do field ... end) with automatic JSON Schema and NimbleOptions generation
    • ConduitMcp.Endpoint aggregator with component macro, declarative rate_limit/message_rate_limit/auth config
    • Auto-detected capabilities from registered component types
    • Compile-time validation (duplicate names, invalid modules, missing callbacks)
    • Atom-keyed params in execute/2 for ergonomic pattern matching
  • ConduitMcp.Errors module — centralized JSON-RPC 2.0 and MCP error code constants
    • parse_error/0, invalid_request/0, method_not_found/0, invalid_params/0, internal_error/0, server_error/0, resource_not_found/0
    • Replaces hardcoded magic numbers across the codebase
  • Transport auto-extraction — StreamableHTTP and SSE transports auto-read endpoint config (name, version, rate_limit, auth) as fallback defaults
  • Handler capability detectionbuild_capabilities/1 uses __capabilities__/0 when available for selective capability advertisement
  • 6 new documentation guides — choosing_a_mode, endpoint_mode, dsl_mode, manual_mode, authentication, rate_limiting

Improved

  • Test coverage expanded to 503 tests (up from 405)
  • README restructured with all 3 server modes, responses reference, MCP spec coverage table
  • Error codes refactoredConduitMcp.Protocol now delegates to ConduitMcp.Errors

0.7.0 - 2026-03-21

Added

  • MCP spec 2025-11-25 support with backward compatibility for 2025-06-18
    • Protocol version negotiation in initialize (supports both versions)
    • MCP-Protocol-Version response header on all POST responses
    • MCP-Session-Id header with session creation and validation
  • Pluggable session store (ConduitMcp.Session.Store behaviour)
  • Cursor-based pagination via arity-2 list callbacks (backward compatible with arity-1)
  • Tool annotations DSL (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)
  • _meta field passthrough for progressToken support
  • listChanged capability declarations
  • Origin header validation for DNS rebinding prevention
  • New handler methods: completion/complete, logging/setLevel, resources/subscribe, resources/unsubscribe
  • audio/2 helper macro for audio content type
  • ConduitMcp.Tasks module for long-running operation state machine
  • ConduitMcp.Client module for server-to-client requests (sampling, elicitation, roots)
  • OAuth 2.1 authentication (ConduitMcp.Plugs.OAuth) with JWT validation
  • New error code -32002 (resource not found)
  • CI/CD pipeline with compile, format, credo, test, dialyzer, and hex publish jobs
  • Configurable initialize response (server_name, server_version via conn.private)

Improved

  • Test coverage expanded to 405 tests (up from 309)
  • Dependencies updated: bandit 1.10.3, credo 1.7.17, ex_doc 0.40.1, telemetry 1.4.1
  • Handler refactored to reduce cyclomatic complexity with extracted helper functions

Fixed

  • Version mismatch where handler returned hardcoded version instead of app version
  • Hardcoded protocol version in transport (now uses Protocol.protocol_version/0)
  • Flaky telemetry tests caused by async race conditions
  • Flaky StreamableHTTP tests caused by shared ETS state in async mode
  • Elixir 1.20 compilation warnings

0.6.5 - 2026-02-07

Added

  • Message-level rate limiting (ConduitMcp.Plugs.MessageRateLimit)
    • Second rate limiting layer that limits MCP method calls per time window
    • POST-only: GET/OPTIONS pass through automatically
    • Skips JSON-RPC notifications (no id field)
    • Configurable excluded methods (e.g., ["initialize", "ping"])
    • User-aware default key function (uses conn.assigns[:current_user] from Auth plug)
    • "msg:" key prefix prevents Hammer counter collision with HTTP rate limiter
    • HTTP 429 response with Retry-After header and JSON-RPC error (code -32000)
    • Telemetry event: [:conduit_mcp, :message_rate_limit, :check]
    • PromEx metrics: message_rate_limit_check_total, message_rate_limit_check_duration_milliseconds
    • Configurable via :message_rate_limit transport option
    • Works alongside existing HTTP-level rate limiting

Improved

  • Test coverage expanded to 309 tests
  • README updated with Rate Limiting documentation (HTTP + message-level)
  • Telemetry documentation updated with message rate limit events
  • PromEx plugin updated with message rate limit metrics
  • Applied mix format to all files in the codebase

[0.5.0] - 2025-11-24

Added

  • Resource URI parameter extraction - Complete implementation

    • Extracts parameters from URI templates (e.g., "user://{id}""user://123"%{"id" => "123"})
    • Supports multiple parameters (e.g., "user://{id}/posts/{post_id}")
    • Uses proper regex escaping with placeholder tokens
    • Returns {:ok, params} on match or :no_match otherwise
    • Full implementation in extract_uri_params/2 (internal)
    • Resolves TODO from previous versions
  • PromEx plugin for Prometheus monitoring

    • Optional integration via {:prom_ex, "~> 1.11", optional: true}
    • Conditional compilation (only loads if PromEx available)
    • 10 production-ready metrics (5 counters + 5 histograms)
    • Monitors all ConduitMCP operations: requests, tools, resources, prompts, auth
    • Optimized histogram buckets per operation type
    • Low cardinality design with string normalization
    • Comprehensive documentation with PromQL query examples
    • Alert rule examples included
    • Zero runtime overhead when not enabled

Improved

  • Test coverage expanded significantly

    • 33 new tests added (21 for core features, 12 for PromEx)
    • Resource URI parameter extraction: 11 new tests
    • Prompt functionality: 4 new tests
    • Tool functionality: 6 new tests
    • PromEx plugin: 12 new tests
    • Total: 229 tests, all passing
  • Documentation enhanced

    • Added comprehensive Prometheus Metrics section to README
    • 190+ lines of PromEx plugin documentation
    • PromQL query cookbook with examples
    • Alert rule templates
    • Complete metric reference

Fixed

  • Version consistency across all files (updated from 0.4.6 to 0.4.7, now 0.5.0)
  • Removed repository artifacts:
    • Deleted erl_crash.dump (4.9 MB)
    • Deleted conduit_mcp-0.4.0.tar and conduit_mcp-0.4.6.tar
  • Updated test badge count (193 → 229 passing)

Breaking Changes

None - This release is fully backward compatible.

[0.4.7] - 2025-11-19

Added

  • raw/1 helper macro for direct JSON output without MCP content wrapping
    • Bypasses standard MCP content structure for debugging purposes
    • Returns {:ok, data} directly instead of wrapped content array
    • Supports maps, strings, lists, and all data types
    • Includes comprehensive documentation with MCP compatibility warnings
    • Full test coverage with 3 test cases

Documentation

  • Updated README.md helper functions list to include raw/1
  • Added detailed module documentation with usage examples and warnings

0.4.6 - 2025-01-16

Changed

  • Streamlined README and CHANGELOG for clarity
  • Focused documentation on essential features
  • Reduced README by 53% (634 → 298 lines)
  • Reduced CHANGELOG by 48% (190 → 99 lines)

Improved

  • README now highlights DSL as primary approach
  • Removed outdated migration guides
  • Cleaner examples and better organization
  • Added version and test badges

0.4.5 - 2025-01-16

Added

  • Clean DSL for defining MCP servers
    • tool, prompt, resource macros for declarative definitions
    • Automatic JSON Schema generation from parameters
    • Helper functions: text(), json(), error(), system(), user(), assistant()
    • Support for inline functions, MFA handlers, and function captures
    • Parameter features: enums, defaults, required fields, type validation
  • Flexible authentication system
    • ConduitMcp.Plugs.Auth with 5 strategies
    • Bearer token, API key, custom function, MFA, database lookup
    • CORS preflight bypass, configurable assign key
    • Case-insensitive bearer token support
  • Extended telemetry
    • [:conduit_mcp, :resource, :read] - Resource operations
    • [:conduit_mcp, :prompt, :get] - Prompt operations
    • [:conduit_mcp, :auth, :verify] - Authentication
    • Complete observability for all MCP operations

Changed

  • Examples updated to use DSL (simple_tools_server, phoenix_mcp)
  • Transport modules support :auth option
  • Auth configured per-transport (no separate pipeline needed)
  • Documentation streamlined to focus on DSL

Tests

  • 36 DSL tests (tools, prompts, resources, helpers, schema builder)
  • 26 auth plug tests (all strategies, error handling, CORS)
  • 16 telemetry tests
  • 193 total tests, all passing

0.4.0 - 2025-01-16

Changed (Breaking)

  • Pure stateless architecture
    • Removed GenServer and Agent - zero process overhead
    • Server is just a module with pure functions
    • No supervision tree required
    • Maximum concurrency (limited only by Bandit)
  • Simplified callback API
    • Removed mcp_init/1
    • Changed {:reply, result, state}{:ok, result}
    • Callbacks receive conn (Plug.Conn) as first parameter
    • No more state passing/returning
    • Error maps use string keys
  • Handler updates
    • Calls module functions directly (no GenServer.call)
    • Transport layers pass Plug.Conn for request context

Performance

  • Zero process overhead - pure function calls
  • Full concurrent request processing
  • No serialization bottleneck

0.3.0 - 2025-10-28

Added

  • Comprehensive test suite (109 tests, 82% coverage)
  • Test infrastructure (TestServer, TelemetryTestHelper)
  • ExCoveralls integration

Changed

  • Simplified and professionalized README

0.2.0 - 2025-10-09

Added

  • Telemetry events ([:conduit_mcp, :request, :stop], [:conduit_mcp, :tool, :execute])
  • Configurable CORS headers
  • Enhanced logging

Fixed

  • SSE buffering with nginx proxies

0.1.0 - 2025-10-08

Added

  • Initial release
  • MCP specification 2025-06-18 implementation
  • ConduitMcp.Server behaviour
  • StreamableHTTP and SSE transports
  • Tools, resources, and prompts support
  • Basic authentication
  • Phoenix integration example