langchain-ai/social-media-agent: URL to Twitter and LinkedIn Post with Human Approval
📲 An agent for sourcing, curating, and scheduling social media posts with human-in-the-loop.
At a glance
- What is it?
- A TypeScript LangGraph agent that scrapes a URL, drafts a Twitter and LinkedIn post, and pauses for a human to approve or edit before anything is published. It is a developer tool, not a hosted product, and the quickstart drops GitHub, Slack, and image handling.
- Who is it for?
- Adopt it if you already run LangGraph and want a review gate between scraping and publishing, and you are willing to hold Anthropic, LangSmith, FireCrawl, Arcade and Supabase keys. Do not adopt it if you want a hosted scheduler or an OAuth flow you control without Arcade.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 20, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap between a URL and a published post
Most content pipelines fail at the same two points: turning a link into something worth posting, and getting a human to look at it before it goes out. langchain-ai/social-media-agent targets both. The README describes it as an agent that "can take in a URL, and generate a Twitter & LinkedIn post based on the content of the URL", with a human-in-the-loop flow that handles platform authentication and lets the user "make changes, or accept/reject the generated post".
The intended user is a developer or content engineer who already works with LangGraph and wants the review step inside the graph rather than bolted on as an approval email. It is not a marketing dashboard. There is no homepage listed for the repository, no release has been retrieved, and the package.json still carries the starter-template name "example-graph" with the description "A starter template for creating a LangGraph workflow". That tells you how the project is positioned: a working reference implementation you fork and adapt, not a versioned product you pin.
How the graph scrapes, drafts, and waits for approval
The repository lists a static/agent_flow.png and a static/graph_screenshot.png, which the README uses to illustrate the flow. From the setup steps you can reconstruct the data path. A URL enters a run started by scripts/generate-post.ts. FireCrawl handles scraping, which is why FIRECRAWL_API_KEY appears in both the quickstart and full env examples. An LLM call against Anthropic produces the draft, which is why ANTHROPIC_API_KEY is required. Arcade sits between the agent and the social platforms, described as "Easy authentication for reading & writing to social media platforms", and is also used for "fetching Tweets, and scheduling LinkedIn/Twitter posts".
The human-in-the-loop step is where the graph interrupts. The README points readers to Agent Inbox to inspect output, with both a deployed and a local option, and to LangSmith as the alternative view. Approval is therefore an interaction with a separate inbox surface, not a terminal prompt. The scheduling layer is separate again: package.json exposes cron:create, cron:delete, and cron:list scripts under scripts/crons/, plus get:scheduled_runs and get:used_links. The used-links script implies the agent tracks which URLs it has already posted, which matters if you run it on a schedule against a feed of links.
Two Python files sit alongside the TypeScript source: pyproject.toml and uv.lock, with the project named langgraph-slack and dependencies on slack-bolt, fastapi, and langgraph-sdk. The README separately offers a Slack developer account as an optional way to ingest data from a Slack channel. So the Slack integration is a Python sidecar, not part of the main TypeScript graph, and it carries its own dependency tree and its own CVE pins for starlette, urllib3, and cryptography.
Installing it and generating your first post
The quickstart assumes Node, Yarn, and a Python toolchain for the LangGraph CLI. Clone, install, and copy the quickstart env file:
git clone https://github.com/langchain-ai/social-media-agent.git
cd social-media-agent
yarn install
cp .env.quickstart.example .envThen fill in the keys the README lists. LANGSMITH_TRACING_V2 is set to true in the example, and LANGSMITH_API_KEY is marked optional in the comment but the README says a LangSmith API key is required to run the LangGraph server locally. Treat it as required despite the comment.
LANGSMITH_API_KEY=
LANGSMITH_TRACING_V2=true
ANTHROPIC_API_KEY=
FIRECRAWL_API_KEY=
ARCADE_API_KEY=The LangGraph CLI installs through pip, and the README suggests confirming it before starting the server:
pip install langgraph-cli
langgraph --version
yarn langgraph:in_mem:upThe last command wraps npx @langchain/langgraph-cli dev --port 54367. The README warns that the first run asks you to accept a CLI install, and you enter y. Once the server is ready, generate a post:
yarn generate_postThat script fires a run against a LangChain blog post as its default input, and the README says you can edit the script to pass different URLs. To see the result, open Agent Inbox or LangSmith. Nothing is published at this point; you are looking at a draft awaiting approval.
The quickstart quietly removes half the feature set
The README is unusually direct about this, which is worth crediting. Running in basic setup mode lacks three things: "Parsing content from GitHub, Twitter or YouTube URLs", "Ingesting data from Slack, or sending updates to Slack", and "Image selection & uploads". If your source URLs are GitHub repositories or YouTube videos, the quickstart will not read them properly, and you will not find that out from an error message.
The full setup widens the key surface considerably. Beyond Anthropic, LangSmith, FireCrawl, and Arcade, it lists Google Vertex AI for YouTube content, a Twitter developer account for uploading media, a LinkedIn developer account for posting, a GitHub personal access token for reading GitHub content, Supabase for storing images, and an optional Slack developer account. That is eight external services before you have posted anything.
Authentication is an either/or, and the README states it plainly: "You can use either method, but not both." You go through Arcade, or you bring your own Twitter and LinkedIn developer accounts. The Arcade path needs ARCADE_API_KEY plus TWITTER_USER_ID and LINKEDIN_USER_ID, and USE_ARCADE_AUTH set to true. That last variable is the kind of switch that silently changes behaviour if it is wrong, and the README excerpt does not document what happens when it is false while Arcade credentials are present.
Where it is the wrong tool
The human-in-the-loop design is the product, and it is also the constraint. Any workflow that needs to publish on a schedule without a person in the loop is fighting the architecture. The cron scripts exist, but the approval step sits upstream of them, so unattended publishing is not what this graph is built for.
Second, the review surface is external. Approval happens in Agent Inbox or by inspecting LangSmith traces. If your team lives in Slack, the Slack integration described in the README is oriented toward ingesting channel data and sending updates, and the Slack code is a separate Python package with its own dependencies. There is no documented Slack approval button.
Third, the repository is a template wearing a project's clothes. package.json names it example-graph, version 0.0.1, private true, with the author field still set to "Your Name". No releases have been retrieved. The last push was on 2026-09-18, so the code is current, but currency is not the same as a stable interface. If you need a dependency you can upgrade on a predictable cadence, this is not that.
Compared with wiring n8n nodes together
The obvious alternative for the same job is a visual automation tool such as n8n, where you chain an HTTP node, an LLM node, and a Slack or Twitter node, then add an approval step. The difference in approach is where the state lives. In n8n, the workflow is a graph of nodes configured in a UI, and the run state is managed by the automation platform. Here, the graph is TypeScript in src/, the run state is managed by LangGraph, and the interrupt is a first-class part of the execution model rather than a wait node.
That matters if you want to version the prompt and the control flow in git alongside your application code, which is the reason to pick this repository over a visual builder. It also matters in the other direction: a visual builder lets a non-engineer change the approval routing, and this does not. The README does document a Customization section covering Prompts and Post Style, so prompt and tone changes are expected edits, but the routing logic is code.
Licence, maintenance, and what upgrading costs
The repository is MIT licensed, and package.json also declares MIT. MIT permits commercial use and modification with the copyright notice retained. Nothing here suggests a dual licence or a hosted-service restriction. This is not legal advice; check the LICENSE file in the repository before you ship.
There are no retrieved releases, so upgrades happen by pulling from main. That has a concrete cost: the LangGraph CLI is invoked through npx, which resolves the latest @langchain/langgraph-cli at run time, and the README notes the first run or a new CLI version triggers an install prompt. Your runtime dependency can therefore change without a commit in your repository. The Python sidecar pins its own constraints for starlette, urllib3, and cryptography with comments citing specific CVEs, which suggests the maintainers track upstream advisories there, but the TypeScript side has no equivalent visible pinning in the README or package.json. If you deploy this, pin the CLI version yourself rather than relying on npx resolution.
Editorial conclusion
Adopt it if you already run LangGraph and want a review gate between scraping and publishing, and you are willing to hold Anthropic, LangSmith, FireCrawl, Arcade and Supabase keys. Do not adopt it if you want a hosted scheduler or an OAuth flow you control without Arcade. Verify first that .env.quickstart.example covers your target platform, because posting to LinkedIn as an organization needs POST_TO_LINKEDIN_ORGANIZATION and LINKEDIN_ORGANIZATION_ID set beyond the quickstart variables.
Frequently asked questions
What is langchain-ai/social-media-agent?
It is a TypeScript LangGraph agent that takes a URL, generates a Twitter and LinkedIn post from its content, and uses a human-in-the-loop flow so a person can edit or accept or reject the draft before it is published.
How do I get langchain-ai/social-media-agent running?
Clone the repository, run yarn install, copy .env.quickstart.example to .env, fill in the Anthropic, LangSmith, FireCrawl and Arcade keys, install the LangGraph CLI with pip, start the server with yarn langgraph:in_mem:up, then run yarn generate_post.
Does langchain-ai/social-media-agent post automatically without review?
No. The README describes a human-in-the-loop flow where the user can make changes or accept or reject the generated post, and the output is inspected in Agent Inbox or LangSmith before anything is published.
What extra services does the full setup of langchain-ai/social-media-agent require?
Beyond the quickstart keys, the README lists Google Vertex AI for YouTube content, Twitter and LinkedIn developer accounts, a GitHub personal access token, Supabase for storing images, and an optional Slack developer account.
Can langchain-ai/social-media-agent post to LinkedIn as a company page?
Yes, if you set POST_TO_LINKEDIN_ORGANIZATION to true and provide LINKEDIN_ORGANIZATION_ID, which the README says you can find in the URL of the company page while logged in as an admin.
Community notes