Postzik MCP server
Let Claude, Codex, Cursor and any other MCP client schedule and publish your social posts. Ask in plain words, for example:
Schedule this video to my YouTube and TikTok for tomorrow 9am Tokyo time: https://cdn.example.com/launch.mp4. Title "We're live", and write a short caption for each.
The assistant lists your connected accounts, creates the posts and can check later whether they went live.
| Server URL | https://postzik.com/api/mcp (self-hosted: https://your-domain/api/mcp) |
| Transport | Streamable HTTP |
| Auth | Sign in with your Postzik account (OAuth 2.1), or an API key in the Authorization header |
1. Before you start
Sign in to Postzik and connect your social accounts on the Channels page.
There are two ways to connect a client:
- Sign in (recommended). Add the server URL and the client opens a Postzik window where you approve it. There's no key to copy or leak, access refreshes on its own, and you can disconnect the app on the Developers page. Claude (web, desktop and mobile), ChatGPT, Claude Code, Cursor and VS Code all work this way.
- API key. For clients that can't sign in, scripts, and servers. Open Developers → Create key and copy the
key (
pzk_…, shown once). Send it only in a header:Authorization: Bearer pzk_…. Postzik never accepts keys in the URL, because URLs end up in logs and browser history.
The Developers page shows ready-to-paste setup for each client.
2. Add Postzik to your client
Replace postzik.com with your domain if you self-host.
Claude (claude.ai web, desktop and mobile)
- Go to Customize → Connectors (older layouts: Settings → Connectors) and click Add custom connector.
- Name:
Postzik. URL:https://postzik.com/api/mcp. Leave the OAuth client ID and secret empty. - Click Add, then Connect. Approve Postzik in the window that opens.
- In a chat, turn Postzik on from the + menu → Connectors.
On Team and Enterprise plans an Owner adds the connector under Organization settings → Connectors, and each member then clicks Connect and signs in with their own Postzik account. Connectors added on claude.ai also appear in Claude Desktop and the mobile apps.
Claude's Request headers option (in beta for some organizations) also works: choose No sign-in and add the header
authorizationwith the valueBearer pzk_YOUR_KEY. Every member of the organization then posts as the key's owner, so prefer signing in.
ChatGPT
Custom MCP apps need Developer mode, which is available on paid plans on the web.
- Open Settings → Apps → Advanced settings and turn on Developer mode.
- Click Create app (named Create on the Connectors page in some versions). Name:
Postzik. MCP server URL:https://postzik.com/api/mcp. Authentication: OAuth. Leave the client ID and secret empty. - Click Create, then sign in and approve Postzik.
- In a chat, choose Developer mode from the + menu, turn Postzik on, and mention it by name ("use Postzik to…").
Menu names in ChatGPT change often; the server URL and OAuth are what matter.
Claude Code
claude mcp add --transport http postzik https://postzik.com/api/mcp
Then type /mcp inside Claude Code, pick postzik and choose Authenticate. Your browser opens to approve it.
Add --scope user to use it in every project.
With an API key instead (for example on a server without a browser):
claude mcp add --transport http postzik https://postzik.com/api/mcp \
--header "Authorization: Bearer pzk_YOUR_KEY"
Codex (CLI and IDE extension)
Put your key in an environment variable so it stays out of config files:
export POSTZIK_API_KEY="pzk_YOUR_KEY"
codex mcp add postzik --url https://postzik.com/api/mcp --bearer-token-env-var POSTZIK_API_KEY
Or edit ~/.codex/config.toml yourself:
[mcp_servers.postzik]
url = "https://postzik.com/api/mcp"
bearer_token_env_var = "POSTZIK_API_KEY"
Check it with codex mcp list, or /mcp in a Codex session.
Cursor
~/.cursor/mcp.json (every project) or .cursor/mcp.json (one project):
{
"mcpServers": {
"postzik": { "url": "https://postzik.com/api/mcp" }
}
}
Open Cursor Settings → MCP, click Connect next to Postzik and approve it. Postzik should then show a green dot
and 8 tools. To use an API key instead, add "headers": { "Authorization": "Bearer pzk_YOUR_KEY" }.
VS Code (GitHub Copilot)
.vscode/mcp.json with just the URL signs in with OAuth:
{
"servers": {
"postzik": { "type": "http", "url": "https://postzik.com/api/mcp" }
}
}
Or with an API key, which VS Code asks for once and stores securely:
{
"inputs": [
{ "type": "promptString", "id": "postzik-key", "description": "Postzik API key", "password": true }
],
"servers": {
"postzik": {
"type": "http",
"url": "https://postzik.com/api/mcp",
"headers": { "Authorization": "Bearer ${input:postzik-key}" }
}
}
}
Windsurf
~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"postzik": {
"serverUrl": "https://postzik.com/api/mcp",
"headers": { "Authorization": "Bearer pzk_YOUR_KEY" }
}
}
}
Gemini CLI
~/.gemini/settings.json:
{
"mcpServers": {
"postzik": {
"httpUrl": "https://postzik.com/api/mcp",
"headers": { "Authorization": "Bearer pzk_YOUR_KEY" }
}
}
}
Other clients
Any client that supports Streamable HTTP and MCP authorization only needs the URL https://postzik.com/api/mcp: it
finds the sign-in details on its own. Clients without OAuth send the Authorization: Bearer pzk_… header.
Clients that only run local (stdio) servers
Bridge to the remote server with mcp-remote (needs Node.js 18+).
npx -y mcp-remote https://postzik.com/api/mcp signs in through your browser. With an API key:
{
"mcpServers": {
"postzik": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://postzik.com/api/mcp", "--header", "Authorization:${POSTZIK_AUTH}"],
"env": { "POSTZIK_AUTH": "Bearer pzk_YOUR_KEY" }
}
}
}
The ${POSTZIK_AUTH} indirection avoids a space inside args, which some clients split incorrectly.
3. Try it
Ask your assistant:
- "Which social accounts do I have in Postzik?"
- "Schedule this video to all of Overfit Uncle's channels for Friday 6pm." (uses your brands)
- "How many Postzik credits do I have?"
- "Post https://cdn.example.com/clip.mp4 to my TikTok now with the caption 'Behind the scenes'."
- "What did I schedule for next week? Move Wednesday's post to Thursday at the same time."
- "Did yesterday's posts go live? Retry any that failed."
Assistants ask before using tools that change things, unless you've allowed them to run without asking.
Tools
| Tool | What it does | Changes anything? |
|---|---|---|
get_balance | Credit balance and price per post | No |
list_accounts | Connected accounts, their ids and the brand each belongs to | No |
list_brands | Your brands and their accounts | No |
create_post | Create, schedule or publish now: one post per account, or every account in a brand. Supports per-account targets, platform options, draft, and an idempotency_key | Yes (costs credits when published) |
list_posts | Posts filtered by status and time, with paging | No |
get_post | One post: status, live link or failure reason | No |
update_post | Edit or reschedule a draft, scheduled or failed post | Yes |
publish_post | Publish now, or retry a failed post | Yes (costs credits) |
delete_post | Cancel and delete a post that isn't publishing | Yes |
Fields and options are the same as in the REST API: media_url is required, scheduled_at is ISO 8601
with a timezone, and leaving it out publishes now. Each tool returns JSON as text and as structuredContent. Problems
(an unknown account, too few credits) come back as tool errors with a plain message the assistant can act on.
Brands
If you manage several brands or clients, group their channels on the Channels page (optional). Then you can say "post to Overfit Uncle" and the assistant posts to exactly that brand's channels, even when each platform names the account differently (Overfit Uncle on YouTube, @overfit.uncle on Instagram). Without brands, the assistant matches accounts by name and asks you when it isn't sure.
Credits: 1 credit per post per account, charged when the post is sent and refunded if it fails. Drafts, reads and edits are free. Buy credits on the Pricing page.
Troubleshooting
| Problem | Fix |
|---|---|
401 or "invalid or has been revoked" | Signed in: disconnect and connect again from the app. API key: create a new key on the Developers page and update the client |
| Client shows 0 tools | Make sure the URL is exactly https://postzik.com/api/mcp |
| "Can't connect this app" on the Postzik page | The app sent an address it didn't register. Remove Postzik from the app and add it again |
| "isn't connected to your Postzik account" | Connect the account on the Channels page, then ask the assistant to list accounts again |
| "Not enough credits" | Buy credits on the Pricing page |
Post stuck on publishing | The network is still processing (videos can take minutes). Ask the assistant to check again later |
| Claude Code asks you to sign in, but you meant to use a key | The header is missing: remove the server and add it again with --header |
Test the server on its own with the MCP Inspector:
npx @modelcontextprotocol/inspector
Choose Streamable HTTP, enter the server URL, and either use Open Auth Settings to sign in or add the
Authorization header.
Security
- A signed-in app or an API key can do anything your account can do through the API: create, change and delete posts and spend credits. Neither can connect or disconnect social accounts, change billing or see other users' data.
- The approval screen shows where Postzik will send you back to. Apps from a verified domain (such as claude.ai and chatgpt.com) are labeled; for others, only approve if you started the connection yourself.
- Disconnect apps and revoke keys you no longer use on the Developers page. Both stop working immediately.
- Keys go in headers only. Postzik never reads credentials from the URL.
Technical details
- Protocol versions
2025-06-18,2025-03-26and2024-11-05. - Stateless Streamable HTTP: every
POSTgets a JSON response; there's no session and noGETstream (it returns405). Batched JSON-RPC requests are accepted. - The server only offers tools (no resources or prompts) and shares rate limits with the REST API (120 requests per minute per key or signed-in app by default).
- Authorization follows the MCP authorization spec. An unauthenticated request gets
401withWWW-Authenticate: Bearer resource_metadata="https://postzik.com/.well-known/oauth-protected-resource/api/mcp".- Protected resource metadata (RFC 9728) at that URL and at
/.well-known/oauth-protected-resource; the resource ishttps://postzik.com/api/mcp. - Authorization server metadata (RFC 8414) at
/.well-known/oauth-authorization-server. - Authorization code flow with PKCE (
S256only), resource indicators (RFC 8707) andissin every authorization response (RFC 9207). - Clients register with a Client ID Metadata Document (an
httpsclient id) or Dynamic Client Registration (RFC 7591) at/api/oauth/register. All clients are public (token_endpoint_auth_method: none). Loopback redirects match on any port. - Access tokens last 1 hour. Refresh tokens last 60 days and rotate on every use; reusing an old one disconnects the
app. Token revocation (RFC 7009) is at
/api/oauth/revoke.
- Protected resource metadata (RFC 9728) at that URL and at