LinkAssist LogoLinkAssistDocs

MCP tools reference

Every LinkAssist MCP tool, its inputs and results, and the rules for using them. Written for AI assistants and developers.

This page is the complete reference for the LinkAssist MCP server. It is written for the AI assistant (ChatGPT, Claude, Cursor or any MCP client) that is connected to a user's LinkAssist account, and for developers. For the setup guide, see Use LinkAssist in ChatGPT, Claude & Cursor (MCP).

Machine-readable copies:

  • This page as markdown: https://help.linkassist.ai/docs/features/mcp-tools.md
  • Every help page in one file: https://help.linkassist.ai/llms-full.txt
  • Index of all pages: https://help.linkassist.ai/llms.txt

Server

URLhttps://app.linkassist.ai/api/mcp
TransportStreamable HTTP (stateless, JSON responses)
AuthOAuth 2.1 with PKCE (S256) and Dynamic Client Registration. The user logs in to LinkAssist and presses Connect
Access token1 hour; refresh token 60 days, rotated on every refresh
PlansTrial, Starter, Growth, Enterprise
Rate limits120 requests/min per connection; publish_now 10/min per user

Everything the tools return belongs to the connected user. Tools never see another user's data.

Permissions

The Connect button grants all of these. A tool that needs a permission the connection lacks returns an error asking the user to reconnect.

ScopeAllows
profile:readBrand DNA, User DNA, plan usage
profile:writeUpdating the user's User DNA
posts:readPosts, performance, templates, ideas, rule checks
posts:writeWriting, revising and saving drafts, images
posts:scheduleScheduling and cancelling posts
posts:publishPublishing to LinkedIn immediately

Rules for AI assistants

  1. Start with get_my_profile before suggesting or writing posts, so you know the user's voice, audience and pillars.
  2. Prefer generate_post to writing posts yourself. LinkAssist's writer uses the user's User DNA, hook selection and quality checks, and saves the result to their drafts.
  3. If you write or edit post text yourself, run check_post and fix every issue before save_draft or update_draft.
  4. Never use em dashes (—) or en dashes (–) in post text. Also avoid the banned AI phrases check_post reports.
  5. Never call publish_now without the user's explicit go-ahead on the exact final post. Confirm the time with the user before schedule_post.
  6. Get the user's OK before update_user_dna, and only write things that are true about them.
  7. Tell the user about quota: every new post written or saved uses 1 post from their monthly limit (get_usage shows what's left).

Common workflows

Write a post get_my_profile → generate_post (topic with any details, stories or numbers) → show the post → revise_post with the user's feedback if needed.

Write a post, add an image, schedule it generate_post → create the image in your own tool → attach_image (or get_image_upload_link if you can't pass it) → get_usage for the timezone → confirm the time → schedule_post.

Publish now Show the final post → user says publish → publish_now with confirm: true → it goes live in about 30 seconds. If the user changes their mind, call cancel_schedule inside that window. Check get_post afterwards for the LinkedIn link.

Plan the week get_my_profile → get_post_performance (top) → list_posts (scheduled) → get_content_ideas → suggest 3 to 5 posts → generate_post for the ones the user picks.

Improve the user's User DNA get_user_dna → propose changes based on what you know about the user → get their OK → update_user_dna → if they want it back, call update_user_dna again with the previous values it returned.


Tools

Profile and account

get_my_profile

Read. The user's Brand DNA as LinkAssist's writer sees it: identity, professional background, strategy, voice, performance summary and how complete their profile is.

No inputs.

get_usage

Read. Plan, status, posts used / limit / remaining this month, AI image usage, purchased credits, trial end date and the user's timezone (IANA name, e.g. Asia/Kolkata).

No inputs.

get_user_dna

Read. The user's editable User DNA fields (topics as an array), completeness score (0 to 100), missing checks, scoring (what each check needs, its points and whether it passes), readOnly fields, allowedValues for every enum, and limits for every list. Call it before update_user_dna.

Score checks: a strong opinion (20), proof of work such as a project or achievement (20), a boundary (15), 1 to 3 topics (15), 1 or 2 content types (10: more than 2 means no dominant format and fails), positioning (10), and audience pain points (10). Improve what is weak; don't add content just to raise the score.

No inputs.

update_user_dna

Destructive. Changes any subset of the User DNA fields below. Returns updated (field names), previous (each changed field's old value, for undo), score before/after and what is still missing.

InputTypeNotes
changesobjectOnly the fields to change
listModereplace | appendFor list fields. Default replace

Fields inside changes:

FieldTypeLimits and allowed values
aboutstringWho they are and what they do. Max 1000 chars
writingStylestringHow they write. Max 500 chars
toneenumEducational & casual, Friendly & opinionated, Insightful & professional, Short & crisp, Witty & humorous
primaryGoalenumlead_generation, personal_brand, job_search, authority
topicsstring[]Content pillars, max 3
contentTypesenum[]Personal stories & experiences, Industry insights & opinions, Tips & how-tos, Announcements & updates
opinionsobject[]{ stance, topic?, strength?: mild | moderate | strong }, max 15
knowledgeItemsobject[]{ title, description?, type?, tags? }; type is project, achievement, framework, belief, experience or reference; max 50
expertiseobject{ primaryRole?, domains?[] }
voiceRulesobjectauthorityLevel: peer, mentor, thought-leader, student-sharing; sentenceStyle: short-punchy, flowing-narrative, mixed; complexity: simple, moderate, technical; customVoiceNotes (max 300)
boundariesobject{ avoidTopics?[], avoidStyles?[], customRules? }, 10 items each
positioningobject{ uniqueAngle?, differentiation?, keyMessages?[] }: what they uniquely offer and how they differ. Max 300 chars each, 5 key messages
audienceRolesstring[]Who they write for, max 5
audiencePainPointsstring[]Their audience's problems, max 5
  • List fields (opinions, knowledgeItems, audienceRoles, audiencePainPoints) replace the whole list unless listMode is append.
  • Grouped fields (expertise, voiceRules, boundaries, positioning) keep any part you leave out. Set a part to null to clear it. A list inside a grouped field (for example boundaries.avoidTopics) is replaced whole.
  • To undo, send the previous values back unchanged with listMode: replace. previous lists every part of a grouped field (null where it was empty) and list items keep their isActive and createdAt, so the undo is exact.
  • visualIdentity (brand colours, image style) is read-only here.

Posts

list_posts

Read. The user's posts, newest first (scheduled posts soonest first). Text is cut to 280 characters; use get_post for the full post.

InputTypeNotes
statusdraft | scheduled | published | failedOptional filter
from, toISO dateOptional date range
limit1 to 50Default 20

get_post

Read. One post: full text, images, status, scheduled time, LinkedIn link and performance once published. Input: postId.

get_post_performance

Read. Published posts with views, likes, comments and shares, plus totals.

InputTypeNotes
sortrecent | toptop sorts by views. Default recent
limit1 to 50Default 10

generate_post

Write. Writes a post in the user's voice with LinkAssist's writer and saves it to their drafts (uses 1 post of quota). Takes 20 to 90 seconds. Returns postId, content, hookStyle, framework and any complianceFlags (topics the user said to avoid). If it isn't finished within about 40 seconds you get { status: "running", jobId }: call get_generation_result.

InputTypeNotes
topicstringWhat the post is about, with details, stories or numbers to use. 3 to 2000 chars
postLengthshort | medium | longDefault medium
tonestringe.g. professional, casual, bold
templateId, templateSourcestring, user | trendingFrom list_templates

Fails if the user hasn't finished onboarding, is out of posts, or already has a generation running.

get_generation_result

Write. Waits up to about 40 seconds for a jobId from generate_post or revise_post and returns the finished post. Calling it again for the same job returns the same draft and never uses quota twice. Results are kept for 10 minutes.

revise_post

Write. Rewrites a post with the user's feedback.

InputTypeNotes
feedbackstringWhat to change
postIdstringA draft to revise in place (no extra quota)
contentstringText to revise when there is no draft (saved as a new draft, uses 1 post)
topicstringOptional, when revising content

Pass exactly one of postId or content.

check_post

Read. Checks any post text against LinkAssist's writing rules: em and en dashes, banned AI phrases, hashtag count, hook quality and length. Returns passed, issues (must fix), warnings and wordCount.

InputTypeNotes
contentstringUp to 3000 chars
postLengthshort | medium | longOptional length band to check against

save_draft

Write. Saves text to the user's drafts (uses 1 post of quota). Returns postId and a check_post result. Inputs: content (up to 3000 chars), optional title (100 chars) and postLength.

update_draft

Write. Replaces a draft's content and/or title. Keeps its images and company-page setting. No quota. Drafts only: to edit a scheduled post, cancel_schedule it first.

delete_draft

Destructive. Deletes a draft or failed post. Quota is not refunded. Confirm with the user first.

Templates and ideas

list_templates

Read. The user's own templates (user) and the LinkAssist Library (trending): id, source, name, short description, category.

InputTypeNotes
sourceuser | trending | allDefault all
searchstringMatches name, description and category
limit1 to 100Default 25

get_template

Read. One template's full structure: the skeleton to fill (Library) or the hook/body/CTA pattern (user templates). Inputs: templateId, source.

get_content_ideas

Read. Post ideas LinkAssist researched for the user today. Empty until the user generates ideas in the dashboard that day.

Images

attach_image

Write. Adds an image to a draft or scheduled post. Pass exactly one source:

InputUse it for
imageA file from the conversation, such as an image ChatGPT generated or the user uploaded. ChatGPT fills this in itself (openai/fileParams) as { download_url, file_id, mime_type?, file_name? }
imageUrlA public http(s) link
imageBase64Raw base64 or a data: URL

Sandbox or file paths such as sandbox:/mnt/data/image.png only exist inside the AI app and are refused: pass the file as image instead. PNG, JPEG, WebP or GIF (checked from the file itself), up to 10 MB, 9 images per post. The image is copied into LinkAssist's storage. Returns the post's image list. Free: user images don't use the AI image quota.

remove_image

Destructive. Removes one image. Inputs: postId, imageUrl exactly as get_post returns it.

Write. Returns a link the user opens in their browser to upload images to a post. Valid for 15 minutes, single use, only for the account that owns the post. Use it when you can't pass the image yourself (Claude can't hand chat images to tools).

Scheduling and publishing

schedule_post

Write. Schedules a draft, moves a scheduled post, or reschedules a failed one. No quota.

InputTypeNotes
postIdstring
scheduledAtISO 8601 with offsete.g. 2026-10-01T09:00:00+05:30. At least 1 minute ahead

Returns the time in the user's timezone. LinkAssist runs a risk check first and may hold a risky post as a draft.

cancel_schedule

Write. Moves a scheduled or failed post back to drafts. Also stops a publish_now during its 30 second window.

publish_now

Destructive. Publishes a draft or scheduled post to the user's LinkedIn in about 30 seconds.

InputTypeNotes
postIdstring
confirmtrueOnly after the user explicitly confirmed publishing this exact post now

LinkAssist runs a risk check first. A post that looks risky (for example a damaging claim about a named person or company) is held as a draft and the reasons are returned; tell the user they can publish it from the dashboard after reviewing it.


Resources

URIContent
linkassist://brand-dnaThe user's Brand DNA in the exact form LinkAssist's writer uses
linkassist://writing-rulesThe writing rules every LinkAssist post follows

Prompts

NameArgumentsDoes
write-linkedin-posttopicWrites a post with generate_post, then offers revisions, an image, scheduling or publishing
plan-my-weeknoneSuggests 3 to 5 posts from the user's profile, top posts, schedule and ideas

Errors

Message saysMeaningWhat to do
plan doesn't include AI app connectionsTrial ended or plan inactiveTell the user to upgrade in LinkAssist; no reconnect needed
account is suspendedAccount suspendedTell the user to contact support@linkassist.ai
wasn't granted "…"Connection made before that permission existedAsk the user to reconnect LinkAssist
Post limit reachedMonthly posts used upTell the user; they can upgrade or buy a credit pack
Complete your profile setupOnboarding not finishedAsk the user to finish onboarding in LinkAssist
Generation already in progressAnother post is being writtenWait, then try again
held this post backRisk check blocked schedule or publishShow the reasons; the user reviews it in the dashboard
can only fetch public http(s) image linksA sandbox or file path was sent as imageUrlPass the file as image (ChatGPT) or imageBase64, or use get_image_upload_link
This only works on draft postsWrong post statecancel_schedule first, or pick a draft
HTTP 401Token expired or connection removedThe client refreshes the token, or the user reconnects

On this page