Skip to Content
API ReferenceMCP Server

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/claude

Media 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_KEY

To enter the key without putting its value in shell history:

read -s GENFEED_API_KEY && export GENFEED_API_KEY

Codex 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-resource and the path-suffixed .../oauth-protected-resource/mcp, with identical bodies. A 401 from /mcp carries a WWW-Authenticate header pointing at that metadata. Authorization-server metadata is served by your API at http://localhost:3010/.well-known/oauth-authorization-server. Both documents are readable cross-origin.
  • Resource identifier (RFC 8707). The resource is your MCP URL ending in /mcp for the standard connector, or /mcp/claude for 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 exact client_id, client_name and redirect_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-store and no-cache disable caching. Discovery advertises client_id_metadata_document_supported: true.
  • Legacy registration (RFC 7591). POST /v1/oauth/register with redirect_uris; token_endpoint_auth_method is none.
  • Authorization. code_challenge_method must be S256. state is optional; when supplied it is echoed unchanged on both the success and the access_denied redirect. Both redirects include iss equal to the issuer advertised by authorization-server metadata; clients must validate it before exchanging a code (RFC 9207). Discovery advertises authorization_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 with grant_type=refresh_token to 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 narrower scope may be requested on refresh; a wider one is rejected.
  • Revocation (RFC 7009). POST /v1/oauth/revoke with 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.

ArgumentDescription
brandIdBrand to inspect. Defaults to the brand of the current conversation.
queryOptional preview message. Knowledge, related posts, and memories are ranked against it.
includeSystemPromptInclude 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.

codeWhennextStepUrlExtra fields
unauthorizedMissing or rejected bearer credential (401)/connect on your app origin
rate_limitedRateLimitService, or an upstream 429noneretryAfterSeconds when the limiter reported a wait
validation_failedREST ValidationPipe / ErrorResponse.validationFailed field errors, or a missing required tool argumentnoneerrors[] of { field, message }
approval_pendingmutationPolicy: 'approval-required' queued the write instead of running it/publishing/reviewapprovalId, toolName, approvalStatus, canResolveApproval
brand_requiredA generation tool (generate, generate_content, generate_turbo_content, enhance_prompt, transform_media) was called without brandIdnonebrands[] 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 selectorAdvertised toolsets
No selector or ?profile=defaultcore, generation, content, and scheduler, capped at 26 tools.
?profile=directoryThe same bounded selection, with generation, clips, and ui excluded. This profile does not imply directory approval.
?profile=fullAll 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,scheduler
  • core is always included and cannot be excluded. It holds discovery and account/status tools.
  • A nonempty toolsets selection wins over profile. Use comma-separated, kebab-case toolset names.
  • Absent or blank toolsets uses the selected profile, or default when no profile is supplied. For example, ?toolsets=&profile=full selects all toolsets; ?toolsets= alone uses default.
  • Unknown toolset names, or an unknown profile when profile selection applies, return HTTP 400 before authentication, including public discovery requests.
  • tools/call permissions 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

ToolsetDescription
coreAccount basics and tool discovery. Always included on every connection regardless of the requested toolsets.
contentPosts, articles, the content calendar, repurposing, X post activity, and LinkedIn and article generation through generate_content.
schedulerScheduled release lifecycle and channel scheduling capability discovery.
generationImage, video, music, voice, and avatar generation, media transforms (edit, reframe, upscale, merge), generation options, plus listing generated media.
workflowsWorkflow creation, execution, scheduling, and template management.
analyticsPerformance, content, video, and LinkedIn analytics plus trend discovery.
social-inboxSocial conversation triage: replies, approvals, direct messages, and account activity.
brandcreate_brand_from_url, get_brand_scan_status, brand identity, completeness, publishing readiness, the brand interview flow, and the get_brand_context snapshot.
adsMeta, Google, and TikTok ad account, campaign, and insight tools.
inspirationInstagram and TikTok inspiration and top-performer discovery.
clipsClip project creation, analysis, and highlight extraction from source video.
knowledgeCapture, search, and manage brand knowledge sources.
agent-chatChat with the account and coordinate work across agents: send messages, list and transfer conversations, and request assets from another agent.
skills-proVerify 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,scheduler

core 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.

  1. import_source_post: public X, Instagram, or TikTok URL plus explicit brandId. Approval is required. Unsupported, private, or missing inputs fail closed. The result is the imported source identity and whether it was reused.
  2. create_remix_concept: brandId and sourcePostId. Creates or reuses the canonical saved concept and returns its current revision.
  3. update_remix_concept: runId, expectedRevision, and at least one edit. A stale revision fails instead of overwriting.
  4. attach_remix_analysis_source: optional, for video or avatar output. Pass a same-brand Library video id, or null to clear it. The Library video is the analyzed media. The imported post URL, author, and selector stay provenance.
  5. quote_remix_generation: persists an exact quote for expectedRevision and does not start work. Read it back with get_remix_run before approval. Image and copy accept only operation: "generate" and reject scene or repair fields. Image requires a registered image model; crun/ models do not support remix quotes and are rejected. Copy rejects a caller model and uses the canonical background model. Video and avatar reject model and quote analysis, generate, or repair on the scene pipeline. A quote expires 15 minutes after it is saved. Provider, model, BYOK, source, or recipe changes require a new quote.
  6. start_remix_generation: approval-required. Pass the persisted quoteId and the same revision. A repeated accepted call returns the same canonical run and does not start the attempt again.
  7. get_remix_run: safe reconnect. Returns revision, lineage, quotes, receipts, and artifacts without starting another run.
  8. control_remix_generation: approval-required cancel or resume for 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.
  • query and/or toolset: 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_KEY

Skills

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.

  1. Call request_media_upload with filename, contentType, and category.
  2. Upload to the returned uploadUrl before it expires. For method: PUT, send the file bytes with the returned headers. For self-hosted method: POST_JSON, send the returned localUpload object as JSON, adding the base64-encoded file bytes as localUpload.source.data. Respect the returned file constraints.
  3. Call complete_media_upload with the returned assetId. Its media entries can be passed to create_scheduled_release; a returned hosted url can also be used in create_post mediaUrls. Scheduling retains its approval checks.
  4. Use get_posts with postId to 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_posts with days, 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_status until 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/mcp on 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/config on the MCP host.
  • Cannot connect at all: confirm port 3014 is published; see Troubleshooting.
Last updated on