Bring your own AI
Download your lens as a skill, hand it to a model you already pay for, and paste what comes back. This lane is free and it is the one most accounts have.
Why it works this way
A model writing nodes for a lens has to know three things it cannot guess: which categories exist, which connection types exist, and — most importantly — the exact slugs of the nodes already there. Without that last one it invents plausible slugs, every link it writes points at nothing, and the import reports no error at all, because an unresolvable link is a legal ghost rather than a mistake.
So the problem isn't model quality or prompt wording. It is context. The fix is to hand the model your lens: its vocabulary, its existing node names, and the format your paste box accepts, packaged as an Agent Skill.
That is also why this lane is free. The app never calls a model on your behalf — you do, in a subscription you already have. Nothing is metered because nothing is spent.
Before you start
- A lens. Ideally with a few nodes in it, so the model has something to link to — but an empty one works too, and so does having none at all (see below).
- An AI client that reads Agent Skills — Claude and ChatGPT both do. Anything that accepts an uploaded file will work; skills just make it automatic.
Step 1 — Download the lens skill
Open any micro lens and find the Content section on the control panel at the right of the graph. It is the one place both directions live: everything that gets content out of a lens, and everything that puts it back.
Choose Lens skill. You get a file named <lens>-lens.skill holding the whole lens — its vocabulary and every node in it — packaged as an Agent Skill, the open format Claude, ChatGPT and anything else that reads skills will accept.
That is what makes this more than a copy-paste: the model is not being told about your lens, it is being handed it. Which is why it can add to what you have at whatever level of detail you want, rather than producing plausible material that sits beside your work instead of joining it.
The file contains everything the model needs and nothing it doesn't:
existing.md is the important one and the reason this works at all. It is the list the model checks a name against before inventing one, and the list it copies a slug out of before writing a link.
_lens.md on its own, for people comparing against a vault — it has no nodes in it, so a model given only that file will invent every slug it links to.If your lens has private entries
You'll be asked whether to include them, every time, and the answer defaults to no. The question is about the names only — no definitions or bodies ever leave — but a downloaded file has left this app's access rules behind and can't be recalled. Saying no costs you a possible duplicate you can see and fix; saying yes can't be undone.
Either way the file is honest about it: when entries are withheld, existing.md says how many, so the model knows its list is partial and can say so instead of confidently duplicating something it cannot see.
Step 2 — Give it to your model
Install the .skillfile in your client the way it installs skills. It is self-contained: it carries both the authoring guide and your lens's contents, so there is nothing else to install alongside it.
Then ask for what you want, in plain language:
You do not need to describe the format, name the groups, or explain what a slug is. All of that is in the file. What you supply is the subject and the scope.
If you don't have a lens yet
Ask for the structure first. The guide inside every bundle has a section for exactly this, so a model that has read it will reply with a sketch rather than five hundred nodes: the lenses it proposes, the groups and relations for each, the slug prefix it intends to use, and how the work divides into batches.
Argue with the sketch — it costs one reply and it is free to change. A group is applied to every node at once, so a taxonomy that is wrong is wrong five hundred times, and a slug prefix chosen badly in the first batch cannot be linked to from the ninth.
When you like it, ask for the lenses on their own. That paste creates the lenses; the node batches come after, and from there you are in the ordinary flow below.
Step 3 — Paste it back
Back in the same Content panel you downloaded from, choose Import. Paste the model's reply and hit Preview. Nothing is written until you confirm.
That symmetry is the point of the panel: what left as a skill comes back as nodes, through a door two rows from the one it went out of. There is no other tool to install and no file to convert.
You can paste the whole message, fenced code block and all — the wrapper is recognised and removed. The preview then checks every block against this lens and marks it:
- ready — will import
- exists · skip — a node with that slug is already here. Expected, not an error.
- error — malformed, and named. Fix it in the box and preview again.
- warn— it'll import, but something was undeclared or dropped.
The warnings you will actually see
None of these stop an import. Each one means the node lands slightly poorer than the model intended, and each has a different answer.
| The warning says | What to do |
|---|---|
| Link target “…” doesn't resolve | The most important one. The edge will be dropped silently after import. If you meant an existing node, the model reconstructed its slug instead of copying it — see links didn't connect. If it is a node a later batch will create, it is fine and deliberate. |
| Group “…” isn't declared in this lens | The node imports ungrouped and takes no colour. Either add the group in lens settings, or fix the value and re-paste. |
| No group set | Same outcome, no opinion offered. Ungrouped is a legitimate place to be. |
| Relation “…” isn't declared | The link still draws; it just falls back to a plain, untyped edge. |
…isn't a field this importer stores | An invented frontmatter key. The value is dropped — put the fact in the body instead. (A vault sync would have kept it.) |
| Looks like a near-duplicate of “…” earlier in this paste | The model proposed two nodes for one subject. Usually you want one of them, with the other name as an alias. |
event_dateisn't YYYY-MM-DD | The date is ignored. Dates belong in the prose, where a reader can check them. |
lens: is the one thing here that is an error rather than a warning, and deliberately so. Every other bad value costs the node an attribute; a bad lens costs it its whole location — it would land correctly formed in whichever lens you happened to have open, with nothing on screen to say so.Step 4 — Answer where it came from
Before importing you'll be asked whether a model wrote this or whether you did. It's a question about a fact you already know, not a setting to reason about, and it decides one thing: whether these land as drafts.
Drafts are grey on the canvas and cannot become flashcards until you've opened each one. That is the whole point — a claim you never read shouldn't be able to drill itself into your memory. Opening a node clears it.
Confirm, and the app tells you what happened in plain counts — how many nodes were created, how many were already there and left alone, and how many were held back. If they landed as drafts it says so, and says to read each one to settle it.
Big jobs: work in batches
A few hundred nodes will not fit in one reply, and a truncated final node is worse than a smaller complete set. Ask for a batch at a time, each one naming the lens it targets, and paste each reply as it arrives.
There is one rule that makes this work, and it is worth enforcing yourself rather than hoping:
na-brant for the node it linked to as na-joseph-brant six replies ago. Nothing will tell either of you: a broken promise and a deliberate forward reference look exactly alike.Forward references themselves are fine, and often better than leaving a node isolated. A link to a node a later batch will write is a placeholder that fills itself in — as long as the later batch uses the identical slug.
One paste, several lenses
A node can carry lens: some-lens to say which lens it belongs in, which lets one document fill several at once — the shape you get when a model builds a macro lens and its children together. Without that key a node goes into whichever lens the importer is pointed at, which is what you want for an ordinary single-lens paste and is why it is optional.
Next steps
- The paste format — exactly which frontmatter keys are read, and what gets dropped.
- My links didn't connect anything — the one failure that happens silently.
- Some of my nodes are grey — what a draft is, and how to settle one.
- Generate and weave with hosted AI — the metered lane, if you'd rather the app made the call.