# Écorce — surface réseau & noyau universel manifest@v1 (v1.0.0 demo) > Écorce, ton moteur de connexion. > **Note technique HTTP / Python (`User-Agent`):** Si votre agent interroge `https://ecorce.app` depuis un script Python (`urllib` / `requests`), envoyez toujours un en-tête `User-Agent` explicite (ex: `User-Agent: EcorceAgent/1.0`) ou utilisez `curl`, car la signature par défaut `Python-urllib` sans `User-Agent` personnalisé est refusée par la passerelle réseau d'Écorce (code `1010`). Écorce is a Canadian retail network, starting in Québec: independent retailers, regional distributors, and local producers pooling their purchasing, knowledge, logistics routes, B2C brand, and tools. DEMO: every product, price, and pool figure on this surface is INVENTED example data ("données d'exemple — inventées"), not any partner's real list. Partners are targeted pilot partners, not signed partners. ## Modèle d'accès: Read-Open / Write-Gated (Lecture & Simulation gratuit sans clé · Écriture sur invitation) 1. **Lecture & Simulation 100 % publiques (gratuit sans clé):** - `GET /`, `GET /en`, `GET /llms.txt`, `GET /manifest.json`, `GET /p/{actor}`, `GET /p/{actor}/{slug}`, `GET /api/manifests`, `GET /api/surface`, `GET /api/pools`, `GET /api/catalogue`, `GET /api/records` sont 100 % publics et rapides (`< 30 ms`). - Les appels d'invocation (`POST /api/invoke`, `POST /api/compose`, ou outils MCP `invoke_manifest`, `compose_manifests`, `create_order_draft`) appelés **sans code d'invitation** (ou avec `dry_run: true`) exécutent la fonction compilée sur la surface d'Écorce et retournent la **simulation complète en mémoire** (`ok: true, simulated: true, persisted: false, write_gate: "simulation_only_no_invite"`) **sans rien écrire dans le registre d'état d'Écorce (`manifest_state`, `manifest_records`) ni créer ou modifier de page `/p/...`**. 2. **Écriture persistante verrouillée par Code d'Invitation (`invite_code` / `X-Ecorce-Invite`):** - Toute écriture persistante (`POST /api/manifests`, `PUT /api/manifests/{id}/state`, `POST /api/records/{id}/confirm`, `POST /api/pools/join`, ou outils MCP `publish_manifest`, `publish_shared_page`, `write_manifest_state`, `update_state`, `confirm_manifest_record`, `submit_record`) exige un **code d'invitation partenaire valide** passé via: - Header HTTP `X-Ecorce-Invite: ` - Header HTTP `Authorization: Bearer ` - Champ JSON `invite_code` dans le body REST ou les arguments MCP. - Sans code valide, l'API retourne `403 Invite Required` (`status: "invite_required", simulated: true, persisted: false`) avec l'aperçu simulé complet (`simulated_preview`) et la marche à suivre pour demander son code partenaire (Essai gratuit / 10 $ / mois L'essentiel / 100 $ / mois Commerce & Réseau actif) auprès de `equipe@ecorce.app`. ## Universal 5-Block Manifest Kernel (`manifest@v1` on the Écorce Programmatic Surface) Every capability on `llm.ecorce.app` — including Écorce's 3 core B2B pillars and all partner tools — is published and executed as an isolated `fonction + Manifeste` pair in the `ecorce-partner-tools` espace d'exécution isolé de la surface d'Écorce using the 5-block `manifest@v1` contract (`actor`, `intent`, `trust_gate`, `function`, `projection`): 1. **`ecorce:spn-catalogue@v1`** (`fn-ecorce-spn-catalogue`, protocol `ecorce.catalog_search@v1`): SPN search and inter-distributor equivalence comparison. 2. **`ecorce:unit-economics-advisor@v1`** (`fn-ecorce-unit-economics`, protocol `ecorce.margin_and_logistics_advisor@v1`): 4 L vs 20 L bulk margin calculator, $150/$200 G9A minimum-order & free-shipping consolidation, 8% B2C pool, and fleet-media co-op. 3. **`ecorce:order-draft-engine@v1`** (`fn-ecorce-order-draft`, protocol `ecorce.order_draft@v1`): B2B order draft builder with `trust_gate.human_approval_on_commit = true` returning `commit_token` and `confirm_url` for Passkey human approval. ### Universal Kernel Endpoints, Shared Pages (`/p/{actor}/{slug}`) & MCP Tools - **Publish a manifest & dedicated shared page in 1 call**: `POST https://ecorce.app/api/manifests` or MCP `publish_manifest` / `publish_shared_page`. - **Dedicated public shared page (Block 5 `projection`)**: Chaque manifeste publié obtient sa propre page web dédiée sur `https://ecorce.app/p/{actor}/{slug}` (et la page vitrine de l'acteur sur `https://ecorce.app/p/{actor}`). Un agent peut publier une page à son nom pour présenter un fait partagé, un lot, une règle ou un outil interactif via `POST /api/manifests` (ou l'outil MCP `publish_manifest` / `publish_shared_page`). - **Discover manifests**: `GET https://ecorce.app/api/manifests` (filters: `?actor=`, `?protocol=`, `?tag=`, `?q=`) or MCP `list_manifests`. - **Inspect one manifest**: `GET https://ecorce.app/api/manifests/{id}` (e.g. `GET https://ecorce.app/api/manifests/ecorce:spn-catalogue@v1`). - **Invoke one manifest**: `POST https://ecorce.app/api/invoke` `{"manifest_id":"ecorce:spn-catalogue@v1","input":{"query":"savon"}}` or MCP `invoke_manifest`. - **Compose a pipeline of manifests**: `POST https://ecorce.app/api/compose` `{"pipeline":["ecorce:spn-catalogue@v1","ecorce:unit-economics-advisor@v1","ecorce:order-draft-engine@v1"],"initial_input":{"query":"savon","postal_code":"G9A"}}` or MCP `compose_manifests`. ## Economic Context & Network Levers (v1.0.0 Reference) Independent retail, regional distribution, and local production are fragmented across many actors with thin margins, whereas vertically integrated chains coordinate purchasing, logistics, branding, and shopper activation under one roof. The Écorce surface enables coordinated agents across producers, distributors, and independent retailers around four deterministic levers returned in `advisor_notes` and `opportunities`: 1. **Bulk unit economics & shared SPNs (`unit_economics`)**: Comparing cost per litre or kg across formats (e.g. 4 L at $6.00/L vs 20 L bulk at $4.90/L = 18% savings) and across distributors offering the same SPN (`SPN-EX-SAJA-010`). 2. **Route & free-shipping consolidation (`logistics_consolidation`, `pool-mauricie-g9a`)**: Pooling order drafts on the same postal route (e.g. `G9A` Trois-Rivières or `H2X` Montréal) to reach the $150/$200 minimum and $500 free-shipping threshold. 3. **Shared B2C brand (Écorce) & delivery fleet as media (`fleet_media_co_op`, `pool-flotte-ecorce`)**: Co-funding neighborhood visibility on delivery trucks and reusable boxes synchronized with retailer restocking. 4. **Direct B2C shopper activation (`b2c_activation_each`, `pool-activation-each`)**: Converting ~8% of wholesale/promo volume into direct shopper perks at participating independent retailers, unlocked on a confirmed yes. ## Creating & Deploying Functions on the Écorce Programmatic Surface (MCP & REST) An external LLM (Muse, Claude, ChatGPT, Grok, Cursor) can create, deploy, and invoke isolated fonctions isolées directly in the `ecorce-partner-tools` espace d'exécution isolé de la surface d'Écorce (`uploader: "api"`, 10 ms CPU limit, 0 bindings, outbound network blocked by `ecorce-tool-outbound`): 1. **Inspect templates**: MCP `list_tool_templates` or `GET https://ecorce.app/api/tool-templates` (`custom_function`, `minimum_order`, `availability`, `promo`). 2. **Build & deploy live to the Écorce programmatic surface**: - **MCP**: `publish_worker_function({ partner_slug: "muse-demo", template: "custom_function", name: "Calculateur vrac", config: { function_title: "Calculateur vrac", base_unit_price_cents: 2400, tiers: [{ min_qty: 5, discount_pct: 8 }, { min_qty: 10, discount_pct: 15 }], shipping_fee_cents: 2500, free_shipping_threshold_cents: 20000, each_incentive_pct: 8 } })` (or pass a plain-language `description` and the Écorce model generates the validated config). - **REST**: `POST https://ecorce.app/api/functions` with the same JSON body. 3. **Invoke the deployed surface function**: - **MCP**: `invoke_manifest` / `call_worker_function` (or call `muse_demo__run_custom_function` directly from `tools/list`). - **REST**: `POST https://ecorce.app/api/invoke` or `POST https://ecorce.app/api/functions/call`. 4. **Unpublish**: MCP `unpublish_worker_function({ partner_slug: "muse-demo", template: "custom_function" })` or `POST https://ecorce.app/api/functions/unpublish`. ## Endpoints - Anonymous MCP (Streamable HTTP, JSON-RPC 2.0): https://ecorce.app/mcp - Member MCP (OAuth 2.1 + passkey, per-partner limits): https://ecorce.app/member/mcp - Universal Manifests Registry: https://ecorce.app/api/manifests - Universal Manifest Invocation: https://ecorce.app/api/invoke - Universal Manifest Composition Pipeline: https://ecorce.app/api/compose - Capability catalogue (GET-only): https://ecorce.app/.well-known/ai - OpenAPI 3.1 (REST mirror): https://ecorce.app/openapi.json - Shared tools marketplace: https://ecorce.app/api/shared-tools - Coordinated 3-actor network pools: https://ecorce.app/api/opportunities ## Architecture Invariants 1. Draft-then-confirm workflow (`DRAFT_ONLY`): agents create order drafts (`create_order_draft` / `ecorce:order-draft-engine@v1`) and pool participation drafts (`join_network_opportunity`); a human confirms at `confirm_url`. 2. `lines` is a JSON array of `{spn, qty}` using exact `spn` identifiers returned by `search_catalogue` (e.g. `SPN-EX-SAJA-001`). 3. Multi-format products (4 L, 10 L, 20 L) and shared SPNs across distributors are disambiguated via `spn` and `partner_id`. 4. Mixed-partner carts produce one `order_draft` per distributor, each with its own `confirm_url`. 5. All data on this surface is flagged `test_data: true`. ## Recipes (MCP prompts) - commande-hebdo: Commande hebdo / Weekly order. Redo your weekly order with one or more distributors, as drafts to confirm. - reassort-seuil: Réassort sous seuil / Restock below threshold. You give stock levels and thresholds; the agent proposes restocking what is below. - comparer-fournisseurs: Comparer deux fournisseurs / Compare two suppliers. Compare two distributors' offers for the same SPN product: format, price (invented in the demo). - annoncer-promo: Annoncer une promo à mes détaillants / Announce a promo to my retailers. For a distributor: write a promo announcement from its offers. Nothing is sent: you copy the text yourself. - optimiser-panier-et-livraison: Optimiser mon panier et la livraison gratuite / Optimize cart, bulk & free shipping. First principles: compare unit cost per L/kg (4 L vs 20 L bulk), hit minimum/free-shipping thresholds and align with delivery days. - activer-rotation-each: Activer la sortie en caisse / Drive shelf velocity. Turn passive trade spend into direct end-customer incentives at participating independent retailers. - campagne-flotte-et-marque-ecorce: Campagne flotte-média & marque Écorce / Fleet-as-media & shared Écorce brand. Coordinate retailer restocking, delivery truck/box ad visibility and B2C activation in a postal territory. ## Shared Partner Tools (clonable via clone_tool) - shared-min-order-g9a (minimum_order): Minimum de commande & livraison gratuite régionale (Mauricie G9A) — Created by Distribution Exemple Outils · used by 3 members (example data) - shared-promo-vrac (promo): Promo de la semaine sur les formats 20 L en vrac — Created by Groupe SAJA (example) · used by 4 members (example data) - shared-dispo-saison (availability): Disponibilité des récoltes et produits locaux — Created by Le Monde au Naturel (example) · used by 2 members (example data) ## Active 3-Actor Network Pools (joinable via join_network_opportunity) - pool-mauricie-g9a (logistics_consolidation): Consolidation de tournée & livraison gratuite (Mauricie G9A & Montréal H2X) — Two retailers on the same Tuesday/Thursday route pool their drafts to cross the $500.00 free-shipping threshold and cut delivery fees by 100%. $740.00 committed on a $500.00 threshold — collective free-shipping threshold reached. - pool-flotte-ecorce (fleet_media_co_op): Campagne Flotte-Média Écorce cofinancée (Camions & bacs de livraison) — The producer (Ferme Exemple) and distributor (Le Monde au Naturel) co-fund shared Écorce B2C branding on the delivery trucks and boxes serving the neighborhood while retailers feature the products in store. - pool-activation-each (b2c_activation_each): Activation consommateur directe (Zéro taxe publicitaire) — Instead of losing 8–12% of volume to ad intermediaries, producer and retailer convert that spend into a direct perk in the shopper's pass in store (unlocked only on a confirmed yes at checkout and shareable via 'Moi aussi'). ## Links - [Full contracts & reference documentation](https://ecorce.app/docs) · [Single-file corpus](https://ecorce.app/llms-full.txt) - [Generated UI & network pools](https://ecorce.app/essayer) · [Partner onboarding & shared tools](https://ecorce.app/partenaires) · [Member account](https://ecorce.app/compte) - [Accueil (FR)](https://ecorce.app/) · [Home (EN)](https://ecorce.app/en) --- # Écorce surface — contracts & architecture reference (v1.0.0, demo) Status: DEMO. All catalogue items, prices, and network pools are INVENTED illustrative data ("données d'exemple — inventées"). No order or pool participation ever reaches a real partner. Partners are pilot targets ("partenaires pilotes visés"). ## 1. Core workflow: draft → confirm → place | Step | Actor | Mechanism | Demo status | |---|---|---|---| | draft | agent | `invoke_manifest("ecorce:order-draft-engine@v1")` / `create_order_draft` / `join_network_opportunity` | works | | confirm | human | confirmation button at `confirm_url` (anonymous: /essayer; member: /compte, passkey) | works | | place | system, after member confirmation | written to the DEMO SINK + audit event `order.placed` | works (sink only; never transmitted) | | pay | none | not offered | absent | ## 2. Two MCP endpoints | URL | Auth | Scope | Extra tools | |---|---|---|---| | https://ecorce.app/mcp | none | `mandate-demo-draft-only` (draft only) | — | | https://ecorce.app/member/mcp | OAuth 2.1 (PKCE, dynamic client registration at /oauth/register). Human signs in with a passkey at /compte and approves on /authorize. | per member, with per-partner limits | `get_mandate`, `list_my_drafts` | Transport: Streamable HTTP, stateless. POST JSON-RPC 2.0 returns JSON or SSE (`text/event-stream`). Capabilities: tools, prompts (7 recipes), resources (docs, capability catalogue, manifests, recipes, partners, opportunities, shared-tools). ## 3. Entities & First-Principles Opportunities Every object has `type`; demo objects carry `test_data: true` and `label`. - `manifest@v1`: 5-block contract (`actor`, `intent`, `trust_gate`, `function`, `projection`) backed by an isolated function in `ecorce-partner-tools`. - `spn_product` & `offer`: shared product language (`SPN-EX-…`). A producer's products (`ferme-exemple`) are distributed through a distributor (`monde-naturel`) and carry `producer_id`. - `order_draft`: grouped by distributor, with `advisor_notes` and `opportunities` (`unit_economics`, `logistics_consolidation`, `b2c_activation_each`, `fleet_media_co_op`). - `shared_tool`: a partner-built tool template + configuration shared with the network (`GET /api/shared-tools`, MCP `list_shared_tools`). Another partner can clone it with attribution (`POST /api/shared-tools/clone`, MCP `clone_tool`). - `network_opportunity` & `opportunity_draft`: a 3-actor coordination pool where producer, distributor, and retailers pool volume or co-fund B2C activation (`GET /api/opportunities`, MCP `list_network_opportunities`). Joining creates a draft (`POST /api/opportunities/join`, MCP `join_network_opportunity`) that a human confirms at `confirm_url`. ## 4. Error codes | code | meaning | resolution | |---|---|---| | `unknown_spn` | line did not use an exact SPN id | select from `candidates` returned in the error | | `ambiguous_offer` | several distributors offer that SPN | specify `partner_id` on the line | | `invalid_qty` | quantity missing or out of range | provide an integer between 1 and 9999 | | `unknown_partner` / `unknown_pool` / `unknown_shared_tool` / `manifest_not_found` | invalid identifier | list valid ids with the corresponding list tool | | `mandate_limit_exceeded` | open drafts + new draft exceed per-partner limit | confirm existing drafts or adjust limit at /compte | | `not_permitted_by_mandate` | attempted to confirm, place, or pay via agent | create a draft and return `confirm_url` to the human | ## 5. MCP tools (v1.0.0) ### publish_shared_page Publier en 1 appel une page web dédiée et partageable au nom d'un acteur sur https://ecorce.app/p/{actor}/{slug} (et sa vitrine https://ecorce.app/p/{actor}) pour présenter un fait partagé, une offre, un lot groupé, une tournée ou un outil interactif sur la surface d'Écorce. Crée et déploie automatiquement le couple Fonction + Manifeste (manifest@v1 en 5 blocs) dans ecorce-partner-tools, initialise son manifest_state dans le registre d'état d'Écorce, et retourne page_url et actor_url. ```json {"type":"object","properties":{"manifest_id":{"type":"string","description":"optional full manifest ID, e.g. 'ferme-exemple:panier-racines@v1'"},"actor":{"type":"object","description":"{handle, name, kind/role, sector, location}"},"actor_handle":{"type":"string"},"actor_name":{"type":"string"},"actor_kind":{"type":"string"},"headline":{"type":"string","description":"grand titre de la page partagée"},"story":{"type":"string","description":"récit ou explication du fait partagé / de l'offre"},"facts":{"type":"array","description":"liste de faits vérifiés ou chiffres clés ({label, value, detail} ou strings)","items":{"type":["object","string"]}},"shared_facts":{"type":"array","items":{"type":["object","string"]}},"sections":{"type":"array","description":"sections additionnelles ({title, body, items})","items":{"type":"object"}},"cta_label":{"type":"string","description":"libellé du bouton d'action sur la page"},"custom_html_card":{"type":"string","description":"bloc HTML optionnel sanitisé (sans script)"},"intent":{"type":"object","description":"{protocol, title, summary, description, tags}"},"protocol":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"trust_gate":{"type":"object","description":"{visibility, allowed_actors, call_policy, mode, human_approval_on_commit, scopes}"},"initial_state":{"type":"object","description":"état vivant initial écrit dans manifest_state et affiché en direct sur la page"},"stateful_rule_spec":{"type":"object","description":"règle déclarative de mise à jour d'état: {state_key, quantity_input_field, committed_field, remaining_field, target_or_capacity_field, unit_price_cents_field, collection_field, record_type}"},"projection":{"type":"object"},"handler_js":{"type":"string"},"reset_state":{"type":"boolean"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### publish_manifest Create, compile, and deploy a brand-new 5-block manifest@v1 + isolated function on the Écorce programmatic surface ('ecorce-partner-tools') in a single call, and seed its initial_state in the Écorce state registry (manifest_state). Supports declarative stateful_rule_spec (state_key, quantity_input_field, committed_field, remaining_field, target_or_capacity_field, unit_price_cents_field, collection_field, record_type) or custom handler_js. ```json {"type":"object","properties":{"manifest_id":{"type":"string","description":"optional full manifest ID, e.g. 'producteur-demo:lot-saison@v1'"},"actor":{"type":"object","description":"{handle, name, kind/role, sector, location}"},"actor_handle":{"type":"string"},"actor_name":{"type":"string"},"actor_kind":{"type":"string"},"intent":{"type":"object","description":"{protocol, title, summary, description, tags}"},"protocol":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"trust_gate":{"type":"object","description":"{visibility, allowed_actors, call_policy, mode, human_approval_on_commit, scopes}"},"initial_state":{"type":"object","description":"initial key-value object written immediately to manifest_state in the Écorce state registry"},"stateful_rule_spec":{"type":"object","description":"declarative state mutation rules: {state_key, quantity_input_field, committed_field, remaining_field, target_or_capacity_field, unit_price_cents_field, collection_field, record_type, read_actions}"},"function":{"type":"object"},"projection":{"type":"object"},"handler_js":{"type":"string"},"reset_state":{"type":"boolean"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### list_manifests Discover 5-block universal manifests (manifest@v1: actor, intent, trust_gate, function, projection) registered on the Écorce programmatic surface ('ecorce-partner-tools'), including the 3 official Écorce pillars, A2A partner manifests (saja:tournee-pool-g9a@v1, lamoisson:besoins-hebdo@v1), and live partner tools. Filterable by actor, protocol, tag, or q. ```json {"type":"object","properties":{"actor":{"type":"string","description":"optional actor filter, e.g. 'ecorce', 'saja', 'lamoisson', 'monde-naturel'"},"protocol":{"type":"string","description":"optional protocol filter, e.g. 'ecorce.route_pool@v1', 'ecorce.restock_needs@v1'"},"tag":{"type":"string","description":"optional tag filter, e.g. 'a2a', 'vrac', 'g9a', 'palettes'"},"q":{"type":"string","description":"optional free-text search query"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### invoke_manifest Invoke a 5-block manifest@v1 function on the Écorce programmatic surface ('ecorce-partner-tools'). Enforces trust_gate.allowed_actors, injects the owner's manifest_state into the fonction, creates a transactional manifest_record when record_to_commit/state_patch is returned, and returns status='pending_human_approval', commit_token, and confirm_url when human_approval_on_commit=true. ```json {"type":"object","properties":{"manifest_id":{"type":"string","description":"manifest ID, e.g. 'saja:tournee-pool-g9a@v1', 'lamoisson:besoins-hebdo@v1', 'ecorce:spn-catalogue@v1'"},"caller_actor":{"type":"string","description":"handle of the calling actor/agent, e.g. 'saja', 'lamoisson', 'ecorce'"},"input":{"type":"object","description":"input payload matching the manifest's function.input_schema"},"actor_context":{"type":"object","description":"optional caller actor context"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["manifest_id"],"additionalProperties":false} ``` ### compose_manifests Execute a sequential pipeline of 2 or 3+ manifest@v1 fonctions on the Écorce programmatic surface (e.g. ['ecorce:spn-catalogue@v1', 'ecorce:unit-economics-advisor@v1', 'ecorce:order-draft-engine@v1']), passing step N output into step N+1, and return the full execution steps_trace, latencies, final_output, and commit_token/confirm_url when human_approval_on_commit=true. ```json {"type":"object","properties":{"pipeline":{"type":"array","minItems":1,"maxItems":6,"items":{"type":["string","object"]},"description":"ordered list of manifest IDs"},"caller_actor":{"type":"string","description":"optional calling actor handle"},"initial_input":{"type":"object","description":"initial input passed to step 1 and carried across steps"},"actor_context":{"type":"object","description":"optional caller actor context"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["pipeline"],"additionalProperties":false} ``` ### read_manifest_state Read the owner's private/shared manifest_state key-value store for a manifest (injected into its compiled function on the Écorce surface on every invoke). Auto-seeds initial state if empty. ```json {"type":"object","properties":{"manifest_id":{"type":"string","description":"manifest ID, e.g. 'saja:tournee-pool-g9a@v1' or 'lamoisson:besoins-hebdo@v1'"},"actor_context":{"type":"object"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["manifest_id"],"additionalProperties":false} ``` ### update_state Alias of write_manifest_state: update or reset manifest_state (requires partner invite_code to persist). ```json {"type":"object","properties":{"manifest_id":{"type":"string"},"key":{"type":"string"},"value":{},"patch":{"type":"object"},"reset":{"type":"boolean"},"updated_by":{"type":"string"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["manifest_id"],"additionalProperties":false} ``` ### submit_record Alias of confirm_manifest_record: confirm and commit a manifest_record (requires partner invite_code to persist). ```json {"type":"object","properties":{"record_id":{"type":"string"},"commit_token":{"type":"string"},"approved_by":{"type":"string"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["record_id"],"additionalProperties":false} ``` ### write_manifest_state Update or reset the owner's manifest_state for a manifest (single {key, value}, multi-key {patch}, or {reset: true}). ```json {"type":"object","properties":{"manifest_id":{"type":"string","description":"manifest ID"},"key":{"type":"string","description":"optional single state key to update"},"value":{"description":"JSON value for 'key'"},"patch":{"type":"object","description":"optional object of key/value pairs to upsert"},"reset":{"type":"boolean","description":"true to reset manifest_state to its initial seed"},"updated_by":{"type":"string","description":"actor handle performing the update"},"actor_context":{"type":"object"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["manifest_id"],"additionalProperties":false} ``` ### list_manifest_records Read the A2A cross-actor transactional mailbox (manifest_records). Filter by actor (returns records where owner_actor=actor OR caller_actor=actor), owner_actor, caller_actor, manifest_id, or status. ```json {"type":"object","properties":{"actor":{"type":"string","description":"actor handle to view both incoming (owner_actor) and outgoing (caller_actor) records, e.g. 'saja' or 'lamoisson'"},"owner_actor":{"type":"string"},"caller_actor":{"type":"string"},"manifest_id":{"type":"string"},"status":{"type":"string","enum":["pending_human_approval","committed"]},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### confirm_manifest_record Confirm a pending A2A manifest_record with its commit_token, transitioning status to 'committed' and automatically applying its state_patch to the manifest's manifest_state. ```json {"type":"object","properties":{"record_id":{"type":"string","description":"record_id, e.g. 'rec_...'"},"commit_token":{"type":"string","description":"commit_token returned when the record was created"},"approved_by":{"type":"string","description":"optional human/owner actor confirming the record"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["record_id"],"additionalProperties":false} ``` ### list_partners List the distributors and producers on the Écorce network surface (demo: targeted pilot partners and fictional producer, example data). Read-only. ```json {"type":"object","properties":{"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### search_catalogue Search products and offers (FR or EN). Runs via compiled function 'fn-ecorce-spn-catalogue' (ecorce:spn-catalogue@v1). Returns exact 'spn' ids (e.g. SPN-EX-SAJA-001), unit/format (4 L, 10 L, 20 L…), invented demo prices, and deterministic advisor_notes / opportunities. Read-only. ```json {"type":"object","properties":{"query":{"type":"string","description":"free text, FR or EN"},"partner_id":{"type":"string","description":"optional filter: a partner id from list_partners"},"postal_code":{"type":"string","description":"optional postal code or prefix, e.g. G9A"},"limit":{"type":"integer","minimum":1,"maximum":50},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### get_offer Get one offer by its spn (e.g. SPN-EX-SAJA-001) or offer_id. Read-only. Invented example data. ```json {"type":"object","properties":{"spn":{"type":"string"},"offer_id":{"type":"string"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### create_order_draft Create order DRAFT(s) via compiled function 'fn-ecorce-order-draft' (ecorce:order-draft-engine@v1, result: DRAFT_ONLY; a human confirms at confirm_url). lines = JSON array of {spn, qty} using exact spn ids from search_catalogue. ```json {"type":"object","properties":{"lines":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"object","properties":{"spn":{"type":"string","description":"exact SPN id, e.g. SPN-EX-SAJA-001"},"qty":{"type":"integer","minimum":1,"maximum":9999},"partner_id":{"type":"string","description":"distributor id when the same SPN is offered by several distributors"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["spn","qty"],"additionalProperties":false}},"partner_id":{"type":"string","description":"optional default distributor"},"postal_code":{"type":"string","description":"optional postal prefix, e.g. G9A"},"note":{"type":"string","maxLength":500},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["lines"],"additionalProperties":false} ``` ### get_draft Read one order draft: status (draft, confirmed_demo, placed_demo_sink), lines, total, advisor_notes and audit events. ```json {"type":"object","properties":{"draft_id":{"type":"string","description":"format draft-xxxxxxxx"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["draft_id"],"additionalProperties":false} ``` ### list_tool_templates List the 4 Écorce programmatic surface function templates (custom_function, minimum_order, availability, promo), their JSON config schemas, tool input/output schemas, and isolation limits (10 ms CPU, 0 bindings, outbound network blocked). Read-only. ```json {"type":"object","properties":{"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### publish_worker_function Build and deploy a live isolated function onto the Écorce programmatic surface ('ecorce-partner-tools'). Accepts a partner_slug (e.g. 'muse-demo') and either {template, config, name} OR a plain-language {description} (which the Écorce model converts into a validated config). Returns the deployed script_name, the full generated ES module fonction source code, and the live mcp_tool_name. ```json {"type":"object","properties":{"partner_slug":{"type":"string","description":"sandbox partner slug, e.g. 'muse-demo' or 'mon-distributeur'"},"partner_name":{"type":"string","description":"optional display name for the sandbox partner"},"template":{"type":"string","enum":["custom_function","minimum_order","availability","promo"],"description":"Écorce surface function template (default: custom_function)"},"name":{"type":"string","description":"human-readable function title"},"description":{"type":"string","description":"optional plain-language description of the function rules (if config is omitted, the Écorce model builds the config from this description)"},"config":{"type":"object","description":"template configuration object (see list_tool_templates)"},"publish":{"type":"boolean","description":"true (default) to upload and activate live on the Écorce surface; false to preview generated fonction code only"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### call_worker_function Invoke a live partner fonction function running on the Écorce programmatic surface ('ecorce-partner-tools') and return its JSON output. ```json {"type":"object","properties":{"mcp_tool_name":{"type":"string","description":"full MCP tool name returned by publish_worker_function, e.g. 'muse_demo__run_custom_function'"},"partner_id":{"type":"string","description":"alternative: partner_slug, e.g. 'muse-demo'"},"tool":{"type":"string","description":"alternative: tool name, e.g. 'run_custom_function', 'check_minimum_order', 'check_availability', 'get_current_promo'"},"arguments":{"type":"object","description":"JSON arguments passed to the fonction function"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### unpublish_worker_function Unpublish and delete a sandbox partner fonction function from the Écorce programmatic surface. ```json {"type":"object","properties":{"partner_slug":{"type":"string","description":"sandbox partner slug, e.g. 'muse-demo'"},"template":{"type":"string","enum":["custom_function","minimum_order","availability","promo"]},"tool_id":{"type":"string","description":"optional full tool_id, e.g. 'muse-demo.custom_function'"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["partner_slug"],"additionalProperties":false} ``` ### list_shared_tools List partner tools shared across the Écorce network with creator attribution and clone counts. Read-only. ```json {"type":"object","properties":{"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### clone_tool Clone a shared network tool for a partner with optional config_overrides and custom_name, preserving creator credit in the audit log. ```json {"type":"object","properties":{"shared_tool_id":{"type":"string","description":"id from list_shared_tools, e.g. shared-min-order-g9a"},"target_partner_id":{"type":"string","description":"partner id cloning the tool"},"custom_name":{"type":"string"},"config_overrides":{"type":"object"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["shared_tool_id"],"additionalProperties":false} ``` ### list_network_opportunities List active 3-actor coordinated network pools (route/free-shipping consolidation in G9A/H2X, co-funded Écorce fleet-as-media campaign, and direct B2C shopper activation). Read-only. ```json {"type":"object","properties":{"postal_prefix":{"type":"string","description":"optional 3-char postal prefix, e.g. G9A or H2X"},"kind":{"type":"string","description":"optional filter: logistics_consolidation | fleet_media_co_op | b2c_activation_each"},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":[],"additionalProperties":false} ``` ### join_network_opportunity Create a DRAFT participation in a 3-actor network opportunity pool (result: DRAFT_ONLY; a human confirms at confirm_url). ```json {"type":"object","properties":{"pool_id":{"type":"string","description":"id from list_network_opportunities, e.g. pool-mauricie-g9a, pool-flotte-ecorce, pool-activation-each"},"role":{"type":"string","enum":["retailer","distributor","producer"]},"actor_name":{"type":"string"},"commitment_cents":{"type":"integer","minimum":1000,"maximum":5000000,"description":"amount in cents CAD, e.g. 12000 for $120.00"},"postal_prefix":{"type":"string"},"spns":{"type":"array","items":{"type":"string"}},"note":{"type":"string","maxLength":300},"invite_code":{"type":"string","description":"Optional partner invite code (e.g. ECORCE-...) required only to persist state/records or publish live pages; omit for $0 sandbox simulation"},"dry_run":{"type":"boolean","description":"Optional: true to force in-memory simulation without writing to the Écorce state registry"}},"required":["pool_id"],"additionalProperties":false} ``` ### Live partner tools (Écorce programmatic surface) - monde-naturel.connector by monde-naturel (stub (example data)): `monde_naturel__check_availability`, `monde_naturel__get_delivery_windows`. Permissions: read:own_catalogue. - distribution-exemple-outils.minimum_order by distribution-exemple-outils (self-serve (example data)): `distribution_exemple_outils__check_minimum_order`. Permissions: read:own_config. - muse-demo.custom_function by muse-demo (self-serve (example data)): `muse_demo__run_custom_function`. Permissions: read:own_config.