A clean, httpie-style command-line client for Meta's Graph API and Instagram Graph API.
$ meta me
{"id": "10000...", "name": "Jane Doe"}
$ meta ig accounts
{"data": [{"page_id": "12345", "page_name": "My Page", "ig_user_id": "17841..."}], "count": 1}
$ meta ig publish 17841... --image-url https://example.com/img.jpg --caption "Hello world"
{"container_id": "18002...", "status": {"status_code": "FINISHED"}, "published": {"id": "17984..."}}
No SDK to wrap, no React app to log in to, no config server. Just your token and a thin HTTP shell.
Meta ships SDKs (Python, JS, PHP) but no CLI. The SDKs are typed object hierarchies that don't translate to flags, and the official one is heavy and Marketing-skewed. meta-graph is the missing piece: a small, version-agile CLI that maps directly to the underlying HTTP API and bundles the entire Graph + Instagram reference offline.
pip install meta-graph-cli # binary becomes `meta`Or from source:
git clone https://github.com/crimeacs/meta-graph-cli && cd meta-graph-cli
pip install -e .Get a short-lived user token from the Graph API Explorer and either:
export META_GRAPH_TOKEN="EAA..."…or write a config file at ~/.config/meta-graph/config.toml:
[default]
token = "EAA..."
api_version = "v22.0"
app_secret = "..." # optional; enables appsecret_proof signing
[profile.prod]
token = "EAA..."Use --profile prod to switch profiles.
meta token info # decode scopes, expiry, app id
meta token refresh --app-id ... --app-secret ... # short-lived → long-lived (~60 days)meta get /me fields=id,name,email
meta get /PAGE_ID/feed fields=id,message,created_time limit=50
meta post /PAGE_ID/feed message='Hello world'
meta delete /POST_ID
echo '[{"method":"GET","relative_url":"me"},
{"method":"GET","relative_url":"me/accounts?limit=2"}]' | meta batchmeta me # /me
meta me pages # /me/accounts (with linked IG account ids)
meta me permissions # granted/declined permissions# two flows, auto-detected from token prefix:
# EAA… → graph.facebook.com (Instagram with Facebook Login; needs linked Page)
# IGAA… → graph.instagram.com (Instagram with Instagram Login; no Page needed)
# Override the host with --base when needed.
# accounts
meta ig accounts # works on either flow
# IG-direct shortcuts (no explicit ig_id needed)
meta ig me # the IG account itself
meta ig me media [--all] # your media
meta ig me insights --metric impressions,reach --period day
# user
meta ig user IG_ID # account fields
meta ig user IG_ID media [--all] # list media
meta ig user IG_ID stories # active stories
meta ig user IG_ID tags # tagged in
meta ig user IG_ID mentions # @mentions
meta ig user IG_ID insights --metric impressions,reach --period day
meta ig user IG_ID limit # 24h publish quota
meta ig user IG_ID live # active live broadcasts
# publish (two-step container flow handled for you)
meta ig publish IG_ID --image-url https://example.com/img.jpg --caption "..."
meta ig publish IG_ID --video-url https://example.com/clip.mp4
meta ig publish IG_ID --video-url https://... --reel
meta ig publish IG_ID --carousel "https://a.jpg,https://b.jpg,https://c.mp4" --caption "..."
meta ig publish IG_ID --story-image https://example.com/story.jpg
meta ig publish-status CONTAINER_ID
# media
meta ig media MEDIA_ID
meta ig media MEDIA_ID children
meta ig media MEDIA_ID comments [--all]
meta ig media MEDIA_ID insights --metric impressions,reach,saved,video_views
meta ig media MEDIA_ID delete
# comments
meta ig comment-on MEDIA_ID --message "Welcome!"
meta ig comment COMMENT_ID
meta ig comment COMMENT_ID reply --message "Thanks!"
meta ig comment COMMENT_ID hide
meta ig comment COMMENT_ID unhide
meta ig comment COMMENT_ID delete
# hashtags
meta ig hashtag search "barista"
meta ig hashtag recent HASHTAG_ID
meta ig hashtag top HASHTAG_ID
# discovery + embed
meta ig business-discovery IG_ID --username @nasa
meta ig oembed https://www.instagram.com/p/SHORTCODE/meta nodes # every documented Graph + IG node
meta edges page # edges of /page
meta fields user # documented fields of /usermeta get /me # compact JSON, jq-friendly
meta get /me --pretty # indented + colored when stdout is a TTY
meta get /me --jq '.id' # passthrough to jq if installed; tiny fallback otherwiseErrors go to stderr as JSON. Exit codes:
| code | meaning |
|---|---|
| 0 | success |
| 1 | Graph API error |
| 2 | usage error (bad flags / JSON) |
| 3 | auth (token missing / invalid / expired) |
- Thin HTTP wrapper. No FB SDK; just
requests. The CLI follows the Graph API shape directly so anything Meta documents is reachable viameta get/post/delete. - Auto retry on transient codes (
1,2) and rate limits (4,17,32,613) with exponential backoff + jitter. appsecret_proofsigning on every request whenapp_secretis configured (recommended for Live-mode apps).- Cursor pagination via
--allon listing commands; underlyingclient.paginate()followspaging.nextuntil exhausted. - Batched requests via
meta batch(reads JSON array from stdin). - Bundled docs at
docs/reference.md— every Graph + Instagram endpoint scraped in one searchable markdown file. Regenerated viapython scripts/scrape.py && python scripts/concat.py && python scripts/build_data.py.
A Claude Code skill named meta-platform-ops ships at skills/meta-platform-ops/ and teaches Claude how to drive this CLI from natural-language requests. Install with:
mkdir -p ~/.claude/skills && cp -r skills/meta-platform-ops ~/.claude/skills/Then ask Claude things like "post this image to Instagram with caption '…'" or "reply to all unanswered comments on this Reel" — it'll resolve your IG account, run the right meta ig … invocations, and surface error codes with actionable fixes. See skills/README.md for details.
from meta_graph.client import GraphClient
client = GraphClient(token="EAA...", version="v22.0", app_secret="...")
me = client.get("/me", fields="id,name")
for media in client.paginate("/IG_ID/media", fields="id,caption,timestamp"):
print(media["id"], media.get("caption"))pip install -e .[dev]
pytest -q # unit + vcr replay
ruff check src/ tests/
mypy --strict src/meta_graphMIT — see LICENSE.
The bundled docs/reference.md is scraped from https://developers.facebook.com/docs/ and is © Meta Platforms, Inc.