Getting Started
Changelog
All notable changes to Routecraft.
Routecraft is in active development -- APIs may change between minor versions.
v0.6.0 Pre-release
August 2026
This section covers every change since the v0.5.0 release. 0.6.0 is the architecture release before v1: the contracts that freeze at v1 changed shape once, now, so they do not have to change after, and the engine rework brings a significant performance improvement to route and event processing. See the 0.5.x to 0.6.0 migration guide for all upgrade steps.
Core Breaking
- Fixed event names; identity in the payload -- hierarchical names like
route:<id>:exchange:failedbecome a fixed set (route:exchange:failed) withrouteIdindetails. Wildcard patterns onctx.on()/ctx.once()are replaced by exact names, the"*"catch-all, and theforRoute()filter helper (theevent()source adapter keeps its pattern support); ecosystem packages declare events by merging intoEventDetailsMap.plugin:registeredis removed (it duplicatedplugin:starting). Subscriptionsource contract -- source adapters receive a singleSubscriptionobject ({ context, signal, meta, ready(), complete(), emit() }) instead of five positional parameters..from()additionally accepts async generator functions and (async) iterables, and@routecraft/testingadds atestSubscription()helper.StepOutcomestep contract -- customStepimplementations return what happened (continue/complete/drop/branch/fanOut) and the executor owns all scheduling; the wrapper buffer/relay protocol is gone. Per-execution metadata rides the outcome instead of mutating the sharedStepinstance. Custom aggregators return{ body, headers? }instead of a fabricatedExchange.- Namespaced error-code registry -- ecosystem packages own codes under a claimed namespace via
registerErrorCodes()plusErrorCodeRegistrydeclaration merging;RCis reserved for core. AddsRC1003(error-code registration failed). - Type-enforced builder positioning --
craft()returns a pre-frombuilder, so pipeline operations before.from()are compile errors; builder generics move to a state bag (RouteBuilder<{ body: T }>,AnyRouteBuilderfor lists). - Splitters return child bodies --
.split()callbacks return values (orsplitChild(body, headers)for per-child header overrides) instead of hand-builtExchangeinstances; the framework owns child construction. - Consumer SPI --
Consumer.registerreceives theMessageenvelope and consumer classes construct from oneConsumerDepsbag;Message,ProcessingQueue,ConsumerType, andConsumerDepsare exported. - Per-adapter header key objects --
HeadersKeyskeeps framework keys only; adapter keys move toTimerHeaders/CronHeaders/FileHeaders/CsvHeaders/JsonlHeaders/MailHeaders/CarddavHeaders;HEADER_MAIL_*/HEADER_CARDDAV_*andHeaderKeysRegistryare removed (wire keys unchanged)..header()rejects every engine-ownedroutecraft.*key up front. client.sendDirectand public capability discovery --CraftClient.sendis renamedsendDirect(response generic defaults tounknown);context.capabilities()replaces reads of the internal direct registry, andADAPTER_DIRECT_REGISTRY/getDirectChannel/sanitizeEndpointare no longer exported.- Naming sweeps --
CardDAV*exports becomeCarddav*(acronym casing per theHttpprecedent), the carddav option types adopt the two-sided Server/Client naming (CarddavServerOptionsfor the read role,CarddavClientOptionsfor writes and deletes), and jsonl's three file option types fold into oneJsonlFileOptions. choice()variadic surface;BranchBuilderrenamed,ChoiceSubBuilderremoved -- the fluent callback.choice(c => c.when(p, fn).otherwise(fn))becomes variadic.choice(when(p, fn), ..., otherwise(fn))with standalonewhen/otherwisehelpers imported from@routecraft/routecraft, the path surface now shared with the newmulticast.BranchBuilderis renamedPathBuilder;ChoiceSubBuilderis gone.- Adapter role model:
Source/Destination/Enricher--Destination.sendis now strictly void and the newEnricher.fetchpulls a value in, so the operation keyword selects the role instead of an option value. Pull-in adapters are renamed to*EnricherAdapter, and@routecraft/ai,@routecraft/osand@routecraft/testingraise their core peer range to>=0.6.0. See the migration guide. .enrich()replaces the body by default -- with the aggregator omitted it now replaces rather than spread-merges, so audit every bare.enrich().only()andnone()still merge, andreplace()is deleted. See the migration guide.- File-family adapters drop
mode--file,csv,json,jsonl,xmlandhtmltake their role from the operation keyword, withappend: true/delete: trueselecting send behaviour. Two silent flips to audit:jsonlsends now overwrite by default, and a migrated.tap(json({ path }))writes wheremode: 'read'used to read and discard. See the migration guide. MailSendResult,CarddavWriteResultandCarddavDeleteResultdeleted -- sends that produce a receipt now surface it onroutecraft.mail.*androutecraft.carddav.*headers instead of replacing the body. See the migration guide.- Option laws: arity is not a discriminant, key presence means supplied --
mail()returns one read adapter for both call shapes rather than changing role with a second argument, and a supplied-but-undefinedpathon the codec adapters now throwsRC5003instead of silently selecting the transformer role. Both changes are additive for code that already compiled. See the migration guide. .input()validation folds into the pre-from filter chain --.error()can now observe and recover an input failure, which previously bypassed it. Migrate observers: validation failures no longer emitroute:exchange:dropped, they take the normal error path..retry({ exponential })removed in favour offactor-- migrateexponential: truetofactor: 2andexponential: falsetofactor: 1, the new default; the old option throwsRC5003at build with a hint. See the retry reference for the backoff, cap and jitter options.authorize()defaults toactor: 'none'--Principalbecomes delegation-aware (RFC 8693act/may_act) and the newdelegate()helper mints delegated principals, so a principal carrying an actor, including a Clerk impersonation session, is rejected until the route declares its permitted actors. AddsRC5034toRC5038. See the migration guide and securing capabilities.
Core
- Recovery directives --
.error()handlers may returnrecovery.drop(reason?)(discard the failing exchange) orrecovery.rethrow()(decline recovery) instead of a recovery body or a manual throw. - Open error and principal models --
rcErroraccepts a per-occurrenceretryableoverride;RCMeta.categoryandPrincipal.kindaccept ecosystem-defined strings alongside the known values. - Plugin identity and lifecycle -- plugins may declare
name(used aspluginIdon events and logs) and reservedependsOn;registerTeardowncallbacks unwind LIFO;getRoutes()returns a copy. route:source:failedlifecycle event -- fires when a source subscription rejects (the source gave up producing), with{ routeId, route, adapter?, error }. Unlikeroute:stoppingit never fires for an orderly shutdown, so it is the signal to alarm on for a dead channel.concurrency(bulkhead) wrapper operation --.concurrency({ max })bounds how many exchanges run an operation at once, the sibling of.throttle(), which bounds a rate. See the concurrency reference.dispatchload-balancing operation --.dispatch(strategy, ...targets)runs exactly one of several targets by failover, round-robin, weighted or sticky strategy, the sibling ofmulticastandchoice. See the dispatch reference.debounceflow-control operation --.debounce({ waitMs })releases only the last exchange in a burst after a quiet period, for file-change batching and search-as-you-type. Route scope only, and a pending exchange is flushed on drain rather than lost. See the debounce reference.sampleanddedupeflow-control operations --sample()passes every Nth exchange or the first in each time window, anddedupe()suppresses duplicates by a derived key. Both drop silently, like afilterreturning false. See the sample and dedupe references..timeout()propagates anAbortSignal-- an expired deadline now cancels the wrapped step instead of leaving abandoned work running in the background, andhttp()forwards the signal into its fetch automatically. The.timeout(ms)surface is unchanged. See the timeout reference..input({ body })retypes the builder -- the following.from(source)opens the pipeline with the schema's inferred output type, so the duplicated.from<T>()generic is no longer needed.jwt()andjwks()surfaceclockToleranceSec-- a consumer re-checking a verified principal'sexpiresAtcan now see the skew the verifier allowed. The expiry boundary is also inclusive everywhere, matching jose and RFC 7519, wherejwt()previously honoured an expired token for one further second. See the migration guide.
AI & MCP Breaking
-
AI error codes renamed --
RC5025/RC5026/RC5027becomeAI1001/AI1002/AI1003under the newAInamespace; update any code or alerting that matches onerror.rc. -
Agent blocks replace skills --
AgentOptions.skillsandagentPlugin({ skills })are removed in favour of ablocksrecord that unifies skills, memory, identity, and instructions, with progressive disclosure now the default. -
skills({ source })andfromFile(path)builders --skillsnow returns ablocksrecord to spread intoblocks: { ... };fromFilereads a UTF-8 file at resolution time. -
Nested block groups -- a
blocksvalue can be a single block or a nestedblocksgroup, soskills({ source })can stay grouped under one key (blocks: { skills: await skills(...) }) instead of being spread flat. Groups flatten togroup__leafnames. -
Tag selectors on
tools()removed -- the{ tagged }/{ tagged, from }variants and thetagsoverride ondirectToolare gone. Use the newtools((catalog) => [...])builder form for dynamic selection. -
Block-loader calls partitioned out of
toolCalls-- progressive loads surface onAgentResult.blocksLoadedand emitagent:block:*events instead ofagent:tool:*. -
skills:frontmatter onagents()rejected -- supplyblocksthrough the per-agent overrides map instead. -
New error codes
AI1001-AI1003-- block resolution failure, name collision / reserved_block_prefix, and block misconfiguration. -
direct_<routeId>and_block_load_<name>tool names renamed -- synthetic tool names now use__as their sole structural separator, so they becomedirect__<routeId>and_block__load__<name>. Fn ids andmcp__<server>__<tool>are unchanged, and theDirect(...)/MCP(...)authoring grammar does not change. Update anything pinning a generated name: tool-name guards, assertions ontoolCalls[].toolNameorblocksLoaded[].toolName, recorded transcripts, evals. See the migration guide. -
ResolvedTool.sourceis a new required field -- a resolver-setfn/direct/mcp/blockdiscriminant. Affects only code that hand-constructs aResolvedTool. -
Direct(<routeId>)and fn ids validated against the provider charset -- a name that cannot survive as a provider tool name (/^[A-Za-z0-9_-]{1,64}$/) now raisesRC5003naming the offending character or length, rather than being rejected by the provider later. Expose an unsafe route id under a tool-safe alias withdirectTool(routeId). An MCP client tool whose remote name cannot form a valid wire name is dropped with a warning instead of failing the dispatch. -
MCP protocol revision 2026-07-28: the server is stateless --
mcpPluginbuilds a fresh server per request, so any replica can answer any request behind a plain load balancer. Sessions, their events andMcpHeadersKeys.SESSIONare gone, and the@modelcontextprotocol/sdkv1 peer is replaced by the v2 package split. 2025-era clients keep working. See the migration guide. -
oauth({ endpoints, client })removed;oauth()becomes a resource-server helper -- it no longer proxies your Authorization Server, so point clients at your IdP's own endpoints, which they discover from the RFC 9728 metadata Routecraft serves. Passissuerinstead. See the migration guide. -
MCP client names reject
__and a trailing_-- such a name composed an ambiguousmcp__<server>__<tool>that resolved to the wrong tool, silently, somcpPlugin()now throwsRC5003at startup with a suggested replacement. A single underscore inside the name is unaffected. See the migration guide.
AI & MCP
agentPlugin({ toolPolicy })-- repository-wide admission control for the agent tool surface, keyed by tool kind (fn/direct/mcp), eachtrue,false, or a predicate over a read-only tool descriptor. Omit it and nothing changes; supply it and the surface becomes an allowlist where every kind must be decided. Enforced at the single point every agent form converges on, so inline, registered, markdown, and nested agents are all covered, and multiple installs compose with AND. See the tool policy reference.route:agent:tool:deniedevent -- emitted once per tool refused admission by a policy, carryingagentName,toolName,toolKind, and areasonofrule,rule-error, orunknown-provenance, so denials are alertable and auditable rather than only logged.mcpPlugin({ proxy })re-exposes client tools -- proxy tools from registeredclientsthrough the Routecraft MCP server without a route per tool, with an optional per-toolguard. Proxied calls run no route pipeline and do not forward the caller's principal, so reserve them for simple read-only tools. See the expose as MCP guide.baseURLhonoured by the Anthropic and Gemini providers -- previously only OpenAI honoured it, so explicit config lost to the ambientANTHROPIC_BASE_URLenvironment variable.
Internals
- Engine restructuring --
CraftContextdelegates events to an internalEventBus; adapter config keys (cron,direct,mail,telemetry,http) move to per-module config appliers; the route engine splits intopipeline/modules (executor, validation, synthetic steps). Two behavioural notes: context store seeding for adapter config now happens ininitPlugins()(called automatically bystart()), and plugin teardown (includingregisterTeardowncallbacks) drains in reverse order. - Uniform factory tagging -- every public adapter factory is tagged for
mockAdapter(), enforced by a conformance test; previouslydirect,simple,timer,cron,log,noop, and others (plus two transformer-mode branches ofhtml()/json()) were silently unmockable. - Every optional peer loads through
loadOptionalPeer-- the mail drivers andagentBrowser()now surface a missing package asRC5017with an install hint rather than a raw module-not-found, and detection no longer misses the phrasing Bun uses for a subpath import. A contract test scans all four code packages for bare external dynamic imports. - Config appliers restored in the published bundles -- a
sideEffectsallowlist let esbuild prune every core config applier out of the published bundle, sodefineConfig({ mail: { accounts } })typechecked but never applied at runtime. A post-build guard now asserts every applier is live in the registry, and an unrecogniseddefineConfigkey warns instead of being a silent no-op. @routecraft/ai,@routecraft/osand@routecraft/testingdeclare core as a peer -- at>=0.6.0 <1.0.0, with a workspace devDependency for development, instead of duplicating core as a regular dependency.- Dependency floors refreshed -- runtime ranges on
@routecraft/ai,@routecraft/cliandcreate-routecraftmove to their newest in-range minor and patch releases, and core's optionalfast-xml-parserpeer floor rises to^5.10.1to exclude a DOCTYPE entity-expansion advisory. No majors are included, and theimapflowfloor is held back deliberately.
Adapters
- HTTP source Breaking --
http()is now a two-sided adapter.http({ path, method? })exposes a route over HTTP viadefineConfig({ http: { port, host, auth } }); Bun runtimes bind throughBun.serveand Node 22+ uses a zero-dependencynode:httpshim. Global auth acceptsjwt()/jwks()bearer orapiKey({...}); per-route constraints reuse.authorize({...}). Per-route auth handling has three modes viahttp({ auth: "required" | "optional" | "skip" }): secure-by-default"required","optional"(admit anonymously, attach principal when a valid credential is present, reject invalid credentials), and"skip"(bypass the middleware entirely for truly identity-free routes like RSS or probes). Built-in/health,/ready, and/openapi.jsonendpoints register automatically. Each is configured via the uniformhttp: { builtins: { health, ready, openapi } }block with{ enabled, requireAuth }per endpoint (Spring-Actuator-inspired). Defaults gate theroutescount on/readyfrom anonymous callers (requireAuth: true) and keep/openapi.jsonpublic (requireAuth: false, matching the Stripe / GitHub / Twilio convention). Request bodies are parsed byContent-Type(JSON / text / urlencoded / multipart), capped bymaxBodySize. Adds error codesRC5018(request rejected) andRC5019(server bind failed). Breaking: the destination option typeHttpOptions<T>is renamedHttpClientOptions<T>(the source usesHttpServerOptions); a type-only change with no runtime impact. - CSV and JSONL decode transformers -- calling
csv()orjsonl()with nopathnow returns a transformer that parses a CSV / JSONL string already in the body (for example anhttp()response), matching the existingjson()andhtml()decode transformers. AddsCsvTransformerOptions,CsvFileOptions, andJsonlTransformerOptions;csv()'spathis now optional. A dynamic (function) path used as a destination now works forhtml()too, where it previously threw at construction. xmladapter -- read, write and transform XML through a plain-object representation, mirroring thejsonandcsvcodec adapters.fast-xml-parserloads as an optional peer. See the xml reference.directoryadapter -- scan a directory and list its entries as a source, or pull a listing in mid-route with.enrich(). Emits one exchange with the full listing by default, or one per entry withchunked: true. See the directory reference.- CSV appends no longer splice records together -- appending
a,band thenc,dthrough.to(csv({ append: true }))used to writea,bc,d. Appends are also serialised per path, so concurrent writes can no longer both emit the header. - Signed webhooks on the
http()source --http({ signature })verifies the raw request bytes before the route runs, covering the GitHub, legacy HMAC-SHA1 and Stripe timestamped schemes, andhttp({ rawBody: true })exposes those bytes for any other scheme. AddsRC5039. See securing capabilities. /openapi.jsonnever advertises a workspace container -- when the nearestpackage.jsonis a monorepo root, auto-detection serves the neutral fallbacks instead of the container's private, often stale identity. Apps run from their own directory are unaffected. See the http reference.
- Mail source envelope moves to headers Breaking --
.from(mail(...))now follows the payload-on-body, envelope-on-headersconvention shared with the HTTP source. The exchangebodyis aMailBody({ text?, html?, attachments? }) and the envelope (from,to,cc,bcc,subject,date,messageId,replyTo,flags,sender,rawHeaders) lands onroutecraft.mail.*headers, declaration-merged intoRoutecraftHeadersand exported on theMailHeaderskey object..input({ body })now validates against the message content alone. The fetch destination (.enrich(mail(...))) still returnsMailMessage[]unchanged. New exported typeMailBody. - Direct mail no longer misclassified as auto-forwarded -- a single first-hop ARC seal (
i=1,cv=none) added by the delivering MX is no longer read as forwarding, so DMARC-aligned direct mail staysdirect/verifiedinstead ofunverified. Mailing-list and validated-forward classification are unchanged. - Connection recovery covers every failure path, and is configurable -- IDLE-mode fetch failures and the initial connect at route start now go through the same reconnect-with-backoff loop as IDLE drops and poll fetch failures (previously they killed the route), and the folder is drained right after a reconnect so mail that arrived during an outage is delivered immediately. New
reconnect: { maxAttempts?, baseDelayMs?, maxDelayMs? } | falseoption onMailServerOptions(defaults match the old hardcoded 30 / 1s / 60s;maxAttempts: Infinitynever gives up;falsefails fast). Because the initial connect retries, the source signals readiness before the first connection succeeds, soroute:startedno longer guarantees the mailbox was reachable. New exported typeMailReconnectOptions. When any source gives up for good, the new coreroute:source:failedevent fires with{ routeId, route, adapter?, error }so a dead channel can be alarmed on (#425). - Threading and custom headers on the send payload --
inReplyTo,referencesandheaders, so agent replies stitch into the original email thread. - IMAP operations report their metadata again --
move,copy,delete,flag,unflagandappendlost theirs when the role model split the observability hooks.
Packages Breaking
@routecraft/prettier-plugin-routecraft-- new package, formatting DSL chains compactly so a route reads as one shape rather than one operation per line. See formatting.agentBrowser()moves to@routecraft/os-- browser automation folds into@routecraft/osand the standalone@routecraft/browserpackage is deprecated. Update imports; the factory, options and result shape are unchanged.
Docs site
- Blog at /blog -- Markdoc-backed posts with a featured + latest layout.
- Cheat sheet at /cheat-sheet -- searchable single-page DSL reference, print-to-PDF friendly.
- 0.5.x to 0.6.0 migration guide -- step-by-step upgrade notes for every breaking change above.
v0.5.0 Pre-release
May 2026
Several breaking changes across the core, AI, mail, telemetry, logger, and CLI surfaces. See the 0.4.x to 0.5.0 migration guide for the full public-API diff and step-by-step upgrade notes.
Core
- Dual-mode wrapper pattern --
.error()becomes a route-level wrapper rather than a top-level method, and source-level parse errors flow through the same handler. - Immutable Exchange -- the
Exchangeis frozen with explicit copy-on-write; state is unified on{ body, headers }. .authorize()route-entry guard -- a route-only authorization validator that replacesrequirePrincipaland raisesRC5020when a credential expires mid-run.- Field-shaping helpers
keepandmask-- two.transform()helpers:keepis grant-based, fail-closed allowlisting;maskobfuscates values regardless of caller. - Choice operation -- a conditional routing primitive with
transform()andenrich()on branch builders. - Discovery metadata on the route builder -- route id, description, and validation move from source options to the builder.
AI & MCP Breaking
- Agent runtime -- tool-calling loop, streaming via
onEvent/onDelta, agent destination, and per-binding tool description overrides. tools()DSL -- declarative tool registration, selection, and resolution.- Agent configuration overhaul --
agentPlugin.agentsis a record (nodefineAgent), andsystem/useraccept a string or function. See the migration guide. - MCP OAuth 2.1 server -- OAuth 2.1 provider with principal hierarchy, plus a general MCP HTTP auth surface and tool annotations.
- MCP protected-resource metadata -- resource identity moves to
mcpPlugin({ title, resource }); both validator and OAuth-proxy modes auto-mount RFC 9728 metadata. Field-by-field moves are in the migration guide. - Plugin-level
userinfoenrichment --mcpPlugin({ userinfo })hydrates the principal after verification, enabling the WorkOS AuthKit pattern. Lives on the plugin, orthogonal to the auth mode. ClaimMappers.{email,name,roles}removed -- superseded byuserinfoenrichment; the token-level mappers remain.- New error codes
RC5020-RC5022-- token expired during processing, principal enrichment failed, and userinfosubinvariant violated.
Adapters
- Adapter mocking --
mockAdapterswaps any tagged adapter in tests; thefile,csv,json,jsonl, andhtmlfactories are tagged out of the box. direct<TIn, TOut>()distinct types -- a route can accept one body shape and emit another.- Mail (IMAP) reliability -- reconnect on transient fetch failures, a reshaped
MailMessagebody, and a verify-sender option. - Optional peer loader everywhere -- every optional-peer import now routes through
loadOptionalPeerand emitsRC5017with an install hint.
Telemetry Breaking
- Bun-only SQLite sink -- the built-in telemetry sink uses
bun:sqlite;better-sqlite3is removed. Node deployments that relied on it must bring their own sink.
Logger
- stdout default -- the logger writes to stdout instead of stderr.
CLI & Tooling
- Bun-only
craftCLI -- the published binary now requires Bun >= 1.1.0. - Bun monorepo -- installs, scripts, and lockfile migrate from pnpm to Bun.
create-routecraftrefactor -- scaffolder extracted into a library with expanded test coverage.bun:testeverywhere -- the internal suite migrates off vitest, retained only for the cross-runtime tests.
Docs
- Migration guide -- new 0.4.x to 0.5.0 migration guide.
- Canary docs at
/next/-- canary builds deploy alongside the stable build at the root. - Operator reference --
loganddebugdocumented;mapandschemaclarified. - Claude Code skills -- Agent Skills for authoring adapters and capabilities bundled at the repo root.
v0.4.0 Pre-release
March 2026
Adapters
- Cron source -- new adapter for scheduling capabilities with cron expressions.
- JSONL adapter and chunked mode -- read and write line-delimited JSON with chunked streaming for large files.
- Modular adapter structure -- adapters refactored into a consistent file layout with a unified DSL registration system.
- Merged options --
cronanddirectadapters now support merged options across config and route.
AI & MCP
- stdio MCP client -- spawn and manage stdio-based MCP servers with a unified tool registry.
- Bearer token authentication -- secure MCP HTTP transport with bearer tokens.
Framework
- Terminal UI -- new TUI for inspecting running contexts and routes.
- Reduced public API surface -- internal-only exports are no longer published, tightening the long-term API contract.
TypeScript
- Declaration-merging registries -- compile-time adapter safety via type registries that adapter packages can extend.
Testing
- Spy adapter assertions -- richer assertion helpers in
@routecraft/testingfor spying on capability output.
Docs
- Light mode -- hero section and syntax highlighting now respect light mode.
- Copy-to-clipboard -- code blocks gain a copy button.
- Community resources -- new section linking external content and contributors.
- Dark-mode contrast -- prose strong text is more readable on dark backgrounds.
v0.3.0 Pre-release
March 2026
Adapters
- Agent, embedding, and LLM adapters -- new adapters for integrating AI agent workflows, embedding models, and large language models directly into capabilities.
- HTTP adapter -- first-class HTTP source and destination support.
- Browser and HTML adapters -- interact with web pages and parse HTML content.
- JSON adapter -- dedicated adapter for JSON data sources.
- Grouping adapter -- group messages by key before forwarding.
- File adapter -- read and write text, JSON, and CSV files with a unified adapter.
AI & MCP
@routecraft/testingpackage -- expanded testing utilities with MCP integration support.- Consistent adapter pattern -- all adapters now follow a unified pattern for configuration, lifecycle, and error handling.
Events
- Hierarchical event model -- new operation-level events with parent-child relationships, enabling fine-grained observability across capability execution.
TypeScript
- TypeScript support -- author capabilities in TypeScript with full type inference and compile-time validation.
Docs
- Capability-centric terminology -- all documentation renamed from "routes" to "capabilities" for consistency.
- Advanced guides -- new documentation covering advanced patterns, capability composition, and adapter authoring.
v0.2.0 Pre-release
February 2026
AI & MCP
- New
@routecraft/aipackage -- MCP integration with full schema validation via Zod. Expose any capability as an MCP tool for Claude Desktop, Cursor, and other MCP clients. - MCP server support -- run your capabilities as an MCP server with a single CLI command.
- MCP client support -- call external MCP servers from within a capability using the
mcpPlugin.
Adapters & Operations
directadapter validation -- improved validation and error messages for inter-capability communication.aggregateoperation -- default aggregator now flattens arrays and combines scalars automatically.batchoperation -- new ESLint rule (batch-before-from) enforces correct batch positioning at the route level.pseudoadapter -- new adapter for stubbing sources and destinations in tests and local development.
Framework
- Cross-instance identity -- supports multiple package copies and
npx-based installs resolving to the same context identity. - Logging configuration -- enhanced logging setup with more control over levels and output format.
v0.1.1 Pre-release
November 2025
Quality-of-life improvements.
Adapters
- Custom log messages -- adapters and operations now support custom log message overrides.
- Fetch adapter -- automatically parses JSON responses, no manual parsing needed.
Framework
.env.localsupport -- environment variables in.env.localare loaded automatically alongside.env.
Tooling
create-routecraft-- project scaffolding now supports example selection and template file configuration.- CodeSandbox -- added online playground link in the installation docs for zero-install experimentation.
v0.1.0 Pre-release
October 2025
Initial release.
Framework
- Fluent DSL --
craft().from().to()builder syntax for authoring capabilities. - Core operations --
transform,filter,enrich,aggregate,split,validate,tap,process,header, and more. - Backpressure -- simple and batch consumers with built-in backpressure support.
- CraftContext -- route lifecycle management with hot reload in development.
- Error handling -- structured RC error codes with Pino logging.
Adapters
- Built-in adapters --
simple,timer,direct,log,noop,fetch.
Tooling
- CLI --
craft runandcraft watchcommands. create-routecraft-- project scaffolding tool.- ESLint plugin --
require-named-routerule out of the box. - Test utilities --
@routecraft/testingpackage withtestContextandspyadapter.