# Clouture > Clouture is a web app for ecommerce brands and agencies to find, vet and work with UGC creators on TikTok and Instagram. It has an MCP server for AI assistants such as Claude and Muse. ## Connect an AI assistant - [MCP server](https://clouture.io/mcp): Streamable HTTP, OAuth 2.1 with PKCE and dynamic client registration - [How to connect](https://clouture.io/mcp-info): two steps, plus permissions and token lifecycle - [agents.md](https://clouture.io/agents.md): the OAuth flow, every tool with its parameters, and the rules - [Full reference](https://clouture.io/llms-full.txt) ## Discovery - [OAuth protected resource](https://clouture.io/.well-known/oauth-protected-resource) - [OAuth authorization server](https://clouture.io/.well-known/oauth-authorization-server) - [AI catalog](https://clouture.io/.well-known/ai-catalog.json) - [ARD manifest](https://clouture.io/.well-known/ard.json) ## About - [Home](https://clouture.io/) - [Privacy Policy](https://clouture.io/privacy) - [Terms of Service](https://clouture.io/terms) - [Creators: join](https://clouture.io/creators/join) --- # Clouture for AI agents Tools version: 2026-10-13.1 (app 0.13.0). This file is generated from the server's tool definitions. ## What it does Clouture finds and vets UGC (user-generated content) creators for ecommerce brands. It works with Claude, Muse and any MCP-compatible assistant. Start with whoami, then list_brands and list_briefs. list_candidates shows a brief's creators with AI scores; get_creator gives the full picture. Paid searches can only be started in the app, so if a brief needs new creators, tell the user to open the brief and click Run search or Find more. Nothing is ever sent to creators from here: draft_outreach writes drafts the user sends from their own mail app. Every change-making tool accepts dry_run; use it to show the user what will happen before doing it. ## Connect - MCP endpoint: `https://clouture.io/mcp` (Streamable HTTP, JSON responses, POST only; GET returns 405 because there is no event stream) - Protocol versions: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05 - CORS: `OPTIONS` returns 204 with `Access-Control-Allow-Origin: *`, `Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS`, `Access-Control-Allow-Headers: Authorization, Content-Type, Accept, Mcp-Session-Id, Mcp-Protocol-Version, Mcp-Method, Mcp-Name, Last-Event-ID` and `Access-Control-Expose-Headers: Mcp-Session-Id, Mcp-Protocol-Version, WWW-Authenticate`. - Discovery for catalogs: `https://clouture.io/.well-known/ai-catalog.json` and `https://clouture.io/.well-known/ard.json` (Agentic Resource Discovery, v0.9 draft). - Unauthenticated requests return HTTP 401 with a JSON-RPC error and `WWW-Authenticate: Bearer resource_metadata="https://clouture.io/.well-known/oauth-protected-resource"`. ### OAuth 2.1 (recommended) 1. Read `https://clouture.io/.well-known/oauth-protected-resource`, then `https://clouture.io/.well-known/oauth-authorization-server`. 2. Register at `https://clouture.io/oauth/register` (RFC 7591). Public clients use `token_endpoint_auth_method: none`. Redirect URIs must be https, or http on localhost. 3. Send the user to `https://clouture.io/oauth/authorize` with `response_type=code`, `client_id`, `redirect_uri`, `state`, `code_challenge` and `code_challenge_method=S256` (PKCE is required), optional `scope` and `resource=https://clouture.io/mcp`. 4. The user signs in, picks the account and approves the permissions. You get `code` and `state` (and `iss`) back. 5. Exchange the code at `https://clouture.io/oauth/token` with `grant_type=authorization_code` and the `code_verifier`. 6. Call the MCP endpoint with `Authorization: Bearer `. ### Scopes - `brands:read`: See your brands and their profiles - `briefs:read`: See briefs, their settings and search results so far - `briefs:write`: Create and edit briefs (it can't start paid searches) - `creators:read`: See creators, their scores, track records and your creator database - `creators:write`: Shortlist, reject and rate creators, update deal notes, and add creators from your database to briefs - `outreach:read`: See outreach templates, messages and follow-ups due - `outreach:write`: Write outreach drafts and mark messages as sent (it never sends anything itself) - `spend:read`: See this month's spending against your cap tools/list only shows the tools the token's scopes allow. Calling a tool outside them returns a tool error that names the missing scope. ### Token lifecycle - Access tokens last 1 hour. Refresh them at the token endpoint with `grant_type=refresh_token`. - Refresh tokens last 30 days and rotate: every refresh returns a new refresh token and retires the old one. Reusing a retired refresh token ends the whole connection, since it means the token was copied. - Authorization codes last 10 minutes and work once. - Personal API tokens (created by the user under Profile, API tokens) last for the period they choose, or until revoked. Send them as Bearer tokens. - Revoke any token at `https://clouture.io/oauth/revoke` (RFC 7009); revoking an OAuth token ends that connection. Users can also disconnect apps and revoke tokens under Profile in the app. - All tokens stop working at once if the user is disabled or leaves the account. Resetting the password or choosing Sign out everywhere also ends every OAuth connection (personal API tokens keep working until revoked). ## Rules - Paid searches are never started through MCP. If a brief needs new creators, ask the user to run it in the app. - Nothing is sent to creators. `draft_outreach` writes a draft; the user sends it from their own mail app; `mark_outreach_sent` records that. - Every change-making tool accepts `dry_run: true`. Preview first when the user hasn't explicitly asked for the change. - Creators marked Do not contact (including anyone who unsubscribed) can't be drafted to or moved into outreach. - Changes made through MCP are recorded in the account's audit log with the connecting app's name. - Rate limit: 300 requests per 5 minutes per token; above that you get HTTP 429. ## Tools ### `whoami`: Who am I Shows who this connection acts as: the user, the account, their role, the permissions (scopes) granted, and how many brands they can see. Call this first if you are unsure what you can do. - Permission: none - Changes data: no - Parameters: none ### `list_brands`: List brands Lists the brands this user can see in the account, with each brand's category, what it sells, its customers and its notes for creator scoring. Use the brand_id from here with other tools. - Permission: `brands:read` - Changes data: no - Parameters: none ### `get_brand`: Get a brand Full profile of one brand: website, category, what it sells, customers, scoring notes, outreach defaults (offer, deliverables, usage rights, sender), and counts of briefs and creators. - Permission: `brands:read` - Changes data: no - Parameters: - `brand_id` (integer, required): The brand, from list_brands. ### `list_briefs`: List briefs Lists briefs (saved creator searches), optionally for one brand. Each row has the platforms, status, when it last ran, and how many creators are in each inbox stage. Use brief_id from here with get_brief and list_candidates. - Permission: `briefs:read` - Changes data: no - Parameters: - `brand_id` (integer): Only briefs for this brand. Optional. - `status` (string) (one of: active, paused, all): Defaults to active. ### `get_brief`: Get a brief Everything about one brief: what it looks for, its filters and sources, its AI scoring settings, the latest run (status, creators found, cost, log), scoring progress and inbox counts. Searches can only be started in the app, not through this connection. - Permission: `briefs:read` - Changes data: no - Parameters: - `brief_id` (integer, required): The brief, from list_briefs. ### `list_candidates`: List a brief's creators Lists the creators in one brief's inbox with their AI score, one-line summary, style tags, stats and pipeline status. Use candidate_id from here with get_creator and the write tools. Sorted by best score unless you choose otherwise. - Permission: `creators:read` - Changes data: no - Parameters: - `brief_id` (integer, required): The brief, from list_briefs. - `status` (string) (one of: new, shortlisted, outreach, booked, rejected, all): Inbox stage. outreach means contacted, replied or negotiating; booked includes delivered; rejected includes not interested. Defaults to new. - `sort` (string) (one of: score, recent, followers, engagement): Defaults to score. - `min_score` (integer): Only creators with at least this AI score (0 to 100). Optional. - `limit` (integer): 1 to 100, default 25. - `offset` (integer): For paging. Default 0. ### `get_creator`: Get a creator Full detail on one creator in a brief: profile, stats, contact emails, recent post captions, the AI score breakdown with evidence, the team's rating, deal notes, follow-up date, outreach history, and their track record (collaboration reviews and Spark Ads results). - Permission: `creators:read` - Changes data: no - Parameters: - `candidate_id` (integer, required): The creator in a brief, from list_candidates. ### `search_creators`: Search your creator database Searches every creator this account has found before, across all brands and briefs, by words in their handle, bio, captions and AI tags, plus filters. Free: it doesn't touch paid data sources. Use profile_id from here with add_creators_to_brief. - Permission: `creators:read` - Changes data: no - Parameters: - `query` (string): Words to match, like "kitchen demo". Optional. - `platform` (string) (one of: tiktok, instagram): Optional. - `min_followers` (integer): Optional. - `max_followers` (integer): Optional. - `has_email` (boolean): Only creators with a public email. Optional. - `worked_with` (boolean): Only creators the account has booked or reviewed. Optional. - `sort` (string) (one of: score, rating, followers, recent): Defaults to score. - `limit` (integer): 1 to 100, default 25. ### `list_followups_due`: List follow-ups due Lists creators whose follow-up date is today or earlier and who are still in outreach (contacted, replied or negotiating), oldest first. - Permission: `outreach:read` - Changes data: no - Parameters: none ### `list_outreach`: List outreach Lists creators in outreach across all brands, with status, last message sent, follow-up date and quoted rate. - Permission: `outreach:read` - Changes data: no - Parameters: - `status` (string) (one of: active, booked, declined, all): active means contacted, replied or negotiating. Defaults to active. - `brand_id` (integer): Only this brand. Optional. ### `list_templates`: List outreach templates Lists a brand's outreach templates (pitch, pricing request, follow-up, direct message and custom ones) with their subject and body. Use template_id with draft_outreach. - Permission: `outreach:read` - Changes data: no - Parameters: - `brand_id` (integer, required): The brand, from list_brands. ### `get_spend`: Get spending This month's spending on data sources and AI, against the monthly cap, broken down by provider. - Permission: `spend:read` - Changes data: no - Parameters: none ### `create_brief`: Create a brief Creates a brief: a saved description of the creators a brand wants. It does not start a search; the user runs searches in the app. Describe the creators in plain words in description; keywords and hashtags are optional (AI suggests search terms on the first run). - Permission: `briefs:write` - Changes data: yes (supports `dry_run`) - Parameters: - `brand_id` (integer, required): The brand, from list_brands. - `name` (string, required): Short name, like "Kitchen demo creators". - `description` (string, required): Who you are looking for, in plain words. - `platforms` (array of string) (items: tiktok, instagram): Defaults to both. - `keywords` (string): Comma-separated search phrases. Optional. - `hashtags` (string): Comma-separated, without #. Optional. - `content_style` (string): The videos you want, like "face to camera product demos". Optional. - `min_followers` (integer): Optional. - `max_followers` (integer): Optional. - `regions` (string): Comma-separated two-letter country codes. Optional; leaving it empty finds more creators. - `require_email` (boolean): Only keep creators with a public email. Default false. - `max_results` (integer): Creators per source per run, 5 to 200. Default 50. - `dry_run` (boolean): Preview the change without saving anything. Defaults to false. Use it to show the user what would happen first. ### `update_brief`: Update a brief Changes a brief's settings. Only the fields you pass change. Setting status to paused stops scheduled runs. It cannot start a search. - Permission: `briefs:write` - Changes data: yes (supports `dry_run`) - Parameters: - `brief_id` (integer, required): The brief, from list_briefs. - `name` (string) - `description` (string) - `keywords` (string) - `hashtags` (string) - `content_style` (string) - `min_followers` (integer) - `max_followers` (integer) - `regions` (string) - `require_email` (boolean) - `max_results` (integer) - `status` (string) (one of: active, paused) - `dry_run` (boolean): Preview the change without saving anything. Defaults to false. Use it to show the user what would happen first. ### `set_candidate_status`: Move creators in the pipeline Moves up to 50 creators to a pipeline status: new, shortlisted, contacted, replied, negotiating, booked, delivered, declined (not interested) or rejected. Creators marked Do not contact can't be moved into outreach. - Permission: `creators:write` - Changes data: yes (supports `dry_run`) - Parameters: - `candidate_ids` (array of integer, required): From list_candidates. Up to 50. - `status` (string, required) (one of: new, shortlisted, contacted, replied, negotiating, booked, delivered, declined, rejected) - `dry_run` (boolean): Preview the change without saving anything. Defaults to false. Use it to show the user what would happen first. ### `rate_candidate`: Rate a creator Records the team's verdict on a creator for this brand: up (good fit), down (not a fit) or clear, with an optional reason. The AI scorer learns from the last ten verdicts for each brand. - Permission: `creators:write` - Changes data: yes (supports `dry_run`) - Parameters: - `candidate_id` (integer, required): From list_candidates. - `rating` (string, required) (one of: up, down, clear) - `note` (string): Why, in a sentence. Optional. - `dry_run` (boolean): Preview the change without saving anything. Defaults to false. Use it to show the user what would happen first. ### `add_creators_to_brief`: Add creators from your database to a brief Adds up to 50 creators the account already has (profile_id from search_creators) to a brief. Free: no paid search. If the brief has AI scoring on, the new creators are scored, which uses a little AI spend. - Permission: `creators:write` - Changes data: yes (supports `dry_run`) - Parameters: - `brief_id` (integer, required): The brief, from list_briefs. - `profile_ids` (array of integer, required): From search_creators. Up to 50. - `dry_run` (boolean): Preview the change without saving anything. Defaults to false. Use it to show the user what would happen first. ### `update_deal`: Update deal notes Records a creator's quoted rate, deliverables, usage rights, notes and follow-up date. Only the fields you pass change; pass an empty string to clear one. - Permission: `creators:write` - Changes data: yes (supports `dry_run`) - Parameters: - `candidate_id` (integer, required): From list_candidates. - `quoted_rate` (string): Like "$250 per video". - `deliverables` (string) - `usage_rights` (string) - `deal_notes` (string) - `follow_up_date` (string): YYYY-MM-DD, or empty to clear. - `dry_run` (boolean): Preview the change without saving anything. Defaults to false. Use it to show the user what would happen first. ### `draft_outreach`: Draft an outreach message Writes a draft message to a creator from one of the brand's templates, with an AI-written opening line based on their posts, and the required unsubscribe footer for emails. It never sends anything: the user sends it from their own mail app. A dry run previews the template without the AI line. - Permission: `outreach:write` - Changes data: yes (supports `dry_run`) - Parameters: - `candidate_id` (integer, required): From list_candidates. - `template_id` (integer, required): From list_templates. - `ai_opening_line` (boolean): Write a personal opening line with AI. Default true. - `dry_run` (boolean): Preview the change without saving anything. Defaults to false. Use it to show the user what would happen first. ### `mark_outreach_sent`: Mark a message as sent Records that the user sent a draft (from draft_outreach) from their own mail app. The creator moves to contacted and gets a follow-up reminder. Refused if the creator unsubscribed, or if an email draft lost its unsubscribe footer. - Permission: `outreach:write` - Changes data: yes (supports `dry_run`) - Parameters: - `message_id` (integer, required): The draft, from draft_outreach. - `follow_up_days` (integer): 0 for no reminder, up to 30. Defaults to the brand's setting. - `dry_run` (boolean): Preview the change without saving anything. Defaults to false. Use it to show the user what would happen first. ## Example ```json {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_candidates","arguments":{"brief_id":12,"status":"shortlisted","limit":10}}} ```