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.
Unreleased
1.2.1 - 2026-05-13
Fixed
- Hex publish compatibility — Replaced
inflex(GitHub dep, blocked hex.publish) withplurality(Hex dep) for route name singularization. Plurality is a modern, zero-regex inflection library with verified accuracy across 80k+ noun pairs.
Changed
mix.exsdependency:inflex→plurality ~> 0.2RouteIntrospection.singularize/1now callsPlurality.singularize/1directly
1.2.0 - 2026-05-13
Added
- MCP Resources for schema discovery — Each
exposed schema now automatically registers an MCP resource atectomancer://schemas/{name}returning full schema metadata (fields, types, associations, primary key, available actions). A top-levelectomancer://schemasresource lists all registered schemas. Opt-out per schema withresource: false. (Closes #56) - Dynamic association preloading — New
preloadableoption forexposeallows LLMs to dynamically request associated records via anincludeparameter onlistandgettools. Supportspreloadable: true(all associations) orpreloadable: [:posts, :comments](specific). Requested includes are validated against allowed associations. (Closes #57) - Rate limiting — Token bucket algorithm with ETS storage. Configurable per-tool and global limits. Opt-in via
config :ectomancer, :rate_limits. - Multi-repo support — expose schemas from different repos with
expose User, repo: MyApp.ReplicaRepo. Falls back to global repo config. - Browser MCP client — Zero-dependency HTML browser client at
priv/ectomancer.html. Browse tools, call them, see results. No build step required. - Auto-deployed ExDoc to GitHub Pages — New CI workflow builds docs on push to main and deploys via
actions/deploy-pages. - CI, Hex, and Docs badges to README header.
Fixed
singularizehelper now handles edge cases (status,address,series) correctly.- Error handling now returns structured
{:error, %{code:, message:, details:}}tuples consistently.
Testing
- 426 tests (up from 260), all passing
- 28 new tests: 19 for MCP Resources, 9 for dynamic preloading
- 9 new rate limiter tests
- Validated multi-repo integration with secondary Phoenix app (SQLite)
1.1.0 - 2026-04-23
Added
- Interactive setup tool (
mix ectomancer.setup) for automatic project configuration- Auto-discovers Ecto schemas via module introspection and file scanning
- Prompts for schema selection, Oban bridge, and tool namespace
- Generates MCP module with proper
exposedeclarations - Updates mix.exs, config.exs, and router files automatically
- Derives module name from app name (e.g.,
TestEctoApp.MCP)
- Schema discovery module (
Ectomancer.Installer.SchemaDiscovery) with dual discovery strategy - Config updater (
Ectomancer.Installer.ConfigUpdater) for idempotent file patching - Dependency checker (
Ectomancer.Installer.DependencyChecker) for required/optional dep validation - Template renderer (
Ectomancer.Installer.TemplateRenderer) for MCP module generation - Igniter installer stub (
Ectomancer.Igniter)
Testing
- 260 tests (up from 223), all passing
- Full integration tests for the setup tool workflow
1.0.0 - 2026-03-29
🎉 Official v1.0.0 Release - Production Ready!
Ectomancer is now officially stable and ready for production use! Three phases of development complete.
Added
Optional Oban Bridge (Issue #15) - Phase 3 Final Feature!
- New
expose_oban_jobs/0andexpose_oban_jobs/1macros for Oban integration - Automatically generates 5 MCP tools for job queue management:
list_oban_queues- List all queues with job statistics (total, executing, available, retryable, discarded)get_queue_depth- Get detailed counts for a specific queuelist_stuck_jobs- Find executing jobs with optional filters (queue, worker, min_age, limit)retry_job- Retry failed or discarded jobs by IDcancel_job- Cancel or delete jobs by ID
- Only activates when Oban is in dependencies (optional dependency support)
- Supports
:namespaceoption for tool naming (e.g.,background_list_oban_queues) - Comprehensive test coverage (13 tests)
# Expose all Oban job management tools
expose_oban_jobs
# With namespace prefix
expose_oban_jobs(namespace: :background)
# Generates: background_list_oban_queues, background_get_queue_depth, etc.Phoenix Route Introspection (Issue #14) - Phase 3 Complete!
- New
expose_routes/1macro to auto-generate MCP tools from Phoenix router - Support for all HTTP methods: GET, POST, PUT, PATCH, DELETE
- Smart tool naming with automatic singularization:
/users→get_users,post_users/users/:id→get_user,put_user,delete_user
- Route filtering options:
:only- Include only specific paths:except- Exclude specific paths:methods- Filter by HTTP methods:namespace- Prefix tool names (e.g.,api_get_users)
- Automatic path parameter mapping to tool parameters
- Direct controller action execution via
Plug.Test.conn - Proper handling of
Plug.Conn.AlreadySentError
# Expose all routes
expose_routes MyAppWeb.Router
# With filtering
expose_routes MyAppWeb.Router,
only: ["/api/users"],
namespace: :api,
methods: ["GET", "POST"]Testing
- 223 tests (up from 193)
- 30 new tests: 13 for Oban bridge, 17 for route introspection
- Full integration tested with sweetcorn Phoenix app including:
- Oban job insertion, retry, and cancellation via MCP tools
- Route tool execution through Phoenix controllers
- All authorization strategies working with new features
Issues Closed
- #15 - Create optional Oban bridge for job queue management
- #14 - Implement Phoenix route introspection for MCP tools
0.1.0-rc.3 - 2026-03-18
Added
Read-Only Mode (Issue #12)
- New
:readonlyoption forexpose/2macro - When
readonly: true, only generates:listand:gettools - Prevents create, update, destroy operations
- Perfect for public read-only access to data
expose MyApp.Blog.Post, readonly: true
# Generates only: list_posts, get_postChangeset Error Mapping (Issue #13)
Enhanced error messages from Ecto changeset validations
Automatic categorization of validation errors:
- presence: Missing required fields
- format: Invalid format (email regex, etc.)
- inclusion: Value not in allowed set
- confirmation: Confirmation doesn't match
- length: String length issues
- comparison: Numeric comparison failures
Improved database error detection:
- unique_violation: "Duplicate value: Record with this value already exists"
- foreign_key_violation: "Invalid reference: Related record does not exist"
- not_null_violation: "Missing required parameter: Field Name"
Schema changeset integration
- Uses schema's
changeset/2function when available - Ensures unique_constraint validations work properly
- Returns structured error responses instead of binary strings
- Uses schema's
Changed
- Updated README.md with read-only mode and error handling documentation
- Enhanced error categorization in
format_error/1
Fixed
- Fixed unique constraint violations to return proper error responses
- Fixed foreign key violations to show descriptive messages
- Fixed changeset validation errors to show field names and messages
Testing
- 193 tests (up from 172)
- 21 new tests: 16 for read-only mode, 6 for error mapping
- Full integration tested with sweetcorn Phoenix app
- All authorization strategies still working
Issues Closed
- #12 - Implement read-only mode for expose macro
- #13 - Map Ecto changeset errors to MCP error responses
0.1.0-rc.2 - 2026-03-17
Added
Authorization System (Phase 2)
- Inline function authorization - Simple auth checks with inline functions
authorize fn actor, action -> actor.role == :admin end - Policy module authorization - Reusable authorization logic via behavior
authorize with: MyApp.Policies.UserPolicy - Public access -
:noneauthorization for public endpointsauthorize :none - Per-schema authorization - Global auth rules for all actions on a schema
- Per-action authorization - Fine-grained control with action-specific rules
- Authorization cascade - Multiple auth levels work together
Binary ID / UUID Support
- Full support for
binary_idprimary keys - Automatic UUID string casting
- Works with all CRUD operations
Enhanced Error Messages
- Descriptive error messages (e.g., "Missing required parameter: User id")
- Proper MCP error codes (-32602 for validation, -32603 for internal)
- Field identification in error responses
Changed
- Updated README.md with comprehensive authorization documentation
- Improved error handling with better error categorization
Fixed
- Fixed binary_id primary key handling in get/update/destroy operations
- Fixed Peri validation compatibility with JSON Schema format
- Fixed tool parameter generation for nested blocks
- Fixed atom vs string key handling in normalize_params
Security
- SQL injection prevention via parameterized queries
- Row limits to prevent memory exhaustion (100 records default)
- Authorization checks before tool execution
- Proper error messages without exposing internal details
Testing
- 172 tests (up from 128)
- 35 authorization-specific tests
- All authorization strategies tested
- Full integration tested with sweetcorn Phoenix app
Issues Closed
- #10 - Design and implement authorization hook system
- #11 - Add per-schema and per-action authorization granularity
- #35 - Fix critical bugs in binary ID handling and tool parameter schemas
0.1.0-rc.1 - 2026-03-16
Added
- First release candidate with fully functional CRUD operations
- Core MCP server implementation via
Ectomancermodule expose/2macro for auto-generating CRUD tools from Ecto schemas (list, get, create, update, destroy)tool/2macro for custom tool definitions with param validationEctomancer.Plugfor seamless Phoenix router integrationEctomancer.Repoabstraction supporting all major CRUD operations- Automatic actor extraction and threading through
conn.assigns - Field filtering support via
:onlyand:exceptoptions - Namespace support to prevent tool naming collisions
- Comprehensive test suite (128 tests, all passing)
- Full Credo and Dialyzer compliance
- Support for Phoenix 1.7 and 1.8
- MIT License
Fixed
- Fixed Peri schema validation crashes by disabling params in exposed tools
- Fixed GenServer crashes during CRUD operations with proper error handling
- Fixed tool execution to return proper Anubis Response format
- Fixed repo error handling with comprehensive try/rescue blocks
Security
- SQL injection prevention via parameterized queries in Repo operations
- Row limits to prevent memory exhaustion (100 records default)
- Proper error messages without exposing internal details