MCP access
Run PostForge from the tools you already use.
PostForge speaks MCP. Connect Claude Code or another MCP client with a scoped token and drive the same workflow (sourcing, drafting, review, and scheduling) from your assistant.
Tokens act as you. Review rules and post limits apply.
Connect in three steps
- 1
Create a scoped token
Settings → MCP access. Choose full access, draft only, or read-only. The token is shown once.
- 2
Add the endpoint to your client
Send requests to
https://thepostforge.ai/mcpwith anAuthorization: Bearer <token>header.A client that cannot set a header connects with OAuth instead: it reads the endpoint's 401, registers itself, and asks you to approve a scope on a consent page. That produces the same kind of token, listed and revocable in the same place.
https://thepostforge.ai/mcp{ "mcpServers": { "postforge": { "type": "http", "url": "https://thepostforge.ai/mcp", "headers": { "Authorization": "Bearer <your-token>" } } } }Settings generates the same config with your real token.
- 3
Ask for the work
Your client sees the tools below. It can start runs, pick a source, draft, and (with full access) approve. Every step keeps the rules you set in the app.
What stays true
- The token acts as you, within its scope.
- Revoking a token is immediate; that client's calls fail with 401.
- The same review rules, validation checks, and post limits apply.
- Nothing publishes outside the approval rules you set in the app.
What the tools cover
25 tools, grouped by the part of the workflow they touch. Expand a row for its input schema. Descriptions are the text your client shows the model.
Sources 3
discover_sources_for_briefFind source articles that serve an expertise brief.{ "properties": { "expertise_brief": { "additionalProperties": true, "title": "Expertise Brief", "type": "object" } }, "required": [ "expertise_brief" ], "title": "discover_sources_for_briefArguments", "type": "object" }list_candidatesArticle candidates for a run paused at article selection.{ "properties": { "run_id": { "title": "Run Id", "type": "string" } }, "required": [ "run_id" ], "title": "list_candidatesArguments", "type": "object" }select_sourceChoose the article a paused run will draft from.{ "properties": { "run_id": { "title": "Run Id", "type": "string" }, "candidate_id": { "title": "Candidate Id", "type": "string" }, "perspective": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Perspective" }, "template_slug": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Template Slug" } }, "required": [ "run_id", "candidate_id" ], "title": "select_sourceArguments", "type": "object" }
Drafting 6
cancel_runCancel a run and free the single-active-run slot.{ "properties": { "run_id": { "title": "Run Id", "type": "string" } }, "required": [ "run_id" ], "title": "cancel_runArguments", "type": "object" }create_runStart a new LinkedIn post run.{ "properties": { "article_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Article Url" }, "perspective": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Perspective" }, "post_template": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Post Template" }, "generate_image": { "default": false, "title": "Generate Image", "type": "boolean" }, "force_review": { "default": true, "title": "Force Review", "type": "boolean" }, "allow_duplicate": { "default": false, "title": "Allow Duplicate", "type": "boolean" }, "expertise_brief": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Expertise Brief" } }, "title": "create_runArguments", "type": "object" }edit_draftOffer the user an edit form for a parked draft (pop-up where supported).{ "properties": { "run_id": { "title": "Run Id", "type": "string" } }, "required": [ "run_id" ], "title": "edit_draftArguments", "type": "object" }get_draft_optionsShaping context for a new run: voice profile, templates, takes, brief.{ "properties": {}, "title": "get_draft_optionsArguments", "type": "object" }get_runRead a run: your active one, or a specific one by id.{ "properties": { "run_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Run Id" } }, "title": "get_runArguments", "type": "object" }suggest_takesThree article-derived angles for the user to choose from.{ "properties": { "article_url": { "title": "Article Url", "type": "string" } }, "required": [ "article_url" ], "title": "suggest_takesArguments", "type": "object" }
Review 2
approve_draftApprove a draft parked at awaiting_approval — the publish action.{ "properties": { "run_id": { "title": "Run Id", "type": "string" }, "edited_body": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Edited Body" }, "include_image": { "default": true, "title": "Include Image", "type": "boolean" }, "publish_mode": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Publish Mode" }, "publish_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Publish At" }, "save_as_sample": { "default": false, "title": "Save As Sample", "type": "boolean" } }, "required": [ "run_id" ], "title": "approve_draftArguments", "type": "object" }check_claimsCheck the parked draft's claims against its selected source.{ "properties": { "run_id": { "title": "Run Id", "type": "string" }, "draft_body": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Draft Body" } }, "required": [ "run_id" ], "title": "check_claimsArguments", "type": "object" }
Images 2
generate_imageGenerate (first time) or regenerate the run's accompanying image.{ "properties": { "run_id": { "title": "Run Id", "type": "string" } }, "required": [ "run_id" ], "title": "generate_imageArguments", "type": "object" }get_imageFetch the run's generated image to show it to the user.{ "properties": { "run_id": { "title": "Run Id", "type": "string" } }, "required": [ "run_id" ], "title": "get_imageArguments", "type": "object" }
Voice 10
activate_voiceMake a profile the tenant's active voice — global, immediate change.{ "properties": { "profile_id": { "title": "Profile Id", "type": "string" } }, "required": [ "profile_id" ], "title": "activate_voiceArguments", "type": "object" }add_writing_sampleAdd one writing sample — the user's own writing, not instructions.{ "properties": { "profile_id": { "title": "Profile Id", "type": "string" }, "text": { "maxLength": 8000, "minLength": 100, "title": "Text", "type": "string" }, "sample_kind": { "default": "linkedin_post", "enum": [ "linkedin_post", "article", "comment", "other" ], "title": "Sample Kind", "type": "string" }, "user_label": { "anyOf": [ { "maxLength": 120, "type": "string" }, { "type": "null" } ], "default": null, "title": "User Label" }, "is_pinned": { "default": false, "title": "Is Pinned", "type": "boolean" } }, "required": [ "profile_id", "text" ], "title": "add_writing_sampleArguments", "type": "object" }analyze_voiceRun (or re-run) voice analysis over the profile's active samples.{ "properties": { "profile_id": { "title": "Profile Id", "type": "string" } }, "required": [ "profile_id" ], "title": "analyze_voiceArguments", "type": "object" }create_voice_profileCreate a voice profile.{ "$defs": { "EditorialPreferencesIn": { "properties": { "allow_parentheses": { "default": false, "title": "Allow Parentheses", "type": "boolean" }, "allow_dashes": { "default": false, "title": "Allow Dashes", "type": "boolean" }, "hashtag_mode": { "default": "required", "enum": [ "required", "optional", "none" ], "title": "Hashtag Mode", "type": "string" }, "paragraph_style": { "default": "flowing", "enum": [ "flowing", "line_breaks" ], "title": "Paragraph Style", "type": "string" }, "structure_mode": { "default": "guided", "enum": [ "guided", "free" ], "title": "Structure Mode", "type": "string" }, "closing_style": { "default": "either", "enum": [ "either", "question", "statement" ], "title": "Closing Style", "type": "string" } }, "title": "EditorialPreferencesIn", "type": "object" } }, "properties": { "name": { "maxLength": 80, "minLength": 1, "title": "Name", "type": "string" }, "source_type": { "default": "manual", "enum": [ "preset", "manual", "samples" ], "title": "Source Type", "type": "string" }, "preset_key": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Preset Key" }, "explicit_user_instructions": { "anyOf": [ { "maxLength": 1000, "type": "string" }, { "type": "null" } ], "default": null, "title": "Explicit User Instructions" }, "do_not_use_instructions": { "anyOf": [ { "maxLength": 1000, "type": "string" }, { "type": "null" } ], "default": null, "title": "Do Not Use Instructions" }, "editorial_preferences": { "anyOf": [ { "$ref": "#/$defs/EditorialPreferencesIn" }, { "type": "null" } ], "default": null } }, "required": [ "name" ], "title": "create_voice_profileArguments", "type": "object" }delete_voice_profileDelete a voice profile, its samples, and its analysis history.{ "properties": { "profile_id": { "title": "Profile Id", "type": "string" } }, "required": [ "profile_id" ], "title": "delete_voice_profileArguments", "type": "object" }delete_writing_sampleDelete one writing sample. Permanent — there is no restore.{ "properties": { "sample_id": { "title": "Sample Id", "type": "string" } }, "required": [ "sample_id" ], "title": "delete_writing_sampleArguments", "type": "object" }get_voice_profileOne voice profile in full: fields, samples, latest analysis.{ "properties": { "profile_id": { "title": "Profile Id", "type": "string" } }, "required": [ "profile_id" ], "title": "get_voice_profileArguments", "type": "object" }list_voice_profilesAll voice profiles for the tenant, newest first.{ "properties": {}, "title": "list_voice_profilesArguments", "type": "object" }update_voice_profileUpdate a voice profile — patch semantics: only the passed fields change.{ "$defs": { "EditorialPreferencesIn": { "properties": { "allow_parentheses": { "default": false, "title": "Allow Parentheses", "type": "boolean" }, "allow_dashes": { "default": false, "title": "Allow Dashes", "type": "boolean" }, "hashtag_mode": { "default": "required", "enum": [ "required", "optional", "none" ], "title": "Hashtag Mode", "type": "string" }, "paragraph_style": { "default": "flowing", "enum": [ "flowing", "line_breaks" ], "title": "Paragraph Style", "type": "string" }, "structure_mode": { "default": "guided", "enum": [ "guided", "free" ], "title": "Structure Mode", "type": "string" }, "closing_style": { "default": "either", "enum": [ "either", "question", "statement" ], "title": "Closing Style", "type": "string" } }, "title": "EditorialPreferencesIn", "type": "object" } }, "properties": { "profile_id": { "title": "Profile Id", "type": "string" }, "name": { "anyOf": [ { "maxLength": 80, "minLength": 1, "type": "string" }, { "type": "null" } ], "default": null, "title": "Name" }, "explicit_user_instructions": { "anyOf": [ { "maxLength": 1000, "type": "string" }, { "type": "null" } ], "default": null, "title": "Explicit User Instructions" }, "do_not_use_instructions": { "anyOf": [ { "maxLength": 1000, "type": "string" }, { "type": "null" } ], "default": null, "title": "Do Not Use Instructions" }, "generated_style_guide": { "anyOf": [ { "maxLength": 4000, "type": "string" }, { "type": "null" } ], "default": null, "title": "Generated Style Guide" }, "status": { "anyOf": [ { "enum": [ "draft", "archived" ], "type": "string" }, { "type": "null" } ], "default": null, "title": "Status" }, "example_selection_strategy": { "anyOf": [ { "enum": [ "pinned_first", "recent_first" ], "type": "string" }, { "type": "null" } ], "default": null, "title": "Example Selection Strategy" }, "editorial_preferences": { "anyOf": [ { "$ref": "#/$defs/EditorialPreferencesIn" }, { "type": "null" } ], "default": null } }, "required": [ "profile_id" ], "title": "update_voice_profileArguments", "type": "object" }update_writing_sampleUpdate one writing sample — patch semantics: only passed fields change.{ "properties": { "sample_id": { "title": "Sample Id", "type": "string" }, "user_label": { "anyOf": [ { "maxLength": 120, "type": "string" }, { "type": "null" } ], "default": null, "title": "User Label" }, "is_pinned": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "default": null, "title": "Is Pinned" }, "is_active": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "default": null, "title": "Is Active" } }, "required": [ "sample_id" ], "title": "update_writing_sampleArguments", "type": "object" }
Schedule 2
get_scheduleThe tenant's recurring publishing schedule (daily/weekdays/weekly).{ "properties": {}, "title": "get_scheduleArguments", "type": "object" }set_scheduleCreate or replace the tenant's recurring publishing schedule.{ "properties": { "enabled": { "title": "Enabled", "type": "boolean" }, "frequency": { "enum": [ "daily", "weekdays", "weekly" ], "title": "Frequency", "type": "string" }, "hour": { "maximum": 23, "minimum": 0, "title": "Hour", "type": "integer" }, "minute": { "maximum": 59, "minimum": 0, "title": "Minute", "type": "integer" }, "day_of_week": { "anyOf": [ { "maximum": 6, "minimum": 0, "type": "integer" }, { "type": "null" } ], "default": null, "title": "Day Of Week" }, "days_of_week": { "anyOf": [ { "items": { "type": "integer" }, "type": "array" }, { "type": "null" } ], "default": null, "title": "Days Of Week" }, "end_hour": { "anyOf": [ { "maximum": 23, "minimum": 0, "type": "integer" }, { "type": "null" } ], "default": null, "title": "End Hour" }, "end_minute": { "anyOf": [ { "maximum": 59, "minimum": 0, "type": "integer" }, { "type": "null" } ], "default": null, "title": "End Minute" }, "confirmation_email_enabled": { "default": false, "title": "Confirmation Email Enabled", "type": "boolean" }, "generate_image": { "default": false, "title": "Generate Image", "type": "boolean" }, "target_platforms": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "default": null, "title": "Target Platforms" } }, "required": [ "enabled", "frequency", "hour", "minute" ], "title": "set_scheduleArguments", "type": "object" }
A token's scope can be narrower than this list: read-only covers the read tools, draft only adds creation, and approval tools need full access.