diff --git a/plugins/examples/Makefile b/plugins/examples/Makefile
new file mode 100644
index 000000000..f84d469d4
--- /dev/null
+++ b/plugins/examples/Makefile
@@ -0,0 +1,18 @@
+# Build example plugins for Navidrome
+# Auto-discover all plugin folders (folders containing go.mod)
+PLUGINS := $(patsubst %/go.mod,%,$(wildcard */go.mod))
+
+# Prefer tinygo if available, it produces smaller wasm binaries.
+TINYGO := $(shell command -v tinygo 2> /dev/null)
+
+all: $(PLUGINS:%=%.wasm)
+
+clean:
+ rm -f $(PLUGINS:%=%.wasm)
+
+%.wasm: %/main.go %/go.mod
+ifdef TINYGO
+ cd $* && tinygo build -target wasip1 -buildmode=c-shared -o ../$@ .
+else
+ cd $* && GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o ../$@ .
+endif
diff --git a/plugins/examples/README.md b/plugins/examples/README.md
new file mode 100644
index 000000000..168788e11
--- /dev/null
+++ b/plugins/examples/README.md
@@ -0,0 +1,87 @@
+# Navidrome Plugin Examples
+
+This folder contains example plugins for Navidrome that demonstrate how to build metadata agents using the plugin system.
+
+## Building
+
+### Prerequisites
+
+- [TinyGo](https://tinygo.org/getting-started/install/) (recommended) or Go 1.23+
+- [Extism CLI](https://extism.org/docs/install) (optional, for testing)
+
+### Build all plugins
+
+```bash
+make
+```
+
+This will compile all example plugins and place the `.wasm` files in this directory.
+
+### Build a specific plugin
+
+```bash
+make minimal.wasm
+make wikimedia.wasm
+```
+
+### Clean build artifacts
+
+```bash
+make clean
+```
+
+## Available Examples
+
+| Plugin | Description |
+|-------------------------|---------------------------------------------------------------|
+| [minimal](minimal/) | A minimal example showing the basic plugin structure |
+| [wikimedia](wikimedia/) | Fetches artist metadata from Wikidata, DBpedia, and Wikipedia |
+
+## Testing with Extism CLI
+
+You can test any plugin using the Extism CLI:
+
+```bash
+# Test the manifest
+extism call minimal.wasm nd_manifest --wasi
+
+# Test with input
+extism call minimal.wasm nd_get_artist_biography --wasi \
+ --input '{"id":"1","name":"The Beatles"}'
+```
+
+For plugins that make HTTP requests, use `--allow-host` to permit access:
+
+```bash
+extism call wikimedia.wasm nd_get_artist_url --wasi \
+ --input '{"id":"1","name":"The Beatles"}' \
+ --allow-host "query.wikidata.org"
+```
+
+## Installation
+
+Copy any `.wasm` file to your Navidrome plugins folder:
+
+```bash
+cp minimal.wasm /path/to/navidrome/plugins/
+```
+
+Then enable plugins in your `navidrome.toml`:
+
+```toml
+[Plugins]
+Enabled = true
+Folder = "/path/to/navidrome/plugins"
+```
+
+And add the plugin to your agents list:
+
+```toml
+Agents = "lastfm,spotify,wikimedia"
+```
+
+## Creating Your Own Plugin
+
+See the [minimal](minimal/) example for the simplest starting point, or [wikimedia](wikimedia/) for a more complete example with HTTP requests.
+
+For full documentation, see the [Plugin System README](../README.md).
diff --git a/plugins/examples/wikimedia/README.md b/plugins/examples/wikimedia/README.md
new file mode 100644
index 000000000..47db0a8e3
--- /dev/null
+++ b/plugins/examples/wikimedia/README.md
@@ -0,0 +1,137 @@
+# Wikimedia Plugin for Navidrome
+
+A Navidrome plugin that fetches artist metadata from Wikidata, DBpedia, and Wikipedia.
+
+## Features
+
+- **Artist URL**: Fetches Wikipedia URL for an artist using Wikidata (by MBID or name), DBpedia, or falls back to a Wikipedia search URL
+- **Artist Biography**: Fetches the introductory text from the artist's Wikipedia page
+- **Artist Images**: Fetches artist images from Wikidata
+
+## Building
+
+### Prerequisites
+
+- [TinyGo](https://tinygo.org/getting-started/install/) (recommended) or Go 1.23+
+
+### Build using the Makefile (recommended)
+
+```bash
+cd plugins/examples
+make wikimedia.wasm
+```
+
+### Build manually with TinyGo
+
+```bash
+cd plugins/examples/wikimedia
+tinygo build -target wasip1 -buildmode=c-shared -o ../wikimedia.wasm .
+```
+
+### Build manually with Go
+
+```bash
+cd plugins/examples/wikimedia
+GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o ../wikimedia.wasm .
+```
+
+## Installation
+
+Copy `wikimedia.wasm` from the examples folder to your Navidrome plugins folder:
+
+```bash
+cp plugins/examples/wikimedia.wasm /path/to/navidrome/plugins/
+```
+
+Then enable plugins in your `navidrome.toml`:
+
+```toml
+[Plugins]
+Enabled = true
+Folder = "/path/to/navidrome/plugins"
+```
+
+Add the plugin to your agents list:
+
+```toml
+Agents = "lastfm,spotify,wikimedia"
+```
+
+## Testing with Extism CLI
+
+Install the [Extism CLI](https://extism.org/docs/install):
+
+```bash
+brew install extism/tap/extism # macOS
+# or see https://extism.org/docs/install for other platforms
+```
+
+Run these commands from the `plugins/examples` directory.
+
+### Test the manifest
+
+```bash
+extism call wikimedia.wasm nd_manifest --wasi
+```
+
+Expected output:
+```json
+{"name":"Wikimedia","author":"Navidrome","version":"1.0.0","description":"Fetches artist metadata from Wikidata, DBpedia and Wikipedia","website":"https://navidrome.org","permissions":{"http":{"reason":"Fetch metadata from Wikimedia APIs","allowedHosts":["query.wikidata.org","dbpedia.org","en.wikipedia.org"]}}}
+```
+
+### Test artist URL lookup
+
+```bash
+# With MBID (The Beatles)
+extism call wikimedia.wasm nd_get_artist_url --wasi \
+ --input '{"id":"1","name":"The Beatles","mbid":"b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d"}' \
+ --allow-host "query.wikidata.org"
+```
+
+Expected output:
+```json
+{"url":"https://en.wikipedia.org/wiki/The_Beatles"}
+```
+
+### Test artist biography
+
+```bash
+extism call wikimedia.wasm nd_get_artist_biography --wasi \
+ --input '{"id":"1","name":"The Beatles","mbid":"b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d"}' \
+ --allow-host "query.wikidata.org" \
+ --allow-host "en.wikipedia.org"
+```
+
+### Test artist images
+
+```bash
+extism call wikimedia.wasm nd_get_artist_images --wasi \
+ --input '{"id":"1","name":"The Beatles","mbid":"b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d"}' \
+ --allow-host "query.wikidata.org"
+```
+
+Expected output:
+```json
+{"images":[{"url":"http://commons.wikimedia.org/wiki/Special:FilePath/Beatles%20ad%201965%20just%20the%20beatles%20crop.jpg","size":0}]}
+```
+
+## API Endpoints Used
+
+| Service | Endpoint | Purpose |
+|---------|----------|---------|
+| Wikidata | `https://query.wikidata.org/sparql` | SPARQL queries for Wikipedia URLs and images |
+| DBpedia | `https://dbpedia.org/sparql` | Fallback SPARQL queries for Wikipedia URLs and short bios |
+| Wikipedia | `https://en.wikipedia.org/w/api.php` | MediaWiki API for article extracts |
+
+## Implemented Functions
+
+| Function | Description |
+|----------|-------------|
+| `nd_manifest` | Returns plugin manifest with HTTP permissions |
+| `nd_get_artist_url` | Returns Wikipedia URL for an artist |
+| `nd_get_artist_biography` | Returns artist biography from Wikipedia |
+| `nd_get_artist_images` | Returns artist image URLs from Wikidata |
+
+## License
+
+Same as Navidrome - GPL-3.0
diff --git a/plugins/examples/wikimedia/go.mod b/plugins/examples/wikimedia/go.mod
new file mode 100644
index 000000000..15afcd443
--- /dev/null
+++ b/plugins/examples/wikimedia/go.mod
@@ -0,0 +1,5 @@
+module wikimedia-plugin
+
+go 1.23
+
+require github.com/extism/go-pdk v1.1.3
diff --git a/plugins/examples/wikimedia/go.sum b/plugins/examples/wikimedia/go.sum
new file mode 100644
index 000000000..c15d38292
--- /dev/null
+++ b/plugins/examples/wikimedia/go.sum
@@ -0,0 +1,2 @@
+github.com/extism/go-pdk v1.1.3 h1:hfViMPWrqjN6u67cIYRALZTZLk/enSPpNKa+rZ9X2SQ=
+github.com/extism/go-pdk v1.1.3/go.mod h1:Gz+LIU/YCKnKXhgge8yo5Yu1F/lbv7KtKFkiCSzW/P4=
diff --git a/plugins/examples/wikimedia/main.go b/plugins/examples/wikimedia/main.go
new file mode 100644
index 000000000..b85ca4be0
--- /dev/null
+++ b/plugins/examples/wikimedia/main.go
@@ -0,0 +1,458 @@
+// Wikimedia plugin for Navidrome - fetches artist metadata from Wikidata, DBpedia and Wikipedia.
+//
+// Build with:
+//
+// tinygo build -o wikimedia.wasm -target wasip1 -buildmode=c-shared ./main.go
+//
+// Install by copying wikimedia.wasm to your Navidrome plugins folder.
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/url"
+ "strings"
+
+ "github.com/extism/go-pdk"
+)
+
+const (
+ wikidataEndpoint = "https://query.wikidata.org/sparql"
+ dbpediaEndpoint = "https://dbpedia.org/sparql"
+ mediawikiAPIEndpoint = "https://en.wikipedia.org/w/api.php"
+)
+
+// Manifest types
+type Manifest struct {
+ Name string `json:"name"`
+ Author string `json:"author"`
+ Version string `json:"version"`
+ Description string `json:"description"`
+ Website string `json:"website,omitempty"`
+ Permissions *Permissions `json:"permissions,omitempty"`
+}
+
+type Permissions struct {
+ HTTP *HTTPPermission `json:"http,omitempty"`
+}
+
+type HTTPPermission struct {
+ Reason string `json:"reason,omitempty"`
+ AllowedHosts []string `json:"allowedHosts,omitempty"`
+}
+
+// Input types
+type ArtistInput struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ MBID string `json:"mbid,omitempty"`
+}
+
+// Output types
+type URLOutput struct {
+ URL string `json:"url"`
+}
+
+type BiographyOutput struct {
+ Biography string `json:"biography"`
+}
+
+type ImageInfo struct {
+ URL string `json:"url"`
+ Size int `json:"size"`
+}
+
+type ImagesOutput struct {
+ Images []ImageInfo `json:"images"`
+}
+
+// SPARQL response types
+type SPARQLResult struct {
+ Results struct {
+ Bindings []SPARQLBinding `json:"bindings"`
+ } `json:"results"`
+}
+
+type SPARQLBinding struct {
+ Sitelink *SPARQLValue `json:"sitelink,omitempty"`
+ Wiki *SPARQLValue `json:"wiki,omitempty"`
+ Comment *SPARQLValue `json:"comment,omitempty"`
+ Img *SPARQLValue `json:"img,omitempty"`
+}
+
+type SPARQLValue struct {
+ Value string `json:"value"`
+}
+
+// MediaWiki API response types
+type MediaWikiExtractResult struct {
+ Query struct {
+ Pages map[string]MediaWikiPage `json:"pages"`
+ } `json:"query"`
+}
+
+type MediaWikiPage struct {
+ PageID int `json:"pageid"`
+ Ns int `json:"ns"`
+ Title string `json:"title"`
+ Extract string `json:"extract"`
+ Missing bool `json:"missing"`
+}
+
+//go:wasmexport nd_manifest
+func ndManifest() int32 {
+ manifest := Manifest{
+ Name: "Wikimedia",
+ Author: "Navidrome",
+ Version: "1.0.0",
+ Description: "Fetches artist metadata from Wikidata, DBpedia and Wikipedia",
+ Website: "https://navidrome.org",
+ Permissions: &Permissions{
+ HTTP: &HTTPPermission{
+ Reason: "Fetch metadata from Wikimedia APIs",
+ AllowedHosts: []string{
+ "query.wikidata.org",
+ "dbpedia.org",
+ "en.wikipedia.org",
+ },
+ },
+ },
+ }
+ out, err := json.Marshal(manifest)
+ if err != nil {
+ pdk.SetError(err)
+ return 1
+ }
+ pdk.Output(out)
+ return 0
+}
+
+// sparqlQuery executes a SPARQL query and returns the result
+func sparqlQuery(endpoint, query string) (*SPARQLResult, error) {
+ form := url.Values{}
+ form.Set("query", query)
+
+ req := pdk.NewHTTPRequest(pdk.MethodPost, endpoint)
+ req.SetHeader("Accept", "application/sparql-results+json")
+ req.SetHeader("Content-Type", "application/x-www-form-urlencoded")
+ req.SetHeader("User-Agent", "NavidromeWikimediaPlugin/1.0")
+ req.SetBody([]byte(form.Encode()))
+
+ pdk.Log(pdk.LogDebug, fmt.Sprintf("SPARQL query to %s: %s", endpoint, query))
+
+ resp := req.Send()
+ if resp.Status() != 200 {
+ return nil, fmt.Errorf("SPARQL HTTP error: status %d", resp.Status())
+ }
+
+ var result SPARQLResult
+ if err := json.Unmarshal(resp.Body(), &result); err != nil {
+ return nil, fmt.Errorf("failed to parse SPARQL response: %w", err)
+ }
+ if len(result.Results.Bindings) == 0 {
+ return nil, fmt.Errorf("not found")
+ }
+ return &result, nil
+}
+
+// mediawikiQuery executes a MediaWiki API query
+func mediawikiQuery(params url.Values) ([]byte, error) {
+ apiURL := fmt.Sprintf("%s?%s", mediawikiAPIEndpoint, params.Encode())
+
+ req := pdk.NewHTTPRequest(pdk.MethodGet, apiURL)
+ req.SetHeader("Accept", "application/json")
+ req.SetHeader("User-Agent", "NavidromeWikimediaPlugin/1.0")
+
+ resp := req.Send()
+ if resp.Status() != 200 {
+ return nil, fmt.Errorf("MediaWiki HTTP error: status %d", resp.Status())
+ }
+ return resp.Body(), nil
+}
+
+// getWikidataWikipediaURL fetches the Wikipedia URL from Wikidata using MBID or name
+func getWikidataWikipediaURL(mbid, name string) (string, error) {
+ var q string
+ if mbid != "" {
+ q = fmt.Sprintf(`SELECT ?sitelink WHERE { ?artist wdt:P434 "%s". ?sitelink schema:about ?artist; schema:isPartOf