Just calling it Open was not enough — so we built it

A year ago I wrote Just calling it Open is not enough, an essay about why public education infrastructure keeps reproducing the lock-in mechanisms of commercial platforms, and why the Nostr protocol could be a way out. The argument in a nutshell: The openness and collaboration we demand and desire could not previously be implemented technically without leading back to centralization.

Just calling it Open was not enough — so we built it

A year ago I wrote Just calling it Open is not enough, an essay about why public education infrastructure keeps reproducing the lock-in mechanisms of commercial platforms, and why the Nostr protocol could be a way out.
The argument in a nutshell: The openness and collaboration we demand and desire could not previously be implemented technically without leading back to centralization.

The problem is not hypothetical. Back in 2009, Haug and Wedekind examined publicly funded e-learning projects — roughly 300 million euros of funding volume — and found that almost half of them could no longer be found once their funding had ended.
Publicly financed content, locked into publicly financed silos, gone when the project money runs out. That is the actual sustainability record of the platform approach.
Thanks to André Dietrich and Sebastian Zug for pointing me at it (check out their liascript project, its awesome).

That first article was a sketch, an idea, a “could work”-conept. This one is a status report.
Over the past year, a small group of us have been building an open data space for education on Nostr — and enough of it now runs in public that I can walk you through it instead of arguing for it.
Everything below is open source, publicly documented, and reachable already for you.

The stack in one picture

  1. Sources — the legacy web as it is: the OERSI dump (~98,000 OER records), education related calendar sites, WordPress blogs, transferkiosk.net — and, just as importantly: humans.
  2. Ingest — small converters that turn each of those into signed Nostr events: the source crawlers, the WordPress sync, the transferkiosk import, and the web form and MCP tools people publish with directly.
  3. Relay — one Go relay (built on khatru), with a Typesense search index, a semantic embedding index, and NIP-86 management sitting behind the standard relay interface. Code: nope-relay
  4. Consumers — the web app for humans, the MCP server for AI assistants, and any plain
    Nostr client anyone cares to point at it.

So we get data from all kinds of sources: Data dumps (but with JSON-LD in AMB format, thanks OERSI 🙌), sitemaps + JSON-LD (e.g. https://e-teaching.org/oer-sitemap.xml), raw HTML, a JSON API.
Besides the JSON-LD ones there is nothing open or standard about the sources.
But everything after that speaks plain Nostr: the crawlers, metadata forms provide the relay ordinary signed nostr events, and every consumer — any web app, the MCP server, any stock client (supporting that content types) — gets data back through ordinary NIP-01 subscriptions and NIP-50 search.
The MCP server has no privileged access; it is a WebSocket client like every other. Inside the relay’s box there is private machinery — a Typesense index, an embedding service, an indexer that fetches PDFs and HTML — but it sits behind the standard relay interface the way a database sits behind a website: no client ever talks to it, and anyone can mirror the events with nak or simple WebSocket requests.

AMB had everything except a transport

The German OER community has a good learning resource metadata profile: the Allgemeines Metadatenprofil für Bildungsressourcen (AMB), an application profile for educational metadata — publicly documented, validatable, maintained by the volunteer-run KIM OER metadata group.
If you want to describe a learning resource in JSON-LD, the what is a solved problem.

What AMB never defined is the how: a transport.
In practice, AMB documents travel by crawling — each aggregator scrapes sitemaps and embedded JSON-LD for itself, into its own index, probably behind its own API.
And how the AMB data is getting there depends on a pull mechanism.
You have to know the single original point where to get it (despite the publishers have the problem to decide where to publish with all the problems regarding updates if you don’t decide for a single place to put your stuff).

So the first thing we specified was that missing piece: NIP-AMB, which maps an AMB document onto a Nostr event of kind 30142. The nested JSON-LD is flattened into tags with : as the delimiter, arrays become repeated tags, and where Nostr already has a convention we use it — d is the resource’s canonical URL, t carries keywords, p links a creator who has a Nostr identity. The spec’s example event, abridged:

{
  "content": "Eine Unterrichtseinheit für Studierende, die sich mit Religionsfreiheit (Art. 4 GG), positiver und negativer Religionsfreiheit sowie religionssensibler Pädagogik in Kindertageseinrichtungen auseinandersetzt. Die Studierenden erarbeiten sich die Bedeutung dieser Rechte für die pädagogische Praxis und reflektieren den Umgang mit religiöser und weltanschaulicher Vielfalt.",
  "created_at": 1785420698,
  "id": "11549fd85c29ff9267718a4a792a763f1e2d198a8c479d8dd190dea1a2d1de17",
  "kind": 30142,
  "pubkey": "f0a28f62394c4fb487f1bc58fdd13c8ceaf96a2c878922cdb3ceab914c5d0744",
  "sig": "26b0f458f73c4140955305fb3ea6b83076a94f611ce25d28ac00bc80c71e790313f7c17921a77035daa88a2d8394f4929f34edff96de9628e77724d5df8e1c2f",
  "tags": [
    [
      "d",
      "https://blogs.rpi-virtuell.de/relicontent/2025/10/17/religionsfreiheit-beginnt-mit-der-haltung-das-kind-im-mittelpunkt/"
    ],
    [
      "type",
      "LearningResource"
    ],
    [
      "name",
      "Religionsfreiheit beginnt mit der Haltung: Das Kind im Mittelpunkt"
    ],
    [
      "description",
      "Eine Unterrichtseinheit für Studierende, die sich mit Religionsfreiheit (Art. 4 GG), positiver und negativer Religionsfreiheit sowie religionssensibler Pädagogik in Kindertageseinrichtungen auseinandersetzt. Die Studierenden erarbeiten sich die Bedeutung dieser Rechte für die pädagogische Praxis und reflektieren den Umgang mit religiöser und weltanschaulicher Vielfalt."
    ],
    [
      "t",
      "Religionsfreiheit"
    ],
    [
      "t",
      "Kinderrechte"
    ],
    [
      "t",
      "Religionssensible Pädagogik"
    ],
    [
      "t",
      "Grundgesetz Art. 4"
    ],
    [
      "t",
      "Weltanschauliche Vielfalt"
    ],
    [
      "t",
      "Kita"
    ],
    [
      "inLanguage",
      "de"
    ],
    [
      "license:id",
      "https://creativecommons.org/licenses/by/4.0/"
    ],
    [
      "isAccessibleForFree",
      "true"
    ],
    [
      "about:id",
      "nostr:39738:d2689e2f41dabfba953da26655a94ce2aa4e029c383ee921c6a4deafab99a612:religion"
    ],
    [
      "about:prefLabel:de",
      "Religion"
    ],
    [
      "educationalLevel:id",
      "https://w3id.org/kim/educationalLevel/level_6"
    ],
    [
      "educationalLevel:prefLabel:de",
      "Bachelor oder äquivalent"
    ],
    [
      "learningResourceType:id",
      "https://edufeed.org/ns/ekw#lrt/unterrichtsplanung/unterrichtseinheit-und-sequenz"
    ],
    [
      "learningResourceType:prefLabel:de",
      "Unterrichtseinheit und -sequenz"
    ],
    [
      "p",
      "f0a28f62394c4fb487f1bc58fdd13c8ceaf96a2c878922cdb3ceab914c5d0744",
      "wss://relay.damus.io",
      "creator"
    ],
    [
      "L",
      "metadata-form"
    ],
    [
      "l",
      "ekw",
      "metadata-form"
    ],
    [
      "ext:ekw:gradeLevel:id",
      "nostr:39738:d2689e2f41dabfba953da26655a94ce2aa4e029c383ee921c6a4deafab99a612:ef"
    ],
    [
      "ext:ekw:gradeLevel:prefLabel:de",
      "EF (11)"
    ],
    [
      "ext:ekw:gradeLevel:type",
      "Concept"
    ],
    [
      "ext:ekw:schoolType:id",
      "nostr:39738:d2689e2f41dabfba953da26655a94ce2aa4e029c383ee921c6a4deafab99a612:berufliche-schule"
    ],
    [
      "ext:ekw:schoolType:prefLabel:de",
      "Berufliche Schule"
    ],
    [
      "ext:ekw:schoolType:type",
      "Concept"
    ],
    [
      "ext:ekw:didacticConcept:id",
      "nostr:39738:d2689e2f41dabfba953da26655a94ce2aa4e029c383ee921c6a4deafab99a612:biblisches-lernen"
    ],
    [
      "ext:ekw:didacticConcept:prefLabel:de",
      "Biblisches Lernen"
    ],
    [
      "ext:ekw:didacticConcept:type",
      "Concept"
    ],
    [
      "ext:ekw:didacticConcept:id",
      "nostr:39738:d2689e2f41dabfba953da26655a94ce2aa4e029c383ee921c6a4deafab99a612:dialogisches-lernen"
    ],
    [
      "ext:ekw:didacticConcept:prefLabel:de",
      "Dialogisches Lernen"
    ],
    [
      "ext:ekw:didacticConcept:type",
      "Concept"
    ],
    [
      "ext:ekw:didacticConcept:id",
      "nostr:39738:d2689e2f41dabfba953da26655a94ce2aa4e029c383ee921c6a4deafab99a612:interreligioeses-lernen"
    ],
    [
      "ext:ekw:didacticConcept:prefLabel:de",
      "interreligiöses Lernen"
    ],
    [
      "ext:ekw:didacticConcept:type",
      "Concept"
    ],
    [
      "ext:ekw:method:id",
      "nostr:39738:d2689e2f41dabfba953da26655a94ce2aa4e029c383ee921c6a4deafab99a612:dialog"
    ],
    [
      "ext:ekw:method:prefLabel:de",
      "Dialog"
    ],
    [
      "ext:ekw:method:type",
      "Concept"
    ],
    [
      "ext:ekw:method:id",
      "nostr:39738:d2689e2f41dabfba953da26655a94ce2aa4e029c383ee921c6a4deafab99a612:textarbeit"
    ],
    [
      "ext:ekw:method:prefLabel:de",
      "Textarbeit"
    ],
    [
      "ext:ekw:method:type",
      "Concept"
    ],
    [
      "L",
      "https://edufeed.org/ns/bildungsbereich#"
    ],
    [
      "l",
      "schule",
      "https://edufeed.org/ns/bildungsbereich#"
    ],
    [
      "client",
      "Edufeed"
    ]
  ]
}

This is AMB with a delivery mechanism that is push-based, signed, replicable, and queryable with the same filter syntax on every supporting relay that stores it
(and it already supports custom metadata profile extensions, but more on that in another post).

Metadata profiles lean on controlled vocabularies, so those moved onto the protocol too.
NIP-VOCAB defines SKOS vocabularies as native addressable events — concept schemes (kind 39737), concepts (39738), collections (39739), each with a draft counterpart — with an i tag bridging back to the canonical URI, if that already exists.
Vocabularies stop being files on somebody’s web server, which is also kind of a gate, because how many people working with vocabulries are also running web servers?
Now they become data anyone can mirror, query, and — because everything is signed — verifiably attribute.

A relay that understands education metadata

The reference relay is a Go service built on the khatru framework, with Typesense as its search backend.
From the outside it is a completely ordinary Nostr relay: NIP-01 filters, NIP-50 search, NIP-45 counts. I call it the nope-relay (Nostr Oopen Protocol for Education)
The interesting parts hide behind the standard interface:

  • Hybrid semantic search. Queries are answered by a weighted combination of keyword matching and multilingual embeddings (multilingual-e5-base).
  • Passage-level re-ranking. An indexer fetches the actual resource behind each event — web page or PDF — extracts the text, chunks and embeds it. Search results are re-ordered by their best matching passage, not just their metadata.
  • Snippet events. A client that wants to know why a result matched can opt in by adding kind 21142 to its request — a kind we coined for this, ephemeral so it never pollutes storage. The relay then attaches a relay-signed event per result carrying the matched passage, its score, page and heading. Clients that don’t ask, don’t see it.

I want to stress the design rule here: all of this is protocol-transparent.
It’s stock NIP-50 REQ and receives on stock Nostr events.
The moment we would require a dedicated query API, we would have built yet another platform.

Today the public edufeed relays hold over 106,000 AMB resource events between them — 97,690 on the OERSI mirror relay and 8,629 on the main relay as I write this — and the main relay accepts educational resources, long-form articles, wiki pages, scientific publications, calendar events and project descriptions — more on that in a moment further down.

Calendars and ComCal: the proof-of-concept that came first

The first content type where the silo approach was practically broken was not learning materials — it was event calendars.
In ComCal, a publicly funded project I worked on together with Katharina Trostorff, we explored how educational institutions publish their event calendars and how we can get an better overview of events in the education sector by converting them to standard NIP-52 calendar events.
During the project we reached out to a varierty of institutions.
Some (mostly those who had in-house tech assistance) started publishing their calendar events also as NIP-52.
For others we built wordpress crawlers.
And some started automation pipelines converting posts into signed calendar events; any Nostr client could read them.

The chain WordPress → Nostr → arbitrary client → back into WordPress (for some) is the decoupling of user, service and data from the first article, demonstrated end to end.
To be honest: The last step was only impelemented as an example, but till today some keep pushing their events to nostr.
And I hope that once our playground will evolve and the idea spreads, more will join.

No institution asked another for API access at any point.
That project’s funding period has since ended, the original client has since changed dramatically.
But the data structure and the endpoints didn’t change.
So everything is still working and growing.

Getting data in

An empty data space convinces nobody, so we wrote crawlers.
The largest pipeline reconciles the OERSI dump — close to 98,000 AMB records from higher education — into kind 30142 events weekly: content-hashing detects real changes so unchanged records cause zero churn, and upstream removals become standard NIP-09 deletions.
Calendar crawlers watch education portals, and a small tool syncs WordPress sites into long-form or calendar events on a schedule.

Lets hope that this will be transitional technology. Crawling chases materials; that critique from the first article applies to our own crawlers too.
Their purpose is to bootstrap the data space until sources publish natively — the way ComCal’s institutions already do, and the way anyone with a key pair can today.

But as of today also some communities start creating content (mostly metadata records for educational resources) directly in nostr.
With the goal to play this out in a variety of services.

Adding a content type is a spec, not a platform

The claim “one shared data space for all educational content types” is cheap; the test is what it costs to add one.
Recent case: transferkiosk.net documents funded didactic projects in higher education — projects, teaching measures, publications. Bringing that world in took one short spec, NIP-DIDACTIC — kind 30143 for projects, 30144 for documented teaching measures, reusing NIP-AMB’s flattening grammar wholesale — plus a scraper and a batch publish: more than a thousand project records are on the relay today. For the projects’ publications we defined nothing at all — scientific publications already have a community spec some other people published (NKBIP-01, kinds 30040/30041), so we simply use it.

The spec also states its trust model out loud: when a catalogue is mirrored, the event’s signing key is the indexer’s, and the tags are claims attested by that key, with references back to the source. Provenance without a central authority — and when a project later claims its own key, its self-published events should take precedence.

That is the general recipe now: flatten the domain model into tags, reuse existing kinds wherever the Nostr ecosystem already has one, write down who attests what. No new platform, no migration, no permission.

Fittingly, the specs themselves live on Nostr: every NIP in our repository is automatically published as a wiki article (kind 30818), readable in any wiki-capable client.

AI assistants without a platform integration

The newest consumer is amb-mcp, an MCP (Model Context Protocol) server — public domain, and reachable in multiple ways: locally over stdio, publicly over HTTP at https://mcp.amb.edufeed.org/mcp (read access is anonymous).

Connect it to Claude or any MCP-capable client and ask “find German materials on peace education for secondary school” — the assistant searches across all content types, resolves authors, can browses the SKOS vocabularies, and cites linkable resources. There is also an extraction tool: point it at a URL or PDF and it returns an AMB-conformant metadata prefill, grounded in the controlled vocabularies with per-field evidence quotes.
It’s not perfect, but stuff already works.

The framing matters more than the feature list. This is not “our platform now has AI”. It is the opposite: because the data space is open and protocol-based, any model by any operator can be given access with generic tooling. The AI is an access path to a shared commons, not another silo.

Scorecard

The challenges from the first article, one year on:

Challenge (2025) Status today
No easy way to publish OER findably Sign a kind 30142 event and send it to the relay (e.g. via our edufeed-app: immediatley available everywhere;
Every aggregator crawls for itself One shared data space on protocol level; our own crawlers are bootstrap, not architecture
No cross-platform search Cross-platform search is a cross-relay search, incl. semantic ranking. No API needed
AI services bound to one platform’s data model Generic MCP access for any model, no special integration

What is honestly unsolved

Openness creates its own problems.
Four limits we name explicitly — they survived peer review in “Data Spaces in Educational Infrastructures“, our chapter in Springer’s open-access volume Digital Education and Innovation (2026):

  • there is no quality assurance or curation built into the protocol — communities have to negotiate criteria and trust models themselves, much as OERSI and WirLernenOnline already do when importing third-party content. While this is written we are working on modeartion features for communities, based on NIP-29 and the concord protocol.
  • GDPR and the right to be forgotten sit uneasily with distributed, signed storage;
  • key management is important, and a lost key is lost;
  • and a permissionless network at scale will attract spam and abuse. We might mitigate stuff with Web Of Trust and modeartion approaches, but we still have to explore.

Our conclusion is not to wait, but to grow adoption through use cases where these limits are tolerable — public metadata about openly licensed materials is about the most uncritical data imaginable.
And let us fix issues along the way.

One structural idea from the funding perspective deserves its own sentence: permanently financed public institutions — libraries, broadcasters, state institutes — could run archive relays, the way the Internet Archive does for the web. Then “the project ended” would stop meaning “the results vanished”.

You can just build things

None of what I described required anyone’s permission.
We defined event kinds, published them, and they worked.
Anybody interested can pick it up and continue.

  • Relay: wss://amb-relay.edufeed.org — try it out, and here you find all the OERSI data: wss://oersi.edufeed.org
  • MCP endpoint: https://mcp.amb.edufeed.org/mcp — add it to Claude, ChatGPT or similar
  • Code & specs: it’s slowly moving to git over nostr and you will find stuff here: https://gitworkshop.dev/laoc.xyz, most complete is right now: git.edufeed.org/edufeed · github.com/edufeed-org — the specs (NIP-AMB, NIP-VOCAB, NIP-DIDACTIC) are in the nips repo, consider them drafts that can still be improved. Everything is openly licensed.

How open does public education infrastructure want to be? A year later, my answer is: as open as we are willing to build it. And we can just build.


Write a comment