Skip to content

2026.4 ​

Model Context Protocol ​

MCP Server and Ingress Tools Feature ​

Hantera now exposes a Model Context Protocol server at /mcp. Compatible AI clients and developer tools connect through Hantera OAuth 2.1 using Dynamic Client Registration or a Client ID Metadata Document.

The shared endpoint exposes permission-gated resources, built-in read-only system_* tools, and tools explicitly defined by tenants through MCP ingresses. An app can expose a compiled Reactor component with type: mcp; app tools receive deterministic apps_… names, while tenant-managed ingress tools use the tool_… namespace.

Generic MCP authorization includes mcp/tools:call in the default MCP scope bundle, allowing authorized clients to discover and invoke tools. Tenants can instead grant access to individual ingress tools with mcp/tools/ingress/{id}:call. Unauthorized tools are hidden rather than returned as forbidden.

See Model Context Protocol, MCP Ingresses, and the MCP API Reference for connection, authorization, and tool-authoring guidance.

Authentication ​

OAuth Dynamic Client Registration and Client ID Metadata Documents Feature ​

Hantera OAuth now supports two ways for public clients to identify themselves without an administrator pre-registering each application:

  • Dynamic Client Registration (DCR) — clients submit their metadata to /oauth/register.
  • Client ID Metadata Documents (CIMD) — clients use an HTTPS metadata document URL as their client_id; Hantera fetches and validates the document during authorization.

Both mechanisms use the authorization code flow with PKCE. Registration alone does not grant access: a user with iam/dynamic-clients:authorize must authorize the client, and its effective permissions are limited by client policy and the user's authority. OAuth authorization server metadata advertises the enabled discovery options.

This makes it easier to connect compatible third-party applications, including MCP clients. See Authentication and Model Context Protocol.

Orders & Promotions ​

Attributable Promotion Discount Groups Feature ​

Promotion components can now return group(key, label, dynamic, effects) to attribute one or more discount effects as a separately reportable commercial discount. The wrapper accepts only discount effects, so messages and nested groups are rejected at compile time; explicit keys must be non-empty and unique for each promotion evaluation.

Calculated discounts now expose groupKey, label, and dynamic snapshots. This makes actual granted discount amounts queryable by campaign even when one promotion evaluates several ordered rules. Group dynamic fields replace promotion dynamic fields when supplied; otherwise the promotion metadata is used. Ungrouped promotion effects retain their previous behavior through the implicit promotion-default group, and static discounts automatically forward their description and dynamic fields.

See Order Promotions — Discount-effect groups for examples and reporting semantics.

Target-Level Promotion Effect Conflict Modes Feature ​

Promotions can now decide how otherwise-compatible discount effects interact when they target the same order line, fulfillment shipping charge, or fee.

Promotion groups continue to decide whether promotions can be active together. After that group compatibility step, target-level effect conflict modes select effects independently by target, conflict key, and mode:

  • best — keeps the effect with the largest resolved currency discount on that target. This lets a percentage offer and a fixed-amount offer compete fairly.
  • replace — keeps the effect with the highest explicit priority. Use it when one commercial policy is authoritative over another.
  • cumulative — preserves the existing behavior: effects apply alongside other eligible effects.

Promotion components use the conflict decorator with the typed ConflictMode union ('best' | 'cumulative' | 'replace'). Components can expose that mode as a configurable parameter for an app or portal UI.

Existing promotion components remain cumulative unless they use the decorator, so this feature is backward compatible.

See Order Promotions — Effect Conflict Modes for usage and examples.

Ingresses ​

Execution Authority Feature ​

Ingresses can now control the authority under which their target Reactor component runs independently from the permission that admits a transport call. The canonical execution object supports three modes:

  • acl — runs with exactly the ingress ACL. This remains the default.
  • caller — preserves the authenticated caller's effective authority.
  • restricted-caller — runs with the intersection of the caller authority and the ingress ACL.

Existing root-level acl definitions remain compatible and retain their previous behavior: they normalize to execution.authority: acl. New manifests and ingress API writes should use the canonical execution object. Ingress API reads now return that object; a write may use either execution or the legacy root-level acl, but not both.

Authenticated HTTP and MCP ingresses support all three modes. Public HTTP, queue, and stream ingresses remain ACL-only because their invocations do not have an authenticated Hantera caller authority.

See Ingress Execution Authority for configuration, transport support, and examples.

Portal ​

Workflows and Tasks Feature ​

Portal workflows bring outstanding work from apps together in configurable worklists. Apps provide task sources with their own business logic, parameters, and detail views; administrators combine those sources into workflows and choose the roles or identities that see them in My Tasks.

Operators can open a workflow or the combined My Tasks inbox, see task counts, search the list, and work through app-provided detail views with previous and next navigation. Task collections are reactive, so work can appear or leave the list as the underlying data changes. Workflow audiences control visibility, not access to the underlying data: existing Graph and app permissions still apply.

App developers can register sources through apps.standardServices.workflows.taskSourceProvider and use useTaskContext() in a detail view to advance to the next task. See Portal Extensions for the app service pattern.

Presence for Collaborative Work Feature ​

The order view now shows presence avatars for people viewing the same order. Workflow task views also show presence for the selected task, helping colleagues spot overlapping work.

Portal apps can opt into presence in their own views using usePresence() from @hantera/portal-app, or render the global PresenceAvatars component. Apps choose a local activity scope; the portal automatically namespaces app scopes and supplies a reactive roster of identity IDs. Names and pictures are resolved separately under the viewer's existing permissions.

Presence is ephemeral and advisory: it does not lock a record or prevent concurrent actions.

Dynamic Graph Permissions in the Permission Picker Improvement ​

The permission picker's Graph group is no longer hard-coded. It now lists one permission per node in the tenant's loaded Graph meta model, so custom nodes contributed by apps — for example typed assets or tickets — appear automatically, without resorting to custom permissions.

Each node grants graph/<node>:* and is labeled with the node's name, sorted alphabetically. Leading asset. and ticket. namespaces are stripped from the label, so ticket.cart is found under "cart" rather than under "ticket". The permission id always keeps the full node key.

Graph ​

Correct Counts for Table-Formatted Queries Bugfix ​

Graph queries using table formatting now return the correct total count when a count is requested. The count represents expanded table rows, including combinations from multiple selected collections, rather than only root nodes or rows on the current page. Root cursor boundaries and count caps still apply.

See Graph for query and authorization details.

Filtrera & Developer Tooling ​

Liquid Template Module Feature ​

Hantera component runtimes now provide a liquid module for rendering reusable text templates with structured data. Use it in rules and Reactor components for messages, notifications, documents, and other generated content.

Import the module with import 'liquid', validate template syntax with parse, and use render to produce output and warnings. Missing fields render as empty text and are reported in the warnings; a hard rendering failure returns nothing instead of partial output. Number, date, instant, duration, and percent filters support locale-aware formatting, with invariant formatting when no valid locale is supplied.

The module renders text rather than sanitizing HTML. When producing HTML, encode interpolated values and sanitize the output as appropriate. See the Liquid module reference for usage and examples.

Platform & Core ​

Improved Actor Cache Distribution Improvement ​

Primary actors now share a single retention budget across actor categories instead of reserving separate capacity for each category. Recently reused actors receive protected space, helping active actors stay cached when a workload scans many others.

Deployments can set Performance:ActorCacheGlobalSize to control the total number of strongly retained primary actors. If it is not set, the budget is derived from the existing Performance:ActorCacheSize multiplied by the number of registered actor categories, preserving the previous maximum total count. This setting limits retained actor count, not total process memory.

© 2026 Hantera AB. Org. no.: 559242-9582