- Proxy Service: Forwards search queries to configurable source adapters and returns unified OER results via a public API. Supports searching an AMB Nostr relay, Openverse, ARASAAC, RPI-Virtuell, and more through an extendable adapter system - add your own adapters to integrate any external API.
- Source Adapters: Pluggable adapters for OER sources (e.g., AMB relay, ARASAAC, Openverse) that integrate seamlessly with search results. The adapter plugin system makes it easy to add new sources.
- JavaScript Packages: Type-safe API client and web components for integrating OER resources into applications
- Aggregation of Nostr Events though Nostr AMB Relay: The Aggregation of events is done in a separate AMB Relay based on TypeSense that is integrated via a before mentioned adapter.
Motivation: Instead of configuring for each new educational app new OER sources, this project aims to offer a meta search with reusable web components. The idea is to make it as easy as possible to install a OER search component in any Javascript application with multiple sources preconfigured. The main idea started to listen for OER Nostr events. But as this network must be estabilished first, additional sources were introduced.
The screenshot shows an example of using Openverse as a OER source for the keyword "car".┌───────────────────────────────────────────────────────────────────┐
│ Your Application │
│ ┌────────────────────────┐ ┌────────────────────────────────┐ │
│ │ oer-finder-plugin │ │ oer-finder-api-client │ │
│ │ (Web Components) │ │ (TypeScript Client) │ │
│ └───────────┬────────────┘ └────────────────┬───────────────┘ │
└──────────────┼──────────────────────────────────┼─────────────────┘
│ │
└────────────────┬─────────────────┘
│ HTTP API
▼
┌───────────────────────────────────────────────────┐
│ Proxy Server (formerly aggregator) │
│ (NestJS) │
└───────────────┬───────────────────────────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────────┐
│ AMB Relay │ │ Source Adapters │ │ imgproxy │
│ (Nostr OER) │ │ (External APIs) │ │ (Image Proxy) │
└─────────────────┘ └──────────────────┘ └─────────────────────┘
│
┌───────────────┼───────────────┬───────────────┐
│ │ │ │
▼ ▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌──────────────┐ ┌──────────┐
│ARASAAC │ │ Openverse│ │ RPI-Virtuell │ │Wikimedia │
└────────┘ └──────────┘ └──────────────┘ └──────────┘
# 1. Build and start services
docker compose build
docker compose up -d --force-recreate
# 2. Configure environment
cp .env.example .env
# Edit .env with your settings
# 3. Install dependencies
pnpm install
# 4. Run the application
pnpm start:devNote: This is a pnpm workspace monorepo — the adapter packages must be built before the NestJS server can start. The
start:devscript handles this automatically viabuild:packages. If you need to build packages manually (e.g. before runningpnpm start:prod), runpnpm run build:packagesorpnpm run build(which builds both packages and the server).
The API will be available at http://localhost:3000/api/v1/oer with interactive documentation at http://localhost:3000/api-docs.
Full Server Setup Guide - Detailed installation, configuration, and development instructions
Simply use the already built docker image instead of building it yourself: docker pull ghcr.io/edufeed-org/oer-finder-plugin
Docker compose
services:
app:
image: ghcr.io/edufeed-org/oer-finder-plugin
...Please note: This requires a .npmrc file in your root folder with the following content:
@edufeed-org:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}Then, configure an env variable GITHUB_TOKEN.
pnpm add @edufeed-org/oer-finder-api-clientimport { createOerClient } from '@edufeed-org/oer-finder-api-client';
const client = createOerClient('http://localhost:3000');
const { data, error } = await client.GET('/api/v1/oer', {
params: { query: { source: 'nostr-amb-relay', searchTerm: 'plants' } }
});pnpm add @edufeed-org/oer-finder-plugin<oer-search api-url="http://localhost:3000">
<oer-list></oer-list>
<oer-load-more></oer-load-more>
</oer-search>Customize colors with CSS:
<style>
oer-search, oer-list, oer-card, oer-load-more {
--primary-color: #8b5cf6;
--primary-hover-color: #7c3aed;
--secondary-color: #ec4899;
}
</style>
<oer-search api-url="http://localhost:3000">
<oer-list></oer-list>
<oer-load-more></oer-load-more>
</oer-search>Full Client Package Guide - Installation, usage examples, and API reference
- Server Setup - Installation, configuration, development, and testing
- Client Packages - API client and web components usage
- Client Packages Examples for Angular - Web components usage in Angular
- Client Packages Examples for Svelte - Web components usage in Svelte
- Client Packages Examples for React - React component wrappers usage
- Architecture - System architecture and adapter system
- Design Principles - Design philosophy and requirements
- Nostr Events - AMB event types and format
- Creating a New Adapter - Step-by-step guide for building a new source adapter
- 🔍 Meta Search - Query multiple OER sources through a single API
- 🔗 Source Adapters - Extend search results with external OER sources (AMB relay, ARASAAC, Openverse, RPI-Virtuell, and more)
- 📦 Type-Safe Client - Auto-generated TypeScript client from OpenAPI spec
- 🎨 Web Components - Ready-to-use UI components built with Lit
- 🛡️ Privacy-Aware Asset Proxying (server-proxy mode) - Implicitly loaded assets (thumbnails in search results) are proxied via imgproxy or HMAC-signed URL redirects, preventing third-party tracking and CORS issues. Explicit actions like viewing original resources remain in the user's or integrator's domain. In direct-client mode, the browser contacts external sources directly and proxying does not apply.
- 🔒 Rate Limiting - Per-IP rate limiting for API protection
- 🔌 Extensible - Add custom adapters to integrate any external OER API
Security Note — Nostr AMB Relay adapter: If you plan to use the
nostr-amb-relayadapter, it is recommended to use it in direct-client mode (browser-side) only. If you need to use it through the proxy server, configure imgproxy and setASSET_PROXY_ALLOWED_DOMAINSto restrict which domains the proxy may contact. AMB relay events can contain arbitrary URLs; when the proxy fetches these server-side, a malicious event could point to internal network resources (SSRF). See the Server Setup Guide for details.
# Search OER from AMB relay
curl "http://localhost:3000/api/v1/oer?source=nostr-amb-relay&searchTerm=pythagoras"
# Search from Openverse
curl "http://localhost:3000/api/v1/oer?source=openverse&searchTerm=plants&type=image"
# Search from ARASAAC
curl "http://localhost:3000/api/v1/oer?source=arasaac&searchTerm=car"To populate the local AMB relay with sample OER events for development and testing, use the nak (Nostr Army Knife) service:
docker compose run --rm --entrypoint sh nak /data/publish-demo-events.shThis publishes sample Nostr events (kind 30142 learning resources) to the local AMB relay. The events will then be available for the proxy to search via the nostr-amb-relay adapter.
You can also use nak directly to publish a custom kind 30142 learning resource event (the AMB relay only accepts kind 30142 events):
docker compose run --rm nak event -k 30142 \
-c "A custom learning resource description" \
-t "d=my-unique-resource-id" \
-t "type=LearningResource" \
-t "name=My Custom Resource" \
-t "license:id=https://creativecommons.org/licenses/by-sa/4.0/" \
-t "inLanguage=en" \
ws://amb-relay:3334To query events from the relay directly:
docker compose run --rm nak req --search "pythagoras" ws://amb-relay:3334# Run tests
pnpm test
# Run lints and formatting
pnpm lint
pnpm format
# Type check and build
pnpm buildSee Server Setup Guide for detailed development instructions.
Before creating a new version on GitHub, don't forget to bump the versions of the client packages. If not changed, the client packages will not get new release candidates. Then, simply create a new release on GitHub.
- MIT
- BSD-3: The oer-finder-plugin makes use of lit, which is licensed under BSD-3
- edufeed / kanban-editor: edufeed-org/kanban-editor#38
- ARASAAC - Aragonese Portal of Augmentative and Alternative Communication, providing pictograms and resources under Creative Commons license
This project is being funded by the BMBSFJ.
Förderkennzeichen: 01PZ25003


