---
title: Tweet cards (any X/Twitter link renders the tweet, everywhere)
---

# Tweet cards (any X/Twitter link renders the tweet, everywhere)

## What it is

When an X / Twitter **tweet link** (like `https://x.com/SomeUser/status/123…`)
appears anywhere in Omniscio, the app shows the tweet itself — a picture-perfect
**screenshot card** of the tweet (its text plus any images) — right below the
message. It's the exact same rendered tweet you get when you paste a tweet link
into a KMS note.

The key point: it works **no matter how the link got there**. It doesn't matter
whether you pasted it, an agent wrote it in its reply, it arrived as an inbox
alert, a Field-Theory bookmark dripped it in, or it came through a team-chat
message — the same tweet card appears. Click the card to open the tweet on X.

## Where to find it

There is nothing to open or turn on: the card appears inline, right under the text, wherever the link shows up — a message you pasted, an agent reply, an inbox alert, a Field-Theory bookmark drip, a team-chat message, or a KMS note. Click the card to open the original tweet in your browser.

## How it behaves

### How to use it

Nothing to turn on — it just happens. Wherever a tweet link shows up:

1. The tweet's screenshot appears inline under the text.
2. Click it to open the original tweet in your browser.

On a phone it works too — the card loads over Omniscio's secure mobile link.

### What gets a card (and what doesn't)

- **A tweet/status link** (`x.com/<user>/status/<id>` or the `twitter.com`
  equivalent) → tweet card. ✅
- A **profile** link, a `t.co` short link, or any **non-tweet** link → no tweet
  card (a normal web link may still get a plain [link preview](link-hover-title.md)
  in team chat). ✅
- Up to **3 tweets per message** render, to keep things tidy.

### Why it's cheap and safe

Rendering a tweet uses a paid screenshot service, so Omniscio is careful:

- **Each tweet is rendered once, ever.** The screenshot is cached on your machine
  and reused everywhere it appears again — so the same tweet never costs twice.
- **Bursts are capped.** If something (say a busy agent) drops many _different_
  tweet links at once, Omniscio renders up to an hourly limit and shows the plain
  link for the rest, so cost can't run away.
- **Failures are invisible.** A deleted/private tweet, a slow render, or any error
  just leaves the plain link — never a broken image or an error message.
- **No arbitrary web access.** Omniscio only ever sends the tweet's **numeric id**
  to one fixed rendering service — it never fetches a random URL an agent supplied,
  so a malicious link can't be used to probe your network.

**Turn it off:** set `AMC_DISABLE_TWEET_SHOT_CARDS=1` (tune the hourly cap with
`AMC_TWEET_SHOT_HOURLY_MAX`).

### Limitations

- **It's a screenshot**, captured at first sight — not a live, always-current
  embed.
- **Public tweets only.** A deleted or private tweet falls back to the plain link.
- **Tweet status links only** — not profiles, lists, or search links.

## For agents

### How it works (for agents with repo access)

- **Detection (shared)** — [`tweet-url.ts`](/src/shared/tweet-url.ts)
  (`extractTweetUrls` / `extractTweetId`) finds tweet status URLs in any text.
- **Renderer** — [`TweetShots.tsx`](/src/renderer/src/components/ui/TweetShots.tsx)
  (`<TweetShots text enabled?>`) renders a screenshot card per tweet and is wired
  into every content surface: inbox alerts + drip
  ([`AlertContentViewer.tsx`](/src/renderer/src/components/inbox/AlertContentViewer.tsx)),
  agent + operator session messages
  ([`MessageBubbleBody.tsx`](/src/renderer/src/components/ui/MessageBubble/MessageBubbleBody.tsx)),
  and team chat
  ([`TeamChatLinkPreviews.tsx`](/src/renderer/src/features/team-chat/TeamChatLinkPreviews.tsx)).
  Session messages render only once the message is finished (never mid-stream).
- **IPC + Main** — `IPC.LINK_PREVIEW_TWEET_SHOT` →
  [`tweet-shot-cache.ts`](/src/main/services/tweet-shot/tweet-shot-cache.ts)
  (`ensureTweetShot`): cache-first, then a hourly-budgeted call to the tweet-shots
  relay (server-held key), stored **vault-free** at
  `<userData>/tweet-shot-cache/<id>.png`. Served over the `tweetshot://shot/<id>`
  protocol url (desktop) and the `/tweetshot/:id` route (mobile). The id sits in the
  PATH, never the authority: `tweetshot` is a standard scheme, so Chromium would
  canonicalize an all-digit authority as an IPv4 address and the image would never
  load.
- Invariants (provenance-independence, cost bounds, SSRF-safety, graceful
  fallback) are locked by tests and documented in
  `.claude/memory/contracts/tweet-shot-cross-surface-contract.md`.

## Related

- [link-hover-title.md](link-hover-title.md) — hover any web link to see its page
  title (the generic link preview).
- [kms.md](kms.md) — the KMS note editor, where pasting a tweet link first produced
  this same screenshot.
