SocialKit speaks MCP, returns structured JSON, and is designed to live inside a loop. Score, rewrite, regrade, ship. No prompt gymnastics, no JSON-mode bandaids.
One HTTP endpoint, bearer auth, every SocialKit capability exposed as a tool. Drop the config into any MCP-aware client.
# ~/.claude/config.json
{
"mcpServers": {
"socialkit": {
"url": "https://mcp.socialkit.sh",
"auth": { "type": "bearer", "token": "$SOCIALKIT_KEY" }
}
}
}# ~/.cursor/mcp.json
{
"mcpServers": {
"socialkit": {
"type": "http",
"url": "https://mcp.socialkit.sh",
"headers": { "Authorization": "Bearer $SOCIALKIT_KEY" }
}
}
}curl https://mcp.socialkit.sh/tools/list \
-H "Authorization: Bearer $SOCIALKIT_KEY"
# tools: score_post, rewrite_post,
# generate_post, plan_week,
# build_voice, create_post,
# schedule_post, cancel_post,
# list_posts, get_post,
# get_calendar, list_brands,
# list_voices, list_channelsscore_postGrade a post 0-100 with a per-dimension breakdown.rewrite_postVoice-preserving rewrite that returns before/after scores.generate_postGenerate 1-3 scored drafts from a brief, ranked best-first.plan_weekTurn a brief into a sequenced content plan.build_voiceDistill a reusable voice from sample posts; pass its id to generate/plan.create_postSave a draft so it can be scheduled or published; returns its id.schedule_postSchedule a saved draft to publish at a future time.cancel_postCancel a scheduled post so it won't publish.list_postsList posts newest-first, filter by status, paginated.get_postFetch a single post by id with its current status and text.get_calendarSee scheduled and published posts within a time window.list_brandsDiscover brand ids to ground generation and posts.list_voicesDiscover saved voice ids to write in a distilled voice.list_channelsDiscover connected channel ids to bind posts to.The pattern that actually works: let your model draft freely, then use SocialKit as the judge and the rewriter. Three attempts is usually enough to land 80+.
import Anthropic from "@anthropic-ai/sdk";
const claude = new Anthropic();
// SocialKit is plain JSON over HTTPS. No SDK to install.
async function sk(path: string, body: unknown) {
const res = await fetch(`https://api.socialkit.sh/v1/${path}`, {
method: "POST",
headers: {
"content-type": "application/json",
authorization: `Bearer ${process.env.SOCIALKIT_KEY}`,
},
body: JSON.stringify(body),
});
if (!res.ok) throw new Error(`socialkit ${path}: ${res.status}`);
return res.json();
}
async function draftAndGrade(brief: string) {
let draft = await claude.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 800,
messages: [{ role: "user", content: `Write a LinkedIn post: ${brief}` }],
}).then(r => r.content[0].text);
for (let attempt = 0; attempt < 3; attempt++) {
const grade = await sk("score", { post: draft });
if (grade.overall >= 80) return { draft, grade };
const { rewrite, after } = await sk("rewrite", { post: draft });
draft = rewrite;
if (after.overall >= 80) return { draft, grade: after };
}
return { draft, grade: await sk("score", { post: draft }) };
}Your model writes from a brief. No scoring constraints.
/v1/score returns 0–100 with ranked signals.
/v1/rewrite fixes weak dimensions, keeps the voice, returns before and after.
Loop until score ≥ target or max attempts. Return both.
One model, two jobs, grounded both times. The edge isn't a secret ranker. It's what the grader is told before it grades.
The grader is Claude Sonnet run as a judge, with forced tool use so every score comes back as typed JSON, not prose. It does not free-associate. It scores against a written evidence base of how the feed actually ranks.
Claude Sonnet also writes the drafts and the rewrites. It's the best public model at voice mimicry and tight first-person prose. Different prompt, different priors.
Where this goes next: a calibrated ranker trained on real outcomes, scoring dwell and reshare likelihood directly. That's on the roadmap, not in the box yet. We'd rather tell you what runs today than ship a number we can't stand behind.
We can route grading to your own judge or your own ranker. Tell us what you're optimizing for.