Features/MCP Workflows/Notion/Notion component library import

Notion component library import

The work is not copying rows. It is turning "2.4kg", "2400g" and "~2.4kg (TBC)" into engineering values, and being honest about the third one.

NotionWrites · gated

The problem this solves

Component libraries live in Notion as free text, because that is what Notion is good at. Importing them naively either fails on anything that is not a clean number, or silently takes 2.4 from a value the team explicitly marked provisional. A mass budget built from unmarked estimates is a budget nobody can defend at a review.

How it works

Text properties turned into typed values with units, and every value that would not convert reported. Parses masses, powers and dimensions out of free text, normalises the units, and never silently takes a number from a value the team marked provisional. Re-runs match on the Notion page ID, so nothing duplicates.

01
Report the schema back first
Every property, its type, how consistently it is populated, and what the import proposes to do with it. Notion databases are unschematised in practice, so the mapping is your decision, not a silent inference.
02
Parse the values, keep the qualifications
Numbers and units extracted from text and normalised to one unit per property. Anything marked estimated, provisional or vendor-claimed carries that qualification into the model as an attribute rather than losing it.
03
Refuse to guess
Ranges, TBDs, see-datasheet and empty values are reported with their raw text as findings. It never averages a range and never takes the number out of a value the team flagged.
04
Match on the page ID, not the name
The Notion page ID is stored on each part so a re-run updates rather than duplicates. Names get edited in Notion, and matching on them is what makes teams abandon an import.

The prompt

You are importing components from a Notion database into the Dalus
model [model name] as parts with typed variables. The work here is
not copying rows; it is turning text properties into engineering
values with units, and being honest about the ones that will not
convert. This workflow writes to the model, and only after an
approved dry run.

CONFIRM FIRST, in one message: which Dalus model; which Notion
database; whether all rows or a filtered subset; where the parts
should sit in the model hierarchy; whether this is a first import or
a re-run updating components already imported; and which Notion
properties should become variables versus notes versus attributes.
Ask anything else in the same message. Then begin.

READ THE NOTION DATABASE COMPLETELY before writing anything: every
row, every property, and the property types. Report the schema back:
each property, its type, how consistently it is populated, and what
you propose to do with it. Notion databases are unschematised in
practice, and the mapping is a decision the user makes, not one you
infer silently.

PARSE VALUES AND UNITS, the actual work:
- Extract the numeric value and the unit from text properties:
  "2.4kg", "2.4 kg", "2400g", "~2.4kg" all mean the same mass and
  must land as the same typed variable.
- Normalise units within a property so mass is one unit across all
  parts, and say which unit you chose and why.
- Report every value you could not parse cleanly rather than
  guessing: "2.4kg (TBC, see supplier email)", "2-3kg", "TBD",
  "see datasheet", empty. These are common, and each is a finding.
  Never silently take 2.4 from a value the team marked as
  provisional, and never average a range.
- Where a value is qualified as estimated, provisional or
  vendor-claimed, carry that qualification into the model as an
  attribute rather than dropping it, because a mass budget built
  from unmarked estimates is a budget nobody can defend.

MAP THE REST: supplier, part number, status, lifecycle and similar
properties become attributes or notes as agreed in the schema
mapping. Every part records the Notion page URL in its notes, and
the Notion page ID as an attribute, because the URL is for humans
and the ID is what makes a re-run safe.

MATCHING ON RE-RUN: match on the stored Notion page ID, never on
the component name. Names get edited in Notion and matching on them
creates duplicates, which is the failure mode that makes teams
abandon an import. Report rows that are new, rows whose values
changed with old and new shown, rows unchanged, and parts in the
model whose Notion source row no longer exists. Never delete a part
from the model because a Notion row disappeared; report it and let
the user decide.

DRY RUN, before any write: the schema mapping table; row counts;
the first five and last five parts exactly as they will land, with
their parsed variables and units; every unparseable value with the
raw text; every name collision with existing model parts; and, on a
re-run, the changed-value list. Reconciliation arithmetic: rows in
scope = parts to create + parts to update + rows skipped, with
reasons for every skip. Suggest running into a branch. Wait for
approval.

IMPORT the approved set. Preserve the Notion values verbatim in the
notes alongside the parsed variable, so the original text is
recoverable if the parse was wrong. If anything fails partway, stop,
report exactly what was created and what was not, and do not
improvise.

FINAL REPORT: the arithmetic against actuals, the unparseable list
as findings for the team to fix in Notion, the qualified-value list,
and any duplicates or inconsistencies noticed in the source data.
Offer, do not execute: rolling the imported masses and powers into
the model's budgets, connecting the imported parts into the
architecture (which is a design decision, not an import step), and
re-running after the Notion database is cleaned up.

Replace the [bracketed] placeholders with your model and project names.

What you get

Parts with typed variables in normalised units, hierarchy as you specified
The unparseable list with raw text, as findings to fix in Notion
Original Notion text preserved in notes, so a bad parse is recoverable
On re-runs: new, changed with old and new shown, unchanged, and vanished rows
Dalus + Notion

Reads the database with its property types, writes nothing back, and stores the page URL for humans and the page ID for safe re-runs. A part whose Notion row has disappeared is reported, never deleted from the model on Notion's say-so.

Nothing is written until you approve it. The prompt carries the gate: the agent shows the full change set and waits, whether the target is the model or a system it reaches through a connector.

Common questions

What happens to values like "2-3kg" or "TBD"?
They are reported with their raw text and not imported as numbers. It never averages a range and never takes 2.4 out of "2.4kg (TBC)". Those become a findings list for the team to fix at the source, which is where the fix belongs.
Will a second run duplicate everything?
No. Each part stores its Notion page ID and re-runs match on that, never on the component name. You get new, changed with both values shown, unchanged, and rows that have vanished from Notion, which are reported rather than deleted.
Does it update our mass and power budgets?
Not as part of the import. It offers to roll the imported values into the budgets afterwards, and separately offers to connect the parts into the architecture, because that is a design decision rather than an import step.