Install
$ agentstack add skill-jedi4ever-social-skills-social-ledger ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
social-ledger skill
Wraps the social-ledger Go binary at scripts/social-ledger. The ledger is a persistent local memory for every URL the agent has read — automatic when content comes through social-fetch fetch / research / timeline, manual via record for content the agent fetched through other tools (Claude's WebFetch, the research tool's web search, a curl one-off).
Trust the ledger. When the user asks "have we read this before?" or "what did we learn about X recently?" — query the ledger first. Only re-fetch on cache miss. The cache survives across conversations, computer restarts, and Claude versions.
Provenance — know how much to trust each entry. The ledger records who put each item in. Two classes:
- auto-fetched — entry was ingested by `social-fetch fetch /
search / ask / timeline / research. We pulled the URL ourselves, ran our own extractor, normalised the markdown. **High trust.** The source column is one of the platform names: hackernews, reddit, github, x, twitter, linkedin, youtube, bluesky, arxiv, medium, substack, rss, article`.
- agent-recorded — entry was stored via
social-ledger article record,
meaning an agent fed in content it got from somewhere else (Claude's WebFetch, the research tool, a curl one-off, hand paste). Trust depends on what was fed in. The source column is one of webfetch, manual, research-tool, citation.
Quoting from a webfetch-source entry is fine for "what does the page say at a glance"; for high-stakes citations, prefer auto-fetched entries or re-fetch the URL via social-fetch fetch to get a fresh copy through our extractor. The MCP social_ledger_get tool surfaces this as a provenance field on every retrieval; the CLI shows the source column on list / search / get so you can eyeball it.
Subcommands
scripts/social-ledger article seen ... # is URL(s) in the ledger?
scripts/social-ledger article get # full content of one entry
scripts/social-ledger article list [flags] # browse newest first
scripts/social-ledger article search "" # FTS5 over title/content
scripts/social-ledger article stats # counts, sizes
scripts/social-ledger article record [flags] # store URL+content (stdin)
scripts/social-ledger article forget # drop one entry
scripts/social-ledger article filter --skip-seen # JSONL passthrough drops seen
scripts/social-ledger help for full flag reference.
Decision rules
Before fetching anything, ask the ledger first. If the user mentions a URL or topic that might already be cached, run seen / search before any new fetch:
scripts/social-ledger article seen "https://news.ycombinator.com/item?id=43000000"
# seen → use `get` to retrieve, no re-fetch
# unseen → fall through to `social-fetch fetch` or WebFetch
For content-bearing queries:
scripts/social-ledger article search "harness engineering"
# returns BM25-ranked hits across every saved item's title /
# summary / content / author / tags
Combine: search to find candidates, get to dump one in full, then summarise.
Recording content from outside social-fetch
> DO NOT call record for content fetched via social-fetch. > social-fetch fetch / search / ask / timeline / research > all auto-ingest into the ledger via the auto-detected > sibling binary. Calling record on top creates a duplicate > row. The two are mutually exclusive. > > DO call record for content fetched outside social-fetch: > - Claude's WebFetch tool (the built-in one) > - Claude's research / search tool result snippets > - Ad-hoc curl, wget, hand-pasted text > - Any source that didn't go through a social-* binary
When the user asks the agent to fetch content via one of those non-social-fetch paths, the result isn't in the ledger automatically. Add it after, so the next conversation finds it:
# 1. fetch via Claude's WebFetch tool (output: markdown)
# 2. record it:
scripts/social-ledger article record \
--title "Page Title" \
--source webfetch \
"https://example.com/post" `, `--title`. Everything else (`--summary`,
`--author`, `--source`, `--canonical-id`, `--content FILE`) is
optional. Source defaults to `webfetch`; override to
`research-tool`, `manual`, etc. for cleaner `list --source`
filtering later.
**Workflow recipe** for the WebFetch case — user asks the agent
to read a URL that the agent fetches via Claude's WebFetch tool
(NOT social-fetch — if you used `social-fetch fetch`, skip the
record step entirely; it's already in the ledger):
1. `seen ` → if seen, skip 2-3, use `get ` for the body.
2. WebFetch the URL → capture markdown.
3. **Write the markdown to a temp file** (e.g. `/tmp/.md`)
using the Write tool. Then `record --title "..." --source
webfetch --content /tmp/.md`. **Don't stream the markdown
through stdin or as a JSON string when it's longer than a
handful of lines** — file paths avoid bloating the agent's
token budget and the MCP escape-encoding overhead.
4. Reason / summarize from the recorded content.
**The mirror workflow for the social-fetch case** (read this so
you don't double-record):
1. `seen ` → if seen, skip 2, use `get `.
2. `social-fetch fetch ` (or search / ask / etc.) — this
auto-ingests into the ledger; the agent does NOT need to call
record. Verify with `seen ` afterwards if uncertain.
3. Reason / summarize from the fetched content.
The ledger's deduplication (key = `source::canonical_id`) means
re-recording the same URL with the same content is a no-op
(`unchanged`), and re-recording with new content updates the
existing row — agents can run record liberally without worrying
about duplicates.
### Worked example — record the result of a Claude WebFetch
The agent has been asked to summarize a Vercel blog post that
isn't on a platform `social-fetch` natively recognises. It
WebFetches the URL, then records the result so future "have we
seen this?" queries hit cache.
Step 1 — check if the ledger already has it:
```bash
scripts/social-ledger article seen "https://vercel.com/blog/agent-skills"
# unseen https://vercel.com/blog/agent-skills
Step 2 — call Claude's WebFetch tool. The agent gets markdown content back. Write it to a temp file with the Write tool rather than holding the entire body in conversation memory:
# (pseudocode for the agent's perspective)
# 1. WebFetch("https://vercel.com/blog/agent-skills")
# → markdown body returned
# 2. Write tool: /tmp/vercel-agent-skills.md ← markdown body
Step 3 — record by file path (NOT by streaming the content through). The --content FILE flag reads the body from disk so the markdown never has to round-trip through the agent's prompt or the MCP JSON-escape:
scripts/social-ledger article record \
--title "Agent Skills on Vercel" \
--summary "How Vercel ships agent skills via npx skills add" \
--source webfetch \
--author "vercel-labs" \
--content /tmp/vercel-agent-skills.md \
"https://vercel.com/blog/agent-skills"
# stderr: recorded: https://vercel.com/blog/agent-skills (new)
If the body is genuinely tiny (a one-line description, a tweet quote) and writing-then-reading is overkill, stdin still works:
echo "Short body inline." | scripts/social-ledger article record \
--title "Quick Note" --source manual "https://example.com/x"
But for any real WebFetch output, prefer the file path — typical blog posts are 5-50 KB of markdown which is wasteful as a JSON-string argument or piped stdin.
Step 4 — confirm + summarize. The ledger now has the entry; a second seen returns seen, and get dumps the markdown back on demand:
scripts/social-ledger article seen "https://vercel.com/blog/agent-skills"
# seen https://vercel.com/blog/agent-skills
scripts/social-ledger article get "https://vercel.com/blog/agent-skills"
# # Agent Skills on Vercel
# source: webfetch
# url: https://vercel.com/blog/agent-skills
# author: vercel-labs
# (...full body...)
Subsequent conversations that ask "what did we save about Vercel agent skills?" will find this entry via search:
scripts/social-ledger article search "vercel agent skills"
# webfetch Agent Skills on Vercel https://vercel.com/blog/agent-skills
# How Vercel ships agent skills via npx skills add
One-liner template for the common case (file-based, recommended):
# 1. Write tool: /tmp/.md ← WebFetch markdown
# 2. Record:
scripts/social-ledger article record \
--title "$TITLE" --source webfetch \
--content /tmp/.md \
"$URL"
The Write-then-record pattern keeps the markdown body off the agent's token budget AND off the MCP JSON-escape path. For multi-page articles this saves thousands of tokens vs. inlining.
Listing + filtering
scripts/social-ledger article list # newest 25
scripts/social-ledger article list --source hackernews # only HN entries
scripts/social-ledger article list --source webfetch # only Claude-recorded
scripts/social-ledger article list --since 7d # last week
scripts/social-ledger article list -n 100 # bigger window
stats for an at-a-glance summary:
scripts/social-ledger article stats
# → counts per source, total items, disk usage, oldest/newest
Storage location
Default: $XDG_DATA_HOME/social-ledger (typically ~/.local/share/social-ledger). Override per-call with --data-dir , or globally with SOCIAL_LEDGER_DIR.
The store is a single SQLite file (ledger.db) plus an on-disk markdown mirror tree (tree/by-source/, tree/by-date/, tree/by-url//) — agents can also grep / Read files under tree/by-source/ directly for fuzzy "did we save anything about X" without going through search.
Output format
list and search emit one item per line:
2026-05-03 hackernews Y Combinator
https://news.ycombinator.com/item?id=1
(date \t source \t title, then a indented URL line). Easy to grep through and parse. get emits full content as markdown with frontmatter (source, url, author, score, tags, fetched_at). The JSON output mode for seen (--format json) is the cleanest parse target for agent code:
[{"url":"https://...", "seen":true}, {"url":"...", "seen":false}]
When NOT to use this skill
- The user explicitly asks for fresh content ("re-fetch X
with the latest comments"). Hit social-fetch fetch directly.
- The ledger is empty or you're certain the URL is new — running
seen first is wasteful, just fetch.
- Bulk delete / migration / restore — out of scope; tell the
user to operate on the SQLite file directly.
Influencers — track topic authorities
The ledger doubles as a curated directory of people / companies the agent should treat as authorities on specific topics. Same storage, different source tag (influencer).
scripts/social-ledger influencer add "Andrej Karpathy" \
--x karpathy --github karpathy \
--topics ai,research,transformers \
--description "Former Tesla AI / OpenAI co-founder"
scripts/social-ledger influencer subscribe "Andrej Karpathy" \
--platform x --topics ai
scripts/social-ledger influencer list --topic ai --followed
scripts/social-ledger influencer show andrej-karpathy
scripts/social-ledger influencer unsubscribe andrej-karpathy --platform x
scripts/social-ledger influencer remove andrej-karpathy
Re-running add for the same name upserts (socials merge, new platform overwrites same key, others kept; topics union; description replaces when non-empty). So "I just learned Jane's mastodon handle" is one line: add jane --social mastodon=@jane@example.com.
MCP tools mirror the CLI shape for agents that prefer structured calls over shelling out: social_ledger_influencers_{list,get,add,remove,subscribe,unsubscribe}. Use mid-research: when you discover a new authority worth tracking ("the author of this Archon project ships a lot of agent content"), call social_ledger_influencers_add so the next conversation finds them in the directory.
Related
social-fetch fetchand friends auto-populate the ledger when
SOCIAL_LEDGER is unset/auto/1 and social-ledger is on PATH (or bundled alongside in this skill). No env-var setup needed for this skill — auto-detect handles it.
- The standalone
social-fetchskill covers fetch / search /
ask / timeline / research / bridge. Use both: this skill for reading the cache, that one for filling it.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: jedi4ever
- Source: jedi4ever/social-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.