Vibefed detect-nodeinfo
git clone https://github.com/reiver/vibefed
T=$(mktemp -d) && git clone --depth=1 https://github.com/reiver/vibefed "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/detect-nodeinfo" ~/.claude/skills/reiver-vibefed-detect-nodeinfo && rm -rf "$T"
skills/detect-nodeinfo/SKILL.mdDetect NodeInfo Endpoint
NodeInfo is a protocol used by federated social network servers to expose instance metadata in a standardized format. It is widely used in the Fediverse (Mastodon, Misskey, Pleroma, Diaspora, etc.).
How NodeInfo Works (Two-Part Architecture)
NodeInfo is always two endpoints, not one. This is important for classification:
Part 1 — Discovery endpoint (required):
- URL:
GET /.well-known/nodeinfo - Returns a JSON object with a
array, each entry pointing to a versioned schema documentlinks - Example response:
{ "links": [ { "rel": "http://nodeinfo.diaspora.software/ns/schema/2.1", "href": "https://example.org/nodeinfo/2.1" } ] }
Part 2 — Schema endpoint (required):
- URL: typically
or/nodeinfo/2.1
(path is not standardized, but this convention is near-universal)/nodeinfo/2.0 - Returns the full instance metadata document
- Key fields:
,version
,software
,protocols
,usage
,openRegistrationsmetadata
Variant — NodeInfo2 (optional, separate spec):
- URL:
GET /.well-known/x-nodeinfo2 - A different, simpler schema by a different author (jaywink/nodeinfo2)
- Less common; treat as a separate positive signal if found
Step 1 — Fast Signal Search
Search the codebase for
nodeinfo (case-insensitive) across all source
files, excluding: node_modules, vendor, .git, dist, build.
If no matches are found, proceed to Step 2 (fallback search). If matches are found, proceed to Step 3 (classify results).
Step 2 — Fallback Search (if Step 1 found nothing)
Some implementations use only generic well-known routing. Search for:
(the discovery path literal)/.well-known/nodeinfo
(the rel URL used in the links array — a very specific signal)diaspora.software/ns/schema
(NodeInfo2 variant path)x-nodeinfo2
(a distinctive field name in the schema response)openRegistrations
oractiveHalfyear
(unique usage stats field)activeHalfYear
If still nothing — report: NodeInfo not detected.
Step 3 — Classify Each Match
For each file containing a match, determine which category it falls into:
Category A — Discovery endpoint (confirmed)
The file registers a route at
/.well-known/nodeinfo that returns a
links array pointing to a versioned schema document.
Category B — Schema endpoint (confirmed)
The file registers a route (commonly
/nodeinfo/2.0, /nodeinfo/2.1,
/nodeinfo/2.2) that returns the full instance metadata document with
fields like software, protocols, usage, openRegistrations.
Category C — Both endpoints present
The codebase implements both Part 1 and Part 2 — this is a complete implementation.
Category D — Library/Framework delegation
The file imports or references a NodeInfo library (e.g.
go-nodeinfo,
@semapps/nodeinfo, nodeinfo-rack, ActivityPub frameworks like Fedify
which auto-register NodeInfo) without directly defining the handlers.
Category E — Reference only (not an implementation)
The match appears in comments, test fixtures, README files, or configuration pointing to an external NodeInfo server.
Category F — NodeInfo2 variant
The file handles
/.well-known/x-nodeinfo2 — a valid but separate
implementation of the NodeInfo2 spec (jaywink/nodeinfo2). Report alongside
standard NodeInfo findings.
Step 4 — Check for Framework-Specific Patterns
| Framework / Language | Pattern to look for |
|---|---|
| Rails | in routes.rb; |
| Django | in urls.py |
| Express / Node | |
| Spring Boot | |
| Go | constant; handler |
| Mastodon | |
| Misskey / Calckey | in route definitions |
| Fedify (TS/JS) | NodeInfo auto-registered — look for |
| PHP (ActivityPub) | near |
Step 5 — Check Schema Version Support
If a schema endpoint is found, note which version(s) are supported:
— original, rarely seen today1.0
— adds1.1services
— adds2.0
; most commonusage.localComments
— adds2.1
andsoftware.repository
; current standardsoftware.homepage
— draft; uncommon2.2
The
rel URL in the discovery response encodes the version:
http://nodeinfo.diaspora.software/ns/schema/2.1
Step 6 — Report Results
Provide a clear summary with:
- Verdict: NodeInfo detected / Not detected / Possibly delegated to library
- Parts found:
- Discovery endpoint (
): Yes / No / Via library/.well-known/nodeinfo - Schema endpoint (
): Yes / No / Via library/nodeinfo/x.y - NodeInfo2 variant (
): Yes / No / N/A/.well-known/x-nodeinfo2
- Discovery endpoint (
- Schema versions supported (if determinable)
- Evidence: File names and line numbers containing the implementation
- Implementation style: Direct / Library delegation / Framework built-in
- Completeness notes (if applicable):
- e.g. "Discovery endpoint found but no schema endpoint detected"
- e.g. "Schema endpoint found but
stats appear hardcoded rather than queried from a database"usage - e.g. "Missing
field in schema response"openRegistrations
- Caveats: e.g. "NodeInfo may be handled by a reverse proxy or middleware layer not visible in application code"
What a Complete NodeInfo Implementation Looks Like
For reference, a complete implementation provides:
Discovery (
/.well-known/nodeinfo):
{ "links": [ { "rel": "http://nodeinfo.diaspora.software/ns/schema/2.1", "href": "https://example.org/nodeinfo/2.1" } ] }
Schema (
/nodeinfo/2.1):
{ "version": "2.1", "software": { "name": "myapp", "version": "1.0.0", "repository": "https://github.com/example/myapp", "homepage": "https://example.org" }, "protocols": ["activitypub"], "usage": { "users": { "total": 100, "activeHalfyear": 50, "activeMonth": 20 }, "localPosts": 1000, "localComments": 500 }, "openRegistrations": true, "metadata": {} }