MCP Server
Your Genfeed instance runs an MCP server that gives your agent permission-scoped access to content, workflows, publishing, analytics, and ads. It starts with the rest of the stack; no extra install is needed.
Endpoint: http://localhost:3014/mcp on a default install. If you run behind
your own domain, use that MCP URL instead (see
Reverse Proxy and HTTPS).
Transport: Streamable HTTP, MCP revision 2026-07-28, with stateless
compatibility for 2025-era clients. Modern requests carry their protocol version,
client identity and capabilities in params._meta, together with the
MCP-Protocol-Version, Mcp-Method and (where applicable) Mcp-Name headers.
They can call tools directly without initialize or a session ID. server/discover
provides optional server metadata and requires authorization, just like the
legacy initialize handshake. Legacy clients continue to use their existing
handshake on the same endpoint.
Authentication: a scoped API key from your instance, or browser OAuth where your client supports it. See Authentication.
Examples on this page use the default local address. Replace
http://localhost:3014 with your MCP origin and http://localhost:3010 with your
API origin if they differ.
Connect to your instance
Start your stack first (see Installation Options), then connect a client.
Claude Code
Register the dedicated content connector, then open /mcp inside Claude Code,
select genfeed, and complete browser OAuth:
claude mcp add --transport http genfeed --scope user http://localhost:3014/mcp/claudeMedia creation happens separately in Genfeed Studio in your instance’s web app. Configure your deployment’s public app, API, and MCP URLs so OAuth discovery points at addresses your browser can reach; see Configuration.
Codex and other clients
Point the client at the standard http://localhost:3014/mcp endpoint with a
scoped API key. Create the key in your web app under Settings → API keys
using the MCP preset (for the default seeded organization,
http://localhost:3000/default/~/settings/api-keys), or use the guided
Connect page at /connect in your web app, which creates an MCP-scoped key
and runs a verification check. Export the key in the MCP client’s environment,
not in the Genfeed container’s .env:
export GENFEED_API_KEY=gf_live_xxx
codex mcp add genfeed --url http://localhost:3014/mcp --bearer-token-env-var GENFEED_API_KEYTo enter the key without putting its value in shell history:
read -s GENFEED_API_KEY && export GENFEED_API_KEYCodex reads the named environment variable. Do not paste credentials into chats, commits, or shared logs. Inspect and update an existing Genfeed server entry before switching authentication methods; preserve unrelated servers.
You can also add the server in your user-level ~/.codex/config.toml:
[mcp_servers.genfeed]
url = "http://localhost:3014/mcp"
bearer_token_env_var = "GENFEED_API_KEY"In any other client that supports remote Streamable HTTP, add the endpoint as a custom MCP server and supply the key as a bearer token. Genfeed uses standard discovery, registration, and PKCE flows for OAuth, so compatible clients can authorize in the browser instead, but each client still needs a verification run on your deployment. Source compatibility does not establish that a given client’s OAuth, reconnect, or media flows work.
Verify access
Ask your agent: “List my Genfeed brands.” A successful scoped read verifies
access. codex mcp list or claude mcp list can diagnose configuration, but a
server entry or copied command alone does not prove authorization.
If consent is denied or the login expires, restart authorization through
codex mcp login genfeed or Claude Code’s /mcp. Check the account and
organization on the consent screen. Revoke unwanted access from your instance’s
API key settings.
Client syntax was checked against Codex CLI 0.153.2 (mcp add --help and
mcp login --help) and the Claude Code MCP documentation .
Authentication
Turning off the web login wall (BETTER_AUTH_ENABLED=false) does not disable MCP
authentication: the standard /mcp endpoint still requires a bearer token. See
Configuration. Authenticated requests
carry either an API key you created or an access token managed by an OAuth
client:
Authorization: Bearer <api-key-or-access-token>Missing, invalid, or expired tokens return 401 errors. An OAuth client should use its refresh token on a 401 before restarting browser authorization. Keys remain copy-once; see API Keys for scopes, rotation, and revocation. Use the MCP preset, which is approval-first and excludes direct publishing.
The endpoint accepts POST, GET, and DELETE.
OAuth conformance
What a spec-compliant client can rely on:
- Discovery (RFC 9728). Protected-resource metadata is served at both
http://localhost:3014/.well-known/oauth-protected-resourceand the path-suffixed.../oauth-protected-resource/mcp, with identical bodies. A401from/mcpcarries aWWW-Authenticateheader pointing at that metadata. Authorization-server metadata is served by your API athttp://localhost:3010/.well-known/oauth-authorization-server. Both documents are readable cross-origin. - Resource identifier (RFC 8707). The
resourceis your MCP URL ending in/mcpfor the standard connector, or/mcp/claudefor Claude. Claude discovery is at/.well-known/oauth-protected-resource/mcp/claude. Send it on the authorize and token requests. - Client metadata documents (CIMD). A public client can use its HTTPS
metadata-document URL as
client_id, without registering first. The document must have a path and contain the exactclient_id,client_nameandredirect_uris; only public PKCE clients (token_endpoint_auth_method: none) are supported. Fetches require public HTTPS destinations, refuse redirects, time out after five seconds and accept at most 64 KiB of JSON. Valid metadata is cached for at most five minutes;no-storeandno-cachedisable caching. Discovery advertisesclient_id_metadata_document_supported: true. - Legacy registration (RFC 7591).
POST /v1/oauth/registerwithredirect_uris;token_endpoint_auth_methodisnone. - Authorization.
code_challenge_methodmust beS256.stateis optional; when supplied it is echoed unchanged on both the success and theaccess_deniedredirect. Both redirects includeissequal to the issuer advertised by authorization-server metadata; clients must validate it before exchanging a code (RFC 9207). Discovery advertisesauthorization_response_iss_parameter_supported: true. - Tokens. The token exchange returns an access token and a
refresh_token. Access tokens expire after 30 days. Present the refresh token withgrant_type=refresh_tokento obtain a new access token without a second consent screen; each refresh rotates the refresh token, and reuse of a consumed refresh token revokes the whole chain. A narrowerscopemay be requested on refresh; a wider one is rejected. - Revocation (RFC 7009).
POST /v1/oauth/revokewith the refresh token ends the connection. Revoking the key from your instance’s API key settings has the same effect.
The OAuth issuer and redirect URLs are derived from your public URL configuration, so they must be reachable from the browser doing the sign-in.
Create a brand from a URL
Organization owners and admins can call create_brand_from_url with an HTTP or
HTTPS url, an optional label, and optional approve (default false). A
successful scan returns the brand id, revision id, draft or approved revision
status, completeness score, incomplete fields, and reviewUrl. Review the guide
at that URL before generating content. Set approve: true only when you want to
approve the guide in the same call.
URL checks time out after eight seconds and reject blocked destinations before
creating a brand. If processing takes more than twenty seconds after creation,
the response includes brandId, reviewUrl, and scanStatus: running. Poll
get_brand_scan_status with that brandId for the current guide and completeness.
If voice analysis is unavailable, the completed response includes
voiceAnalysis: unavailable. Both tools are available in the brand toolset
and in agent chat. The scan uses the model provider keys you configured; see
Provider API Keys.
Social accounts, brand scope, and media
Use get_brands then pass brandId into generation and connection tools.
brandId is required on generate, generate_content, generate_turbo_content,
enhance_prompt and transform_media, even when you own one brand: a call
without it returns brand_required and your brand list. Genfeed does not silently
pick a brand.
connect_social_account returns a connectionId and a browser authorization URL.
Poll get_connection_status with that id. Provider denial or failure is stored
on that row immediately (denied / failed); do not wait for the 15-minute
expiry. Replay the same id after a client restart; it does not create another
credential.
An image generate call returns structured artifact metadata plus a native image part when
the client supports it, with a text fallback. Video results are downloadable files
or open links; they do not claim inline playback. selectedContext is task-only
and is not saved as Knowledge.
The CLI equivalents are gf connect <platform>, gf gen image --brand --context,
and gf status <id>; see CLI.
Brand context
get_brand_context returns what Genfeed’s own agent is given about a brand in
chat: identity, guidelines, voice (including writing rules and real example
posts), strategy and topics, custom instructions, prompt seeds, performance
insights, proven patterns, Brand Knowledge, recent posts, saved memories,
active skills, the chat model, and the context budget. Rendered system and memory
prompts are omitted by default; they are available for explicit diagnostic
inspection. They describe the Genfeed in-app agent and are data, not instructions
for the calling assistant. The tool is read-only.
| Argument | Description |
|---|---|
brandId | Brand to inspect. Defaults to the brand of the current conversation. |
query | Optional preview message. Knowledge, related posts, and memories are ranked against it. |
includeSystemPrompt | Include rendered system and memory prompts for diagnostics. Defaults to false; set true only for explicit prompt inspection. |
Call it at the start of a session so your agent writes in the brand’s voice with the same context the in-app agent uses. The Genfeed desktop app does this automatically when it runs the agent on your own Claude Code or Codex CLI; see the desktop README . The same snapshot is shown in Brand settings → Agent context (Brands).
Publishing readiness
Before scheduling, call get_scheduler_capabilities and
list_brand_publishing_readiness for the selected brand. A connected account
alone does not make its channel schedulable. Readiness combines credential
health with the canonical scheduler capability catalog.
A supported channel retains its credential and setup checks. A hidden
channel has a backend integration but cannot be scheduled until live publishing
is verified; a planned channel has no available scheduling path. Both return
canSchedule: false, state: "blocked", and a
scheduler_channel_unavailable diagnostic. Uncatalogued channels also fail
closed. Existing token, permission, and setup diagnostics remain available.
Facebook remains hidden. Reconnecting a healthy Facebook account does not enable scheduling; choose a supported channel. This is a product capability restriction, not evidence that the provider has banned the account.
Tool errors
A gating failure is a tool result with isError: true. structuredContent
is the contract below, not a generic 500 and not a bare string. The same
object is error.data on the JSON-RPC response when the Streamable HTTP
transport rejects the request before a tool runs (missing credential, or the
shared RateLimitService window). JSON-RPC error.code stays numeric.
code | When | nextStepUrl | Extra fields |
|---|---|---|---|
unauthorized | Missing or rejected bearer credential (401) | /connect on your app origin | |
rate_limited | RateLimitService, or an upstream 429 | none | retryAfterSeconds when the limiter reported a wait |
validation_failed | REST ValidationPipe / ErrorResponse.validationFailed field errors, or a missing required tool argument | none | errors[] of { field, message } |
approval_pending | mutationPolicy: 'approval-required' queued the write instead of running it | /publishing/review | approvalId, toolName, approvalStatus, canResolveApproval |
brand_required | A generation tool (generate, generate_content, generate_turbo_content, enhance_prompt, transform_media) was called without brandId | none | brands[] of { id, label }, the caller’s brands |
message is always set. retryAfterSeconds and nextStepUrl are omitted
when they do not apply; rate_limited does not invent a URL. Paths are app
routes on your instance; sign-in continues into the caller’s organization. Fix
errors[] and call the tool again. For approval_pending, hand the human
nextStepUrl or, when canResolveApproval is true and the user approves, call
resolve_approval with structuredContent.approvalId. For
brand_required, retry with one of the listed brands[].id values; no brand is
ever picked for you.
Tools
Each call uses the permissions on the authorized token or key.
- Content and media: articles, images, videos, music, avatars, Turbo runs.
- Workflows: list, create, execute, inspect status.
- Publishing: list and publish social posts.
- Analytics and ads: analytics, campaigns, Google Ads, Meta Ads.
- Agents and admin: threads, approvals, role-gated admin tools.
Generation tools call the model providers whose keys you configured; see Provider API Keys.
Toolsets
The bare endpoint uses the default profile. Profiles shape the advertised
tools/list selection:
| Endpoint selector | Advertised toolsets |
|---|---|
No selector or ?profile=default | core, generation, content, and scheduler, capped at 26 tools. |
?profile=directory | The same bounded selection, with generation, clips, and ui excluded. This profile does not imply directory approval. |
?profile=full | All toolsets, subject to the caller’s permissions. |
To expose the available content journey, including generation and analytics, select these toolsets explicitly:
http://localhost:3014/mcp?toolsets=content,generation,analytics,brand,schedulercoreis always included and cannot be excluded. It holds discovery and account/status tools.- A nonempty
toolsetsselection wins overprofile. Use comma-separated, kebab-case toolset names. - Absent or blank
toolsetsuses the selected profile, ordefaultwhen no profile is supplied. For example,?toolsets=&profile=fullselects all toolsets;?toolsets=alone usesdefault. - Unknown toolset names, or an unknown profile when profile selection applies, return HTTP 400 before authentication, including public discovery requests.
tools/callpermissions are unchanged. A tool outside the advertised selection can still be called directly by name if the token permits it. Discovery selectors do not grant authorization or bypass approval checks.
Available toolsets
| Toolset | Description |
|---|---|
core | Account basics and tool discovery. Always included on every connection regardless of the requested toolsets. |
content | Posts, articles, the content calendar, repurposing, X post activity, and LinkedIn and article generation through generate_content. |
scheduler | Scheduled release lifecycle and channel scheduling capability discovery. |
generation | Image, video, music, voice, and avatar generation, media transforms (edit, reframe, upscale, merge), generation options, plus listing generated media. |
workflows | Workflow creation, execution, scheduling, and template management. |
analytics | Performance, content, video, and LinkedIn analytics plus trend discovery. |
social-inbox | Social conversation triage: replies, approvals, direct messages, and account activity. |
brand | create_brand_from_url, get_brand_scan_status, brand identity, completeness, publishing readiness, the brand interview flow, and the get_brand_context snapshot. |
ads | Meta, Google, and TikTok ad account, campaign, and insight tools. |
inspiration | Instagram and TikTok inspiration and top-performer discovery. |
clips | Clip project creation, analysis, and highlight extraction from source video. |
knowledge | Capture, search, and manage brand knowledge sources. |
agent-chat | Chat with the account and coordinate work across agents: send messages, list and transfer conversations, and request assets from another agent. |
skills-pro | Verify and install Skills Pro packs. |
Saved remix handoff
Imported-post remix is not on the bare MCP URL. Reconnect with an explicit profile so discovery includes the inspiration, content, generation, analytics, brand, and scheduler toolsets:
http://localhost:3014/mcp?toolsets=inspiration,content,generation,analytics,brand,schedulercore is still added automatically. The bare URL keeps the default profile
and its 26-tool cap, which does not advertise these actions; use
?profile=full to list every tool.
Call the actions in this order. Saving, importing, reading, editing, attaching, and quoting never dispatch generation, publish, or add brand Knowledge.
import_source_post: public X, Instagram, or TikTok URL plus explicitbrandId. Approval is required. Unsupported, private, or missing inputs fail closed. The result is the imported source identity and whether it was reused.create_remix_concept:brandIdandsourcePostId. Creates or reuses the canonical saved concept and returns its current revision.update_remix_concept:runId,expectedRevision, and at least one edit. A stale revision fails instead of overwriting.attach_remix_analysis_source: optional, for video or avatar output. Pass a same-brand Library video id, ornullto clear it. The Library video is the analyzed media. The imported post URL, author, and selector stay provenance.quote_remix_generation: persists an exact quote forexpectedRevisionand does not start work. Read it back withget_remix_runbefore approval. Image and copy accept onlyoperation: "generate"and reject scene or repair fields. Image requires a registered imagemodel;crun/models do not support remix quotes and are rejected. Copy rejects a callermodeland uses the canonical background model. Video and avatar rejectmodeland quoteanalysis,generate, orrepairon the scene pipeline. A quote expires 15 minutes after it is saved. Provider, model, BYOK, source, or recipe changes require a new quote.start_remix_generation: approval-required. Pass the persistedquoteIdand the same revision. A repeated accepted call returns the same canonical run and does not start the attempt again.get_remix_run: safe reconnect. Returns revision, lineage, quotes, receipts, and artifacts without starting another run.control_remix_generation: approval-requiredcancelorresumefor an existing video or avatar scene pipeline. Image and copy have no control action.
Image and copy execute through the generic generation quote. Video and avatar execute through the scene pipeline. Single-scene legacy video or avatar start is not an unquoted shortcut. Live native-client acceptance, paid provider calls, and real publishing are not claimed here.
Discover tools outside your selection
One read-only meta tool, always in core, lets an agent find a tool that
isn’t in its current selection. find_tools takes { name?, query?, toolset?, limit? }:
- No arguments: every toolset available on this server, with tool counts.
queryand/ortoolset: case-insensitive substring search over tool name, description, and toolset.name: the full tool definition for one name, including the closest name matches when the name isn’t found.
These search the full, role-filtered catalog regardless of the caller’s
current toolset selection. Once an agent has a tool’s name and schema from
find_tools, it can call that tool directly with tools/call (narrowing
tools/list only narrows discovery, not what can be invoked) or reconnect
with a broader ?toolsets= selection so the tool appears in future
tools/list responses.
Connect with a toolset selection
The toolset selector applies to the standard connector. Claude uses the fixed /mcp/claude catalog.
codex mcp add genfeed --url 'http://localhost:3014/mcp?toolsets=content,generation,analytics,brand,scheduler' --bearer-token-env-var GENFEED_API_KEYSkills
MCP gives an agent Genfeed’s tools; Agent Skills give it the content
knowledge to use them well. Install the catalog with
bunx skills add genfeedai/skills.
Uploading local media
The default MCP profile includes request_media_upload, complete_media_upload,
and get_posts. Select a brand before reserving an upload.
- Call
request_media_uploadwithfilename,contentType, andcategory. - Upload to the returned
uploadUrlbefore it expires. Formethod: PUT, send the file bytes with the returned headers. For self-hostedmethod: POST_JSON, send the returnedlocalUploadobject as JSON, adding the base64-encoded file bytes aslocalUpload.source.data. Respect the returned file constraints. - Call
complete_media_uploadwith the returnedassetId. Itsmediaentries can be passed tocreate_scheduled_release; a returned hostedurlcan also be used increate_postmediaUrls. Scheduling retains its approval checks. - Use
get_postswithpostIdto read a post’s targets, state, media, and timestamps.
Upload reservation creates a pending asset. Both upload tools are non-destructive
writes; get_posts is read-only. None of these tools publishes a post.
Interactive content cards
MCP Apps hosts can render Genfeed content directly in the conversation:
- Content calendar:
get_postswithdays, shown as one column per day, with open days and the drafts count. - Post previews: platform, status, copy and media. Generated caption variations appear once each in a responsive grid; a single result keeps one card.
- Images: compact previews with expand and open controls; metadata stays out of the primary view.
- Video and audio players.
- Running generations: a progress state that re-reads
get_job_statusuntil the media is ready. - Article cards.
Account lookups return a readable message with setup status, role, credits, and
requested usage metrics. They do not open a content widget. Tool text contains
readable summaries; internal identifiers and complete payloads remain in
structuredContent.data for follow-up calls. Clients should read structured
fields rather than parse display text as JSON. Errors provide readable guidance
and keep their error codes and approval references in structuredContent.
The MCP server serves a self-contained HTML resource at
ui://genfeed/content-cards-v5-<content-hash>.html with MIME type
text/html;profile=mcp-app. Selected tool descriptors link it through
_meta.ui.resourceUri. They also carry the legacy ui/resourceUri key and the
ChatGPT openai/outputTemplate alias. The widget uses the standard MCP Apps
JSON-RPC bridge, and its only tool call is the read-only get_job_status.
The resource bundles Genfeed’s shared Card, Button, Badge, typography, media
players and Dialog components with the product stylesheet and Satoshi served from the MCP origin. Its content
hash changes when shared UI, styles or the font change, invalidating host caches.
No separate ChatGPT frontend deployment is needed.
Text and media resource links remain available to clients without MCP Apps. Empty results and tool errors remain visible, and pending approvals are never presented as completed content. Cards do not publish or mutate content.
Configure GENFEEDAI_CDN_URL and, if media is served directly by it,
GENFEEDAI_MICROSERVICES_FILES_URL on the MCP server; see
Configuration. Only these media origins
are allowed by the widget CSP. Other HTTP(S) media URLs remain available through
an explicit open-link action. The static HTML resource is public; all account
data still comes from authenticated tool calls. It contains no bearer tokens or
account cookies.
Claude, Claude Code and Cowork
Connect to http://localhost:3014/mcp/claude with browser OAuth (see
Claude Code above). This connector supports brands, drafts,
existing assets, scheduling and analytics. Create images, video and audio in
Genfeed Studio in your instance’s web app, then return to Claude to manage your
content. Opening Studio does not start generation.
This is a custom connector; Genfeed is not yet submitted or published in the public Claude directory.
Existing connections to /mcp retain their original capabilities.
The restriction is bound to the OAuth resource, persists across token refresh and is enforced on execution and discovery. Changing the toolset/profile or using the Claude token on /mcp does not enable generation. Workflows, Turbo runs, remix, arbitrary agent calls and approval redemption are unavailable through this connector. Other clients use the standard /mcp connector.
Troubleshooting
- Discovery fails: use exactly your MCP URL (
http://localhost:3014/mcpon a default install) and a Streamable HTTP client. - 401 errors: an OAuth client should present its refresh token first and restart browser authorization only if that fails; with an API key, check the key and its scopes.
- Wrong endpoint: check
/v1/configon the MCP host. - Cannot connect at all: confirm port
3014is published; see Troubleshooting.