automattic/federation
ActivityPub protocol specification and federation concepts. Use when working with ActivityPub activities, understanding federation mechanics, implementing protocol features, or debugging federation issues.
npx skills add https://github.com/Automattic/wordpress-activitypub --skill federation
This skill provides understanding of the ActivityPub protocol specification and how federation works.
For supported features and compatibility: See FEDERATION.md for the complete list of implemented FEPs, supported standards, and federation compatibility details.
For implementation details: See AGENTS.md for transformers, handlers, and PHP code patterns.
inbox, outboxfollowers, following, liked{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Person",
"id": "https://example.com/@alice",
"inbox": "https://example.com/@alice/inbox",
"outbox": "https://example.com/@alice/outbox",
"followers": "https://example.com/@alice/followers",
"following": "https://example.com/@alice/following",
"preferredUsername": "alice",
"name": "Alice Example",
"summary": "Bio text here"
}
Inbox - Receives incoming activities
Outbox - Publishes actor's activities
Followers - Actors following this actor
Following - Actors this actor follows
Special collection: https://www.w3.org/ns/activitystreams#Public
to, cc, bto, bcc fields for visibilityWraps newly published content:
{
"type": "Create",
"actor": "https://example.com/@alice",
"object": {
"type": "Note",
"content": "Hello, Fediverse!"
}
}
Initiates subscription:
{
"type": "Follow",
"actor": "https://example.com/@alice",
"object": "https://other.example/@bob"
}
Indicates appreciation:
{
"type": "Like",
"actor": "https://example.com/@alice",
"object": "https://other.example/@bob/post/123"
}
Reshares/boosts content:
{
"type": "Announce",
"actor": "https://example.com/@alice",
"object": "https://other.example/@bob/post/123"
}
Modifies existing content:
null values remove fieldsRemoves content:
Reverses previous activities:
{
"type": "Undo",
"actor": "https://example.com/@alice",
"object": {
"type": "Follow",
"id": "https://example.com/@alice/follow/123"
}
}
to, bto, cc, bcc, audience fieldsinbox propertysharedInbox if available for efficiencyapplication/ld+json; profile="https://www.w3.org/ns/activitystreams"Ghost Replies Problem: When Alice replies to Bob's post that Carol follows, Carol might not see the reply if she doesn't follow Alice.
Solution: Inbox forwarding
For public posts with many recipients on same server:
sharedInbox endpoint instead of individual inboxesto - Primary recipients (public in UI)cc - Secondary recipients (copied/mentioned)bto - Blind primary (hidden in delivery)bcc - Blind secondary (hidden in delivery)Important: Remove bto and bcc before delivery to preserve privacy
Public Post:
{
"to": ["https://www.w3.org/ns/activitystreams#Public"],
"cc": ["https://example.com/@alice/followers"]
}
Followers-Only:
{
"to": ["https://example.com/@alice/followers"]
}
Direct Message:
{
"to": ["https://other.example/@bob"],
"cc": []
}
See FEDERATION.md for the complete list of implemented standards and FEPs, including:
FEPs extend ActivityPub with additional features. Common FEP categories include:
For supported FEPs in this plugin: See FEDERATION.md for the authoritative list of implemented FEPs.
When the ActivityPub API option is enabled, third-party clients can authenticate via OAuth 2.0 under activitypub/1.0/oauth/. The plugin supports RFC 7591 dynamic registration, RFC 7636 PKCE (S256 only, required by default for public clients), and the CIMD draft (URL-form client_id, HTTPS required).
Native apps receive the OAuth callback on a loopback port they opened locally. Per RFC 8252 §7.3 / §8.3, redirect URIs of the form http://127.0.0.1:{port}/{path} and http://[::1]:{port}/{path} are accepted with port flexibility (any port may be used at request time). localhost is also accepted for compatibility, although §8.3 marks it "NOT RECOMMENDED".
The loopback allowance applies *only* to redirect URI matching. Reserved-but-not-loopback addresses — 0.0.0.0, link-local 169.254.0.0/16, RFC1918 private ranges (10/8, 172.16/12, 192.168/16), and similar — are not treated as loopback and never bypass wp_safe_remote_get(). CIMD metadata URLs must use https://, and the metadata host is resolved and validated against private/reserved ranges before any fetch — loopback CIMD origins are not supported, even on dev installs.
For implementation details: See includes/oauth/class-client.php (especially the class docblock and is_loopback()) and the OAuth section of FEDERATION.md.
This plugin implements:
For implementation details, see:
# Test actor endpoint
curl -H "Accept: application/activity+json" \
https://site.com/@username
# Test WebFinger
curl https://site.com/.well-known/webfinger?resource=acct:[email protected]
# Test NodeInfo
curl https://site.com/.well-known/nodeinfo
inReplyTo properly setTake automattic/federation from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.