> ## Documentation Index
> Fetch the complete documentation index at: https://docs.realtimelca.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Map materials to EPDs

> Use the MCP to link your inventory materials to EPDs, one user-confirmed batch at a time

Once your project inventory is populated, the next step is to **map each
material to an EPD** so RTLCA can compute GWP and other indicators. This
prompt walks an AI agent through a safe, manual mapping flow — declared
unit check, BR18 lifetime lookup, EPD search across Danish / Nordic /
international generics, and an explicit user confirmation before any
write to the project.

This is the **manual mapping** use case — the agent always pauses for
your go-ahead before calling `rtlca_map_materials`. For bulk
auto-suggestions, run automapping separately.

## Prerequisites

* An RTLCA project with materials in its inventory
  ([add materials](/use-cases/add-materials-to-inventory) first if not)
* An AI client connected to the [RTLCA MCP server](/ai-tools/rtlca-mcp)

## Run the prompt

Open a chat in your connected AI client, point the agent at the target
project (by name or ID), and paste the prompt from the box below.

<Prompt description="Map project inventory materials to EPDs (manual, user-confirmed)" icon="link">
  ````text theme={null}
  ---
  name: rtlca-map-material
  description: Map project inventory materials to EPDs in Real-Time LCA (RTLCA). Use this skill whenever the user wants to map, link, assign, or connect a project material to an EPD; when they ask to "find an EPD for X", "map the glulam", "assign an EPD", "connect this material", "search for matching EPDs"; when material mapping coverage needs to go up; when an LCA dashboard shows unmapped materials; or any time the rtlca_map_materials tool would plausibly be involved. Also use proactively if the user is working in an RTLCA project and mentions specific construction materials (concrete, glulam, gypsum, insulation, etc.) without yet having mapped them. Covers the full safe workflow: declared-unit check, lifetime setting via BR18 table, EPD search and sorting, user confirmation before write, post-mapping verification.
  ---

  # Map a project material to an EPD in RTLCA

  **This skill is for manual, user-confirmed mapping only. It is NOT automapping.** Do not call `rtlca_run_automapping` or `rtlca_preview_automapping` from this skill. Every mapping here is searched, shortlisted, presented to the user, and only written after the user explicitly approves the specific EPD choice. If the user asks for automapping or bulk auto-suggestions, that is a different workflow — stop and ask whether they want manual mapping (this skill) or automapping (separate tool calls) before proceeding.

  This skill is the safe, end-to-end procedure for linking a project's inventory material to a library EPD using the Real-Time LCA MCP tools. Mapping writes data to the user's project, so every run must end with the user explicitly approving the mapping before `rtlca_map_materials` is called.

  ## When this skill applies

  Apply this skill in any RTLCA conversation where the goal involves attaching one or more project materials to EPDs. Typical phrasings:

  - "Map the Glulam materials"
  - "Find an EPD for the gypsum boards"
  - "Assign concrete EPDs to the foundations"
  - "Why is my mapping coverage only 3%? Fix it"
  - "Map everything that's still unmapped in the roof"

  The skill scales from one material to a batch of dozens. The same steps apply.

  ## Core principles

  1. **Never call `rtlca_map_materials` before the user confirms.** Mapping changes project state. Always present the planned mapping (project material → EPD, plus lifetime) and wait for an explicit "yes / go ahead / map it" in chat.
  2. **Match declared units.** A project material can only be mapped to an EPD whose declared unit is one of the units the project material has a quantity in. m³ for volumetric items (beams, concrete), m² for sheet/area items (gypsum, insulation panels), kg for mass-based items, pcs for countables.
  3. **Lifetime must be set on the project material.** A material with `lifeTime: 0` cannot be mapped — the API returns "lifespan not set". Set lifetime from the BR18 reference table before attempting `rtlca_map_materials`.
  4. **Prefer Danish / Nordic generic EPDs for BR18 projects unless the user says otherwise.** Country-of-origin and dataset compatibility matter for compliance reporting.
  5. **Mapping is per-leaf material, not per type.** Project material trees have type-level rows with `children`. Only leaf children get mapped, using their individual `materialId`.

  ## The workflow

  ### Step 1 — Identify the project and target materials

  If the project ID is not already known, call `rtlca_list_projects` and confirm with the user which project is meant. Watch for near-name matches (e.g. "Villa Hortensen" vs. "Villa Hjortestigen") and ask before proceeding.

  Then call `rtlca_get_material_mapping` with `projectId`, `filter: "unmapped"` (or `"all"` if the user wants to see context), and **`detail: "summary"`**. Always start with `detail: "summary"` — the default detail level walks every leaf with full properties and can blow the response up into thousands of lines on real projects. Only call again with the deeper detail level when you actually need a specific leaf's full state.

  Walk the result and collect the **leaf** entries to be mapped — only nodes with no `children`, since parent type-rows are aggregates and not directly mappable.

  For each leaf collect: `id` (materialId), `identifier`, parent type identifier, `category`, `totalDeclaredUnits`, `lifeTime`, `materialCount`.

  ### Step 2 — Decide the declared unit

  Look at `totalDeclaredUnits` on the target leaves. Each entry has a `declaredUnit` enum and a `value`.

  **Always call `rtlca_get_declared_units` to resolve the enum integers to unit labels.** The enum can change as the system evolves — never hard-code the mapping. Call this once per session before reading `totalDeclaredUnits` so the labels are correct.

  Pick the unit that best represents how the EPD should normalize the impact. Rough guidance:

  - **m³** — structural timber (glulam, CLT, sawn lumber), insitu concrete, large fills/aggregates
  - **m²** — sheet products (gypsum, OSB, plywood), insulation panels, roofing membranes, glazing
  - **kg** — fixings, sealants, paints, metals when sheet/volume is awkward
  - **m** — linear items (pipes, profiles where length dominates)
  - **pcs** — discrete items (doors, windows, appliances, sanitary ware)

  The project material must have a non-zero `value` in the chosen unit. If it doesn't, either pick another unit it does have, or stop and tell the user the project material needs a quantity entered.

  ### Step 3 — Set lifetime (if `lifeTime: 0`)

  If any target material has `lifeTime: 0`, set it before mapping. Otherwise `rtlca_map_materials` will fail with `"lifespan not set"`.

  Look up the right value in the BR18 reference table by calling `rtlca_get_lifetime_table`. The table is organized by construction ID (e.g. `(25)1 Bærende konstruktioner`) and material family (`i4 Lamineret træ`, `f2 Beton og cementmørtel`, etc.). Common values worth remembering:

  - Glulam (i4 Lamineret træ) in load-bearing structures (25)1 → **120 years**
  - Glulam in roof structures (27)1 Tagværker → **120 years**
  - Konstruktionstræ (i1) in walls (21)3 Ydervægge → **120 years**
  - Mineraluld (m1) in wall/roof insulation → **50–80 years**
  - Beton (f2) in foundations and primary structure → **120 years**
  - Gypsum (f7) in inner walls (22)2 → **80 years**
  - Doors (i1 / h4) in (31)2 Døre, ydervægge → **40 / 60 years**
  - Windows (o0 Glas, h4 Aluminium) in (31)4 Vinduer → **50 / 60 years**

  When unsure, look the value up in the table rather than guessing. Service life affects B4 replacement emissions, so wrong lifetimes silently distort the calculation.

  Call `rtlca_update_material_properties` in a single batch:

  ```
  updates: [
    { materialId: "...", lifetime: 120 },
    { materialId: "...", lifetime: 120 },
    ...
  ]
  ```

  Don't set `lifetimeOffset` unless the user has asked for a phased replacement.

  ### Step 4 — Find candidate EPDs

  Use `rtlca_search_materials` with both `search` (free-text on the material name) and `declaredUnit` (the int enum from Step 2). For Danish projects, search in Danish first (`limtræ`, `beton`, `gips`, `mineraluld`), then English (`glulam`, `concrete`, `gypsum`, `mineral wool`) to catch international EPDs.

  Useful filters:
  - `owner` — when the user names a specific manufacturer
  - `datasource` — to restrict to a specific EPD programme operator
  - `pageSize: 30` — to see more candidates in one call

  Also try `rtlca_search_materials_tenants` for EPDs the organisation has imported into its private library. These are often the user's preferred dataset and should be surfaced when relevant.

  ### Step 5 — Sort and shortlist

  Present candidates ranked by relevance for the user. Sort priority for a BR18 project in Denmark:

  1. **Danish-named EPDs** (`Limtræ til konstruktion af gran`, `Beton C30/37`, etc.) — these match the project's regulatory context and reporting language
  2. **Other Nordic generic EPDs** (Norwegian/Swedish, e.g. `Limtre - standardformer`)
  3. **EN / German / international generic EPDs** (`Glulam in spruce`, `Brettschichtholz`)
  4. **Manufacturer-specific EPDs** — only when the user has named the manufacturer or the project's procurement is fixed

  Within each tier, prefer:
  - EPDs matching the project's calculation type (e.g. BR18 (2025))
  - The newest version (`newestVersion: true` is the default)
  - For end-of-life variants (Forbrænding / incineration vs. Genbrug / recycling), the BR18 default is **incineration (Forbrænding)** for typical waste scenarios — pick that unless the user says otherwise

  Show the user a short table with name, density (kg/m³ when present), and EPD id. Don't dump 30 candidates — show the top 5–8 across tiers.

  ### Step 6 — Confirm with the user before writing

  State plainly what will be mapped, to what, with what lifetime. Example:

  > I'm about to map all 16 Glulam 24h sections to **Limtræ til konstruktion af gran (Forbrænding)** (id `7037ab29-…`), with lifetime = 120 years. Proceed?

  Wait for the user's explicit go-ahead in chat. Do not infer consent from prior messages.

  If the user wants a different EPD from the shortlist, swap it. If they want a different lifetime, update it via `rtlca_update_material_properties` first.

  ### Step 7 — Map

  Call `rtlca_map_materials` once with the full batch:

  ```
  projectId: "<project uuid>"
  mappings: [
    { materialId: "<leaf id 1>", mappedMaterialId: "<epd id>", includeMapping: true },
    { materialId: "<leaf id 2>", mappedMaterialId: "<epd id>", includeMapping: true },
    ...
  ]
  ```

  Set `includeMapping: true` unless the user has asked to exclude the material from the LCA calculation. Leave `isAutoMapping` at its default (false) since this is a manual user-confirmed mapping.

  ### Step 8 — Handle the common error

  If the call returns `"incompatible units or lifespan not set"`:

  1. **Lifespan not set** — go back to Step 3 and set lifetimes, then retry.
  2. **Incompatible units** — the EPD's declared unit isn't in the project material's `totalDeclaredUnits`. Either pick a different EPD (Step 4) with a compatible unit, or add the missing quantity to the project material via `rtlca_update_material_properties`'s `declaredUnitValuePairs`.

  ### Step 9 — Verify

  After the mapping returns successfully (often an empty string `""` on success), confirm with one of:

  - `rtlca_get_dashboard_summary` — check `mapping.material.percentage` went up
  - `rtlca_get_material_mapping` with `filter: "mapped"` and `detail: "summary"` — confirm the new entries show up under the right EPD (use the summary detail level here too; the full detail is rarely needed for verification)

  Report two numbers back to the user:
  - New material mapping coverage (e.g. "3.27% → 13.73%")
  - Change in GWP used vs. budget (e.g. "14.88% → 15.00% of the BR18 budget")

  Mention briefly if transport mapping percentage changed — adding new materials sometimes drops transport coverage because the new entries don't yet have transport mappings; the user may want to re-run transport mapping.

  ## Patterns and edge cases

  ### Batch mapping of repeated material types

  When the project has many size variants of the same material (e.g. 15 Glulam profiles in different cross-sections, or 24 wall types all built on the same gypsum), it's almost always correct to map them all to the same EPD in one batch. The EPD provides per-unit impact; the project supplies the quantity per variant. Don't search for a separate EPD per profile size.

  ### Constructions vs. single materials

  If the project material is itself a multi-layer assembly (e.g. a wall type that should be mapped to a whole wall construction), consider `rtlca_search_constructions` instead of `rtlca_search_materials`, and map via the construction id. This is appropriate when the user mentions "wall types", "assemblies", or "construction build-ups". For single-material leaves (a specific insulation layer, a specific glulam section), use `rtlca_search_materials`.

  ### Tenant-private EPDs

  If the user's organisation has custom EPDs (often the case for repeat customers and frequent product lines), `rtlca_search_materials_tenants` returns them. Surface these before public EPDs when names match closely — the tenant has imported them for a reason.

  ### Removing a wrong mapping

  If the user wants to undo a mapping (not delete the material), use `rtlca_remove_material_mapping` with the material ids. Do not use `rtlca_delete_material` for this — it permanently removes the inventory entry.

  ### Project material has no quantity

  If `totalDeclaredUnits` is empty or all values are 0, the project material has no measurable quantity and mapping it will produce zero impact. Tell the user. They likely need to fix the source model (Speckle/Revit/IFC) or set a quantity manually via `rtlca_update_material_properties`'s `declaredUnitValuePairs`.

  ## Output style

  Keep responses focused on what's being mapped and why. When presenting EPD shortlists, use a compact table. When confirming, use one sentence stating material → EPD → lifetime, and wait. After mapping, give a two-line summary of coverage delta plus any caveat (e.g. transport mapping dropped, next high-impact targets remain).

  Don't quote raw API JSON back to the user unless asked. Don't enumerate dozens of materials when summarizing — group by category and give counts.
  ````
</Prompt>

<Note>
  This prompt is also published as a **skill** so connected clients can
  install it once and reuse it without copy-pasting. See
  [Skills](/agent-ready/skills) for how to get it.
</Note>

## Next

Once your project is mapped, run a
[quality-assurance pass](/use-cases/quality-assurance) before generating
reports.
