Real code: a Claude agent that researches a topic, drafts a post, and publishes it to LinkedIn — fully automated.
linkedin_create_post tool to publish — all in one agentic loop.
npm init -y
npm install @anthropic-ai/sdk @modelcontextprotocol/sdk
Create linkedin-agent.mjs:
import Anthropic from '@anthropic-ai/sdk';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
const SQUAREMCP_URL = 'https://hermes.squaremcp.com/mcp';
const SQUAREMCP_TOKEN = process.env.SQUAREMCP_TOKEN; // your Bearer token
const topic = process.argv[2] ?? 'AI trends in 2026';
// ── 1. Connect to SquareMCP ──────────────────────────────────────
const transport = new StreamableHTTPClientTransport(new URL(SQUAREMCP_URL), {
requestInit: { headers: { Authorization: `Bearer ${SQUAREMCP_TOKEN}` } },
});
const mcpClient = new Client({ name: 'linkedin-agent', version: '1.0.0' });
await mcpClient.connect(transport);
// Fetch available tools from SquareMCP
const { tools: mcpTools } = await mcpClient.listTools();
// Convert MCP tool descriptors to Anthropic tool format
const anthropicTools = mcpTools.map(t => ({
name: t.name,
description: t.description,
input_schema: t.inputSchema,
}));
// ── 2. Run the agentic loop ──────────────────────────────────────
const anthropic = new Anthropic();
const messages = [
{
role: 'user',
content: `You are a LinkedIn content strategist. Your job:
1. Think about the topic: "${topic}"
2. Draft a compelling LinkedIn post (150-250 words, professional tone, 3-5 hashtags)
3. Call linkedin_create_post to publish it
4. Report back what was posted.
Write the post now and publish it.`,
},
];
console.log(`\n🤖 Agent starting — topic: "${topic}"\n`);
while (true) {
const response = await anthropic.messages.create({
model: 'claude-opus-4-7',
max_tokens: 1024,
tools: anthropicTools,
messages,
});
// Append assistant turn
messages.push({ role: 'assistant', content: response.content });
if (response.stop_reason === 'end_turn') {
const text = response.content
.filter(b => b.type === 'text')
.map(b => b.text)
.join('\n');
console.log('\n✅ Agent finished:\n', text);
break;
}
if (response.stop_reason !== 'tool_use') break;
// Execute each tool call against SquareMCP
const toolResults = [];
for (const block of response.content) {
if (block.type !== 'tool_use') continue;
console.log(`🔧 Calling ${block.name}...`);
let result;
try {
result = await mcpClient.callTool({ name: block.name, arguments: block.input });
console.log(` ✓ ${JSON.stringify(result.content[0]).slice(0, 120)}...`);
} catch (err) {
result = { content: [{ type: 'text', text: `Error: ${err.message}` }] };
console.error(` ✗ ${err.message}`);
}
toolResults.push({
type: 'tool_result',
tool_use_id: block.id,
content: result.content,
});
}
messages.push({ role: 'user', content: toolResults });
}
await mcpClient.close();
export ANTHROPIC_API_KEY=sk-ant-...
export SQUAREMCP_TOKEN=your-bearer-token-here
node linkedin-agent.mjs "The future of AI agents in enterprise software"
Expected output:
🤖 Agent starting — topic: "The future of AI agents in enterprise software"
🔧 Calling linkedin_create_post...
✓ {"id":"urn:li:share:7194...","success":true}...
✅ Agent finished:
I've published the following LinkedIn post:
"Enterprise software is undergoing a quiet revolution..."
[full post text]
The post has been published successfully to your LinkedIn feed.
Now that you have the agentic loop working, you can extend it:
// Replace the user message with:
content: `Draft a post about "${topic}" and publish it on both
LinkedIn (professional tone) and Twitter (punchy, max 280 chars, 2 hashtags).
Use linkedin_create_post and twitter_create_tweet.`
# Post every weekday at 9am
0 9 * * 1-5 SQUAREMCP_TOKEN=... ANTHROPIC_API_KEY=... \
node /path/to/linkedin-agent.mjs "$(cat /path/to/topics.txt | shuf -n1)"
Configure a webhook in the SquareMCP dashboard. When a WhatsApp message arrives, SquareMCP POSTs to your server. Run the same agent loop but start with the inbound message as context:
import express from 'express';
import crypto from 'crypto';
const app = express();
app.use(express.json());
app.post('/webhook', async (req, res) => {
// Verify signature
const sig = req.headers['x-squaremcp-signature'];
const expected = `sha256=${crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(JSON.stringify(req.body))
.digest('hex')}`;
if (sig !== expected) { res.status(401).end(); return; }
res.status(200).end(); // acknowledge immediately
const { platform, data } = req.body;
console.log(`Inbound from ${platform}: ${data.text}`);
// Run agent in background...
runAgent(data).catch(console.error);
});
app.listen(3000);