Preferent MCP server

The Preferent MCP server gives an AI app access to one person’s style guide: the writing habits they asked AI to avoid and their reply preferences. This page lists every tool, what it returns and changes, and how apps sign in. For setup steps in each app, see Connect.

Endpoint

The server uses the Streamable HTTP transport at one URL. Every request needs a bearer token: an OAuth access token, or a personal API token.

https://preferent.ai/api/mcp

Authentication

Preferent runs its own OAuth 2.1 authorization server. An app that supports MCP authorization finds it from the WWW-Authenticate header of a 401 response, then signs the person in and asks them to allow access.

  • Protected resource metadata: https://preferent.ai/.well-known/oauth-protected-resource/api/mcp
  • Authorization server metadata: https://preferent.ai/.well-known/oauth-authorization-server
  • Clients register with Dynamic Client Registration at https://preferent.ai/oauth/register, or use a Client ID Metadata Document: an https client_id that serves the client’s metadata.
  • Authorization uses the code flow with PKCE (S256) and a resource indicator for the MCP endpoint.
  • Access tokens last 60 minutes. Refresh tokens last 90 days and rotate on every use; reusing an old refresh token disconnects the app.
  • Apps can revoke tokens at https://preferent.ai/oauth/revoke, and the person can disconnect any app on their account page.

For a script or an app without OAuth, the person creates a personal API token on their account page and sends it as Authorization: Bearer pfr_.... An account can hold 20 active tokens. A personal token has both scopes.

Scopes

  • style-guide:read: Read your Preferent style guide and reply preferences.
  • style-guide:write: Add marks, habits, and preferences to your style guide, and send suggestions to the catalog when you agree to each one.

Every grant includes style-guide:read. Without style-guide:write, the write tools return an error and change nothing.

Tools

Each tool returns one text content item. The list tools and check_text return JSON in that text. Read tools change nothing. Write tools save the style guide as a new version, and the person can open every earlier version in the editor. Sensitive write tools replace or clear data, or send it outside the account.

get_style_guideGet style guide

Class
Read
Scope
style-guide:read
Annotations
readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false

Returns the user's Preferent style guide as plain text: the writing habits they asked AI to avoid, with definitions and examples, and their reply preferences. full has every habit, with its test, two pairs of examples, and an example that is fine as written. compact has priority tiers 1 and 2, with one pair of examples per habit. tiny has the names and one-line definitions of the top habits, in under 1,500 characters.

InputTypeRequiredDescription
size"full" | "compact" | "tiny"No, default "compact"full, compact, or tiny. The default is compact.

list_habitsList habits

Class
Read
Scope
style-guide:read
Annotations
readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false

Returns the habits in the user's style guide in priority order, as JSON: id, name, group, parent id, priority, description, and counts of examples. mark_text, update_habit, and suggest_habit take these ids. list_preferences returns the reply preferences.

This tool takes no input.

list_preferencesList preferences

Class
Read
Scope
style-guide:read
Annotations
readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false

Returns the reply preferences in the user's style guide in priority order, as JSON: id, name, dimension, description, the values with their ids, the general value (null when unset), and the contexts with their own values. set_preference takes these ids.

This tool takes no input.

check_textCheck text

Class
Read
Scope
style-guide:read
Annotations
readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true

Checks text against the user's Preferent style guide, including habits the user added and reply preferences, and returns JSON. flags lists each sentence that shows a habit, with its start and end offsets in the text, the habit id and name, a short reason, and a suggested rewrite (empty when the sentence can go). preferences lists reply preferences the whole text goes against. counts, summary, and clean (true when nothing is flagged) describe the result. Three AI models read the text through OpenRouter, and a sentence counts when two of them name habits in the same family. Fenced code blocks and table rows are skipped. Each account can run 20 checks a day. The same text against the same version of the guide within 10 minutes returns the stored result, with cached set to true, and does not count.

InputTypeRequiredDescription
textstring, up to 8,000 charactersYesThe text to check, such as a draft reply.
contextstring, up to 500 charactersNoWhat the text answers or where it will appear, such as the question a reply answers.
Error results
  • Send text of 1 to 8,000 characters.
  • Describe the context in 500 characters or fewer.
  • This account ran 20 text checks in the past 24 hours, the daily limit. A repeat of a text checked in the past 10 minutes still returns its result.
  • Too few of the models that check text answered. Try again in a minute.
  • Text checks are not available on this Preferent server.

set_preferenceSet preference

Class
Sensitive write
Scope
style-guide:write
Annotations
readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false

Sets one reply preference in the user's style guide and saves the guide as a new version. Without context, it sets the general value. With context, such as legal questions, it sets the value for that kind of question only. The new value replaces the old one, and an empty value clears the general value or removes the context. Use it when the user asks for the change.

InputTypeRequiredDescription
idstring, up to 80 charactersYesThe preference id from list_preferences.
valuestring, up to 80 charactersYesA value id from list_preferences, or an empty string to clear.
contextstring, up to 80 charactersNoThe kind of question or reader the value applies to, such as coding questions. Leave it out for the general value.
Error results
  • This connection can only read the style guide. Disconnect the app on your Preferent account page and connect it again to allow changes.
  • No preference in the style guide has that id. Call list_preferences to read the ids.
  • Use one of the preference's value ids from list_preferences, or an empty string to clear the setting.
  • Describe the context in 80 characters or fewer, such as legal questions. A preference holds at most 12 contexts.

mark_textMark text

Class
Write
Scope
style-guide:write
Annotations
readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false

Adds text the user marked as an example of one habit to their style guide, and saves the guide as a new version. With preferred, it saves the marked text and the user's rewrite as a pair. The habit's other examples stay. It sends nothing to the shared catalog; suggest_habit does that. Use it when the user asks to mark text.

InputTypeRequiredDescription
habitIdstring, up to 80 charactersYesThe habit id from list_habits.
textstring, up to 500 charactersYesThe text the user marked, on one line.
preferredstring, up to 500 charactersNoThe same content written the way the user prefers.
Error results
  • This connection can only read the style guide. Disconnect the app on your Preferent account page and connect it again to allow changes.
  • No habit in the style guide has that id. Call list_habits to read the ids.
  • Send the text to mark.
  • The habit already has 20 marked lines. The user can remove one in the style guide editor.
  • The habit already lists that marked text.

suggest_habitSuggest for the catalog

Class
Sensitive write
Scope
style-guide:write
Annotations
readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true

Sends text the user critiqued to the shared Preferent catalog review queue, where Preferent admins read it and may add it to the public catalog as an example or a new habit. It does not change the user's style guide. habitId takes a habit id from list_habits. For a habit the user added, the suggestion proposes that habit's name and definition. Without habitId, proposedName and proposedDefinition describe a new habit. The server rejects the call unless consent is true, which records that the user agreed to this text in the conversation: "Preferent admins will read the marked text, the rewrite, your critique, and the context you send. Nothing else from your style guide or your account goes with the suggestion. If an admin accepts it, the text may appear in the shared catalog that every style guide copies." Use it when the user asks to send text to the catalog. Apps whose terms limit how their data may be used, such as Muse, get an error from it.

InputTypeRequiredDescription
textstring, up to 500 charactersYesThe text the user critiqued, on one line.
rewritestring, up to 500 charactersNoThe same content written the way the user prefers.
critiquestring, up to 1,000 charactersYesWhat the user would change, in the user's words.
habitIdstring, up to 80 charactersNoA habit id from list_habits, when one fits.
proposedNamestring, up to 80 charactersNoA name for a new habit, when no habit fits.
proposedDefinitionstring, up to 1,000 charactersNoOne sentence that defines the new habit.
contextstring, up to 500 charactersNoWhere the text appeared, such as a landing-page heading.
consentbooleanYestrue records that the user agreed to the confirmation text in this conversation.
modelstring, up to 80 charactersNoThe model that wrote the marked text, such as claude-sonnet-4.5, gpt-5, or gemini-2.5-pro. This is the model that produced the text the user marked, which may be a different model from you. Leave it out when you do not know which model wrote the text.
Error results
  • This connection can only read the style guide. Disconnect the app on your Preferent account page and connect it again to allow changes.
  • The user has not confirmed the suggestion. The server accepts it with consent set to true once the user agrees to this text: "Preferent admins will read the marked text, the rewrite, your critique, and the context you send. Nothing else from your style guide or your account goes with the suggestion. If an admin accepts it, the text may appear in the shared catalog that every style guide copies."
  • Send the marked text.
  • Send the critique: what the user would change about the marked text, in the user's words.
  • No catalog habit has that id. Call list_habits for the ids, or leave habitId out and send proposedName for a new habit.
  • The account sent 20 suggestions in the past hour. Try again later.
  • This app's terms let Preferent use what it sends only to answer the user's own requests, so suggest_habit does not send text from it to the shared catalog. mark_text or add_habit can save the text in the user's style guide instead.

add_habitAdd habit

Class
Write
Scope
style-guide:write
Annotations
readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false

Adds a new habit to the user's style guide and saves the guide as a new version. Returns the new habit id. The other habits stay unchanged. Use it when the user asks for a new habit.

InputTypeRequiredDescription
namestring, up to 80 charactersYes
descriptionstring, up to 1,000 charactersYesOne or two sentences that define the habit.
priorityintegerNo, default 11 matters most. The default is 1.
groupstringNo, default ""One of Frame, Sentence shape, Word choice, Figure, or an empty string for no group.
parentIdstring or nullNo, default nullThe id of a top-level habit that this habit is a kind of.
teststring, up to 500 charactersNo, default ""A yes/no question that spots the habit.
whystring, up to 1,000 charactersNo, default ""Why the habit costs the reader.
markedarray of stringNo, default []Text that shows the habit. marked[i] pairs with preferred[i].
preferredarray of stringNo, default []The same content as marked[i], written the way the user prefers.
nearMissesarray of stringNo, default []Text that looks like the habit and is fine as written.
Error results
  • This connection can only read the style guide. Disconnect the app on your Preferent account page and connect it again to allow changes.
  • Give the habit a name.
  • Give the habit a description.
  • Use a whole-number priority from 1 to 99.
  • Use one of these groups, or an empty string for no group: Frame, Sentence shape, Word choice, Figure.
  • Each preferred line needs a marked line at the same position in marked.
  • Choose a parent habit that has no parent of its own. A habit with habits under it cannot have a parent.

update_habitUpdate habit

Class
Sensitive write
Scope
style-guide:write
Annotations
readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false

Changes one habit in the user's style guide and saves the guide as a new version. Fields left out keep their current values. marked, preferred, and nearMisses replace the whole list, so a shorter list removes examples. Use it when the user asks for the change.

InputTypeRequiredDescription
idstring, up to 80 charactersYesThe habit id from list_habits.
namestring, up to 80 charactersNo
descriptionstring, up to 1,000 charactersNo
priorityintegerNo
groupstringNoOne of Frame, Sentence shape, Word choice, Figure, or an empty string for no group.
parentIdstring or nullNonull removes the parent.
teststring, up to 500 charactersNo
whystring, up to 1,000 charactersNo
markedarray of stringNoText that shows the habit. marked[i] pairs with preferred[i]. Replaces the current list.
preferredarray of stringNoThe same content as marked[i], written the way the user prefers. Replaces the current list.
nearMissesarray of stringNoText that looks like the habit and is fine as written. Replaces the current list.
Error results
  • This connection can only read the style guide. Disconnect the app on your Preferent account page and connect it again to allow changes.
  • No habit in the style guide has that id. Call list_habits to read the ids.
  • Give the habit a name.
  • Give the habit a description.
  • Use a whole-number priority from 1 to 99.
  • Use one of these groups, or an empty string for no group: Frame, Sentence shape, Word choice, Figure.
  • Each preferred line needs a marked line at the same position in marked.
  • Choose a parent habit that has no parent of its own. A habit with habits under it cannot have a parent.

Check endpoint

POST /api/check runs the same check as check_text for scripts and agent hooks, and returns the same JSON. It takes a personal API token, or an OAuth access token issued for the MCP server with the style-guide:read scope. The body is JSON with text, up to 8,000 characters, and an optional context, up to 500 characters.

curl -fsS -X POST "https://preferent.ai/api/check" \
  -H "Authorization: Bearer $PREFERENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text": "Great question! The fix was simple — a missing semicolon."}'
  • 200 with the result. A result from the cache has cached set to true.
  • 400 when the body is not valid: Send a JSON body such as {"text": "...", "context": "..."}.
  • 401 when the token is missing, expired, or revoked, and 403 when it lacks the read scope: This connection lacks the style-guide:read scope.
  • 429 when the token used up its hourly quota, or the account used up its daily checks, with Retry-After.
  • 503 when too few of the checking models answer.

The Connect page has a hook script that runs the check on each final reply in Claude Code and Cursor and asks the agent to revise when a sentence is flagged.

Resources and prompts

  • preferent://style-guide/full: The user's Preferent style guide as plain text: every habit, with its test, two pairs of examples, and an example that is fine as written.
  • preferent://style-guide/compact: The user's Preferent style guide as plain text: priority tiers 1 and 2, with one pair of examples per habit.
  • preferent://style-guide/tiny: The user's Preferent style guide as plain text: the names and one-line definitions of the top habits, in under 1,500 characters.
  • Prompt preferent: Adds the compact version of the user's style guide to the conversation as a message from the user.

Errors

A tool that cannot do what was asked returns a result with isError set to true and a message that says what to change, such as an unknown habit id. Each tool above lists its messages. HTTP errors come before any tool runs:

  • 401 when the token is missing, expired, or revoked. The WWW-Authenticate header names the resource metadata, and says invalid_token when a token was sent.
  • 429 when the token used up its hourly quota, with Retry-After: 600. A text check past the daily limit returns a tool error instead.

Rate limits

  • Each personal API token and each connected app can make 600 requests an hour, across the MCP server, the export endpoint, and the check endpoint.
  • Each account can send 20 catalog suggestions an hour.
  • Each account can run 20 text checks in 24 hours, across check_text and /api/check. A repeat of the same text against the same guide version within 10 minutes returns the stored result and does not count.
  • The token endpoint takes 300 requests an hour per client and 3,000 per address. Hosted apps whose one client serves many people, such as Claude and ChatGPT, have no per-client limit and 20,000 requests an hour per address.
  • Client registration takes 200 registrations an hour per address, or 5,000 for registrations from a known hosted app.

Data and support

A connected app receives the person’s style guide and can change it with the write tools. check_text and /api/check send the text to AI models through OpenRouter, and keep the result in server memory for up to 10 minutes as a cache. The privacy policy says what Preferent stores and who receives it. For help, write to support@preferent.ai.