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/1macro — attach arbitrary_metametadata to tool definitions (generic, future-proof)ui/1macro — shortcut for declaring_meta.ui.resourceUrion a toolapp/2macro — convenience that registers both a tool (with_meta.ui) and itsui://HTML resource in one declarationraw_resource/2helper — 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 example —
examples/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
JSONmodule 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_whilepass (1.6x faster) - Optimized marker removal — replaced 11-iteration
Enum.reducewithKeyword.drop/2(2.2x faster) - Single config fetch — validation reads
Application.get_envonce per call instead of 3 times (1.3x faster) - O(1) schema lookup in type coercion — replaced
Enum.findper parameter with pre-builtMaplookup
Added
- Benchee benchmark suite (
mix bench) with 6 benchmark files:uri_template_bench— dynamic regex vs pre-compiled vs String.splitvalidation_bench— full pipeline, key conversion, constraint passes, marker removal, config lookupshandler_bench— method dispatch,function_exported?overhead, telemetry costjson_bench— built-in JSON encode/decode at varying payload sizesprotocol_bench— request validation and response construction baselinefull_request_bench— DSL vs Manual vs Endpoint mode comparison
mix benchtask — 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.Componentbehaviour for defining tools, resources, and prompts as individual modulesConduitMcp.Component.SchemaDSL (schema do field ... end) with automatic JSON Schema and NimbleOptions generationConduitMcp.Endpointaggregator withcomponentmacro, 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/2for ergonomic pattern matching
ConduitMcp.Errorsmodule — centralized JSON-RPC 2.0 and MCP error code constantsparse_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 detection —
build_capabilities/1uses__capabilities__/0when 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 refactored —
ConduitMcp.Protocolnow delegates toConduitMcp.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-Versionresponse header on all POST responsesMCP-Session-Idheader with session creation and validation
- Protocol version negotiation in
- Pluggable session store (
ConduitMcp.Session.Storebehaviour)- Default ETS store included (
ConduitMcp.Session.EtsStore) - Documentation for Redis, PostgreSQL, and Mnesia stores
- Default ETS store included (
- Cursor-based pagination via arity-2 list callbacks (backward compatible with arity-1)
- Tool annotations DSL (
readOnlyHint,destructiveHint,idempotentHint,openWorldHint) _metafield passthrough forprogressTokensupportlistChangedcapability declarations- Origin header validation for DNS rebinding prevention
- New handler methods:
completion/complete,logging/setLevel,resources/subscribe,resources/unsubscribe audio/2helper macro for audio content typeConduitMcp.Tasksmodule for long-running operation state machineConduitMcp.Clientmodule for server-to-client requests (sampling, elicitation, roots)- OAuth 2.1 authentication (
ConduitMcp.Plugs.OAuth) with JWT validation- JWKS key provider with HTTP fetching (
ConduitMcp.OAuth.KeyProvider.JWKS) - Static key provider (
ConduitMcp.OAuth.KeyProvider.Static) - Resource metadata endpoint (
ConduitMcp.OAuth.ResourceMetadata) - Tool-level scope enforcement
- JWKS key provider with HTTP fetching (
- 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_versionviaconn.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
idfield) - 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-Afterheader 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_limittransport 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 formatto 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_matchotherwise - Full implementation in
extract_uri_params/2(internal) - Resolves TODO from previous versions
- Extracts parameters from URI templates (e.g.,
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
- Optional integration via
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.tarandconduit_mcp-0.4.6.tar
- Deleted
- Updated test badge count (193 → 229 passing)
Breaking Changes
None - This release is fully backward compatible.
[0.4.7] - 2025-11-19
Added
raw/1helper 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,resourcemacros 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.Authwith 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
:authoption - 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
- Removed
- 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.Serverbehaviour- StreamableHTTP and SSE transports
- Tools, resources, and prompts support
- Basic authentication
- Phoenix integration example