openaffiliate-mcp
Server Details
Search and discover affiliate programs with agent-ready data and commission details.
- Status
- Healthy
- Uptime
- 100.0% over 69 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- Affitor/open-affiliate
- GitHub Stars
- 0
TDQS
Scored across 5 tools
Each tool targets a distinct action in the lifecycle: category browsing, keyword search, detail lookup, submission, and status polling. Descriptions go further than most by explicitly naming when NOT to use a tool and which tool to call instead (e.g. get_program vs search_programs vs submit_program), eliminating overlap.
All five tools follow a strict snake_case verb_noun pattern: get_program, get_submission_status, list_categories, search_programs, submit_program. The verbs (get/list/search/submit) are semantically meaningful and used consistently.
Five tools is exactly the surface needed for a program registry: discover, inspect, browse categories, submit, and track submission. No tool is redundant and none feels like filler for the stated scope.
The lifecycle is well covered end-to-end, including category browsing, discovery, detail retrieval, submission, and status polling with rejection reasons. Minor gaps exist: no way to withdraw or update a queued submission, and no dedicated comparison/ranking tool beyond commission-type filtering in search_programs.
Available Tools
5 toolsget_programGet ProgramARead-onlyIdempotentInspect
Use with a known slug or alias to read full program details, status, agentPrompt recommendation guidance, restrictions, signup information, and a citable markdownUrl. Also returns paused entries and dated answers with alternatives for discontinued or no_program brands. Do not use for broad discovery; call search_programs first if the slug is unknown. Read status and agentPrompt before recommending; if no entry exists, use search_programs to find a match.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | Use the slug from search_programs results or the final segment of a program URL (e.g. /programs/vercel). Aliases resolve to the canonical program |
Output Schema
| Name | Required | Description |
|---|---|---|
| oas | No | OAS, the OpenAffiliate Score: how clearly the program publishes its terms and protects its partners. Omitted when the program is not scored or OAS is not published |
| url | Yes | Brand's product or website URL |
| kind | No | Income program model: affiliate commissions, customer referrals, creator payouts, revenue sharing, cashback or a partner network; omitted when unspecified or discontinued/no_program |
| logo | Yes | Text logo placeholder: the uppercase first character of the brand name, not an image URL |
| name | Yes | Display name of the program or brand |
| slug | Yes | Canonical slug, including when the input was an alias |
| tags | Yes | Searchable product and program tags; empty when none are stored |
| stars | Yes | Legacy star-count placeholder, currently always 0; not a program quality score |
| alsoOn | No | Additional marketplace listings; null when none are stored, omitted for discontinued/no_program |
| answer | No | Answer explaining the lack of an affiliate program, dated when a check date exists; only returned for discontinued/no_program |
| payout | Yes | Published payout terms; empty when terms are unverified or no program exists |
| source | No | Registry source identifier or URL; omitted when unspecified |
| status | No | Availability: active is listed in search; paused is temporarily unavailable; discontinued means closed; no_program means no public program found. Non-active entries are excluded from search; missing status defaults to active |
| aliases | No | Alternative slugs accepted by get_program; empty when none are stored |
| network | No | Affiliate network identifier, such as partnerstack or in-house; null when unknown, omitted for discontinued/no_program |
| approval | No | Application approval process: auto, manual or invite-only; omitted when unverified, unspecified or discontinued/no_program |
| category | Yes | Exact registry category name, as returned by list_categories |
| verified | Yes | True when the terms have been checked on the brand's own program page; false means unconfirmed |
| claimedBy | No | Verified owner domain that claimed the listing, never an email address; null when unclaimed |
| createdAt | Yes | Registry entry creation date in YYYY-MM-DD form; empty when unspecified |
| signupUrl | No | Affiliate signup or program URL; omitted when not stored or status is discontinued/no_program |
| updatedAt | No | Registry entry update date in YYYY-MM-DD form; omitted when unspecified |
| commission | Yes | Commission structure, figures and earning conditions; unverified terms are unconfirmed, while discontinued/no_program entries return neutral placeholders |
| cookieDays | No | Attribution window in days; omitted until terms are verified |
| programAge | No | How long the program has existed, as source text without a fixed unit; null when unspecified, omitted for discontinued/no_program |
| statusNote | No | Explanation and source for the program's status; null when unspecified |
| agentPrompt | Yes | Recommendation guidance and conditions; read before recommending |
| attribution | No | Referral attribution model, such as last-click; omitted when unspecified or discontinued/no_program |
| description | Yes | Full product and program description; unverified cookie, payout and approval claims are withheld |
| markdownUrl | Yes | Citable program page in Markdown on openaffiliate.dev |
| submittedBy | Yes | Registry submitter identifier; defaults to community |
| alternatives | No | Verified, active cash-paying alternatives in the same category; only returned for discontinued/no_program, empty when none match |
| apiAvailable | No | Whether an affiliate API is available; omitted when unspecified or discontinued/no_program, not an implied false |
| approvalTime | No | Expected application review time as source text; null when unspecified, omitted when unverified or discontinued/no_program |
| dashboardUrl | No | Affiliate dashboard URL; null when unspecified, omitted for discontinued/no_program |
| restrictions | No | Program rules and prohibited promotion methods; unverified term claims are withheld; empty when none remain, omitted for discontinued/no_program |
| agentKeywords | No | Semantic keywords for matching user needs; empty when none are stored |
| agentUseCases | No | Recommendation scenarios; unverified term claims are withheld; empty when none remain |
| payoutMethods | No | Same methods as payout.methods; empty when none are stored, omitted when unverified or discontinued/no_program |
| lastVerifiedAt | No | Date terms were checked, in YYYY-MM-DD form; null when unspecified, omitted for unverified or discontinued/no_program entries |
| trackingMethod | No | How referrals are tracked, such as cookie, link or coupon; omitted when unspecified or discontinued/no_program |
| statusCheckedAt | No | YYYY-MM-DD date the discontinued/no_program status was checked, not verification of terms; omitted for other statuses or when no check date is stored |
| dedicatedManager | No | Whether a dedicated affiliate manager is provided; omitted when unspecified or discontinued/no_program, not an implied false |
| oasMachineChecks | No | Machine checks shown on the OAS report, not counted in OAS; omitted when there are none to show |
| shortDescription | Yes | Brief product summary; unverified cookie, payout and approval claims are withheld |
| commissionDuration | No | Same duration text as commission.duration; null when unspecified, omitted for discontinued/no_program |
| marketingMaterials | No | Whether promotional assets are provided; omitted when unspecified or discontinued/no_program, not an implied false |
| commissionConditions | No | Same earning conditions as commission.conditions; null when unavailable, omitted for discontinued/no_program |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds behavioral context beyond annotations by naming return categories: paused entries, dated answers, alternatives for discontinued/no_program brands, and a citable markdownUrl. It also prescribes reading status and agentPrompt before recommending, though it does not mention permissions or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the primary action and return content, followed by usage constraints and prerequisite checks. It is somewhat long, but each sentence carries distinct routing or behavioral guidance. Minor tightening could improve it, but nothing is redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not explain return values, but it still summarizes returned content usefully. It covers purpose, alternatives, prerequisite checks, and caveats for missing or discontinued entries. Nothing an agent needs to invoke it correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the slug parameter is already fully documented, including alias resolution and URL-segment examples. The description repeats that the slug must be known or an alias but adds no syntax, format, or edge-case detail beyond the schema. Baseline 3 is appropriate when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: read full program details using a known slug or alias. It explicitly contrasts this with sibling search_programs, saying it is not for broad discovery. An agent can distinguish it from list_categories and search_programs without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use guidance: only with a known slug or alias, and call search_programs first if the slug is unknown. It also says to read status and agentPrompt before recommending, and to use search_programs if no entry exists. These are clear conditions and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_submission_statusGet Submission StatusARead-onlyIdempotentInspect
Use with an id from submit_program to read where a submitted program is: queued, verifying, listed (with listingUrl and, once scored, reportUrl) or rejected (with reason). Do not use to look up listed programs; call get_program for those.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The id submit_program returned |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Submission id for get_submission_status; omitted when the domain is already listed |
| reason | No | Why a submission was rejected, in one sentence |
| status | Yes | queued: waiting for a maintainer; verifying: terms being checked on the brand's own page; listed: on OpenAffiliate; rejected: see reason |
| createdAt | No | When the submission was made, ISO 8601 |
| duplicate | No | True when this domain was already in the queue; the existing submission is returned |
| reportUrl | No | The program's OAS report when it is scored |
| statusUrl | No | REST URL that returns this submission's status |
| updatedAt | No | When its status last changed, ISO 8601 |
| listingUrl | No | The program's page on openaffiliate.dev when it is listed |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and closed-world, so the safety profile is covered. The description's added value is the state machine and which payload accompanies each state (listingUrl/reportUrl once scored, reason on rejection), which tells the agent what a partial result means. It stops short of describing polling expectations or timing, which is the main remaining gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste. The positive usage and the return states come first, with the disambiguation clause last where it is most useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present the description need not restate return shapes, and the rich annotations cover safety. What an agent still needs — input provenance, state vocabulary, and sibling routing — is all present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter is well documented, so the schema already carries the load. The description repeats the same provenance note ('an id from submit_program') and adds no format or validation detail beyond it; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (read where a submitted program is) and enumerates the exact state set it returns: queued, verifying, listed, rejected. It also names the sibling it must not be confused with, so an agent can distinguish it from get_program without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit precondition (the id must come from submit_program) and an explicit exclusion with the correct alternative: do not look up listed programs, call get_program instead. Both the when and the when-not are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_categoriesList CategoriesARead-onlyIdempotentInspect
Use to browse category names and active program counts before filtering a search. Returns all registry categories, including categories with zero active listings. Do not use for program details or commission comparisons; call search_programs with a returned category, then get_program for individual terms.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| categories | Yes | All registry categories and their active program counts, including zero counts |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint=false and destructiveHint=false, so safety is covered. The description adds a genuinely useful behavioral trait not in the annotations: the result set is exhaustive, 'including categories with zero active listings', which tells the agent not to treat empty counts as missing data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: purpose and scope first, then the completeness caveat, then the routing away to alternatives. Front-loaded and free of filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description needn't explain return values, and it still adds the zero-listing caveat. Combined with explicit routing to search_programs and get_program, an agent has everything needed to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, which is the baseline 4 case. There is no parameter syntax to clarify, and the description correctly frames the tool as a parameterless listing rather than implying hidden filters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('browse category names and active program counts') and distinguishes itself from siblings by naming search_programs and get_program as the tools for downstream needs. An agent can identify this as the discovery/listing step without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('before filtering a search') and when-not ('Do not use for program details or commission comparisons'), then names the exact follow-up sequence: search_programs with a returned category, then get_program. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_programsSearch ProgramsARead-onlyIdempotentInspect
Use to discover active affiliate programs by keyword, category, commission type, or verified status. Returns matching summaries with canonical slugs, commission figures, signup links, and citable markdownUrl fields. Do not use to check a known brand's paused or no-program status; call get_program with its slug. Call list_categories for category names, then get_program for recommendation guidance and restrictions before recommending a match.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Search keyword to match against name, description, tags, or category | |
| category | No | Filter by exact category name as returned by list_categories (case-sensitive, not a slug), e.g. 'AI', 'Email Marketing' | |
| verified_only | No | When true, return only programs whose terms were checked on the brand's own program page. False or omitted includes unverified programs with unconfirmed terms | |
| commission_type | No | Filter by payment structure: recurring = paid on each renewal within the commission duration; one-time = paid once per qualifying referral; tiered = commission varies by performance level. Omit to include all types, including hybrid |
Output Schema
| Name | Required | Description |
|---|---|---|
| programs | Yes | Matching active programs; empty when no listings match |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, closed-world behavior, so the safety profile is covered. The description adds value beyond that: it describes what results look like (canonical slugs, commission figures, signup links, citable markdownUrl) and scopes the search to active programs only. It does not discuss pagination or result limits, so it stops just short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the primary use case, then routing constraints in descending order of importance. The final sentence bundles two instructions (list_categories, then get_program) which is slightly dense, but every clause carries actionable routing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still summarizes the return fields so the agent knows slugs and markdownUrl are available for citation. For a zero-required-param search tool with full schema coverage and a clear sibling map, nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters are already documented with the enum and case-sensitivity rules. The description restates the filter dimensions (keyword, category, commission type, verified status) but adds no syntax or format guidance beyond the schema, which is the expected baseline here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (discover affiliate programs) with the searchable dimensions (keyword, category, commission type, verified status) and the returned shape. It also explicitly differentiates itself from get_program and list_categories, so the agent can pick between siblings without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names positive conditions (discovery by keyword/category/commission/verified), an explicit exclusion (do not use to check a known brand's paused status — use get_program with its slug), and a prerequisite workflow (list_categories for category names, get_program for recommendation guidance before recommending).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_programSubmit ProgramAIdempotentInspect
Use when get_program and search_programs do not find a brand's affiliate program: queues the brand's own program page for a maintainer to verify against the brand's published terms. Not instant: nothing is listed and no score exists until the terms are verified. A domain already listed returns its listingUrl instead; a domain already queued returns the existing submission. Send the brand's own program or partners page, never a network or review site. Never invent terms. Then call get_submission_status with the returned id.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Brand or program name, up to 100 characters | |
| note | No | Optional note for the maintainer, up to 1000 characters | |
| contact | No | Optional email for the person submitting; never shown publicly and never returned by any tool | |
| termsUrl | No | https:// link to the page that states the program's terms, when it is a different page | |
| programUrl | Yes | https:// link to the affiliate or partner program page on the brand's own website |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Submission id for get_submission_status; omitted when the domain is already listed |
| reason | No | Why a submission was rejected, in one sentence |
| status | Yes | queued: waiting for a maintainer; verifying: terms being checked on the brand's own page; listed: on OpenAffiliate; rejected: see reason |
| createdAt | No | When the submission was made, ISO 8601 |
| duplicate | No | True when this domain was already in the queue; the existing submission is returned |
| reportUrl | No | The program's OAS report when it is scored |
| statusUrl | No | REST URL that returns this submission's status |
| updatedAt | No | When its status last changed, ISO 8601 |
| listingUrl | No | The program's page on openaffiliate.dev when it is listed |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses that nothing is listed and no score exists until a maintainer verifies terms, and it spells out concrete idempotency behavior (already-listed domain returns its listingUrl; already-queued domain returns the existing submission). Annotations give idempotentHint=true, and this description makes that hint actionable rather than just declarative.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the trigger condition, then dedup behavior, then URL constraint, then next step. No sentence is redundant despite the density.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the trigger, the async/manual verification model, duplicate handling, source-quality rules, and the follow-up tool. An output schema exists and the description still names the returned id used for status polling, so nothing an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds a real constraint beyond the schema by restricting programUrl sourcing to the brand's own program or partners page and forbidding invented terms. Other parameters (note, contact, termsUrl, name) are left to the schema, which handles them adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (queues for verification) plus resource (the brand's own affiliate program page) and an explicit statement of what the tool is not for. An agent can distinguish it from get_program and search_programs without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the precondition explicitly ("Use when get_program and search_programs do not find a brand's affiliate program"), adds a hard exclusion on what URL to send (never a network or review site), and prescribes the follow-up call to get_submission_status.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
- Added
get_submission_status - Added
submit_program
1 tool update
- Changed
get_program1 field changed- added
Output schema / properties / oasMachineChecksAdded value: +{ + "description": "Machine checks shown on the OAS report, not counted in OAS; omitted when there are none to show", + "items": { + "additionalProperties": false, + "properties": { + "id": { + "description": "A1 program page is live; P5 Core Web Vitals (mobile); P6 estimated monthly brand-query search volume (Google Ads, worldwide)", + "enum": [ + "A1", + "P5", + "P6" + ], + "type": "string" + }, + "label": { + "description": "The check's name as the report shows it", + "type": "string" + }, + "measuredAt": { + "description": "Measurement date, YYYY-MM-DD", + "type": "string" + }, + "measurement": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "status": { + "const": 200, + "description": "HTTP status of the listed program page", + "type": "number" + } + }, + "required": [ + "status" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "data": { + "const": "field", + "description": "Real-user data (Chrome UX Report)", + "type": "string" + }, + "notGood": { + "description": "Core Web Vitals not in the good range; empty when all are", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "data", + "notGood" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "cls": { + "description": "Cumulative Layout Shift", + "type": "number" + }, + "data": { + "const": "lab", + "description": "Lab test, no real-user data", + "type": "string" + }, + "lcpMs": { + "description": "Largest Contentful Paint, ms", + "type": "number" + }, + "tbtMs": { + "description": "Total Blocking Time, ms, standing in for INP", + "type": "number" + } + }, + "required": [ + "data", + "lcpMs", + "cls", + "tbtMs" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "reached": { + "description": "Whether the estimate reaches the threshold", + "type": "boolean" + }, + "scope": { + "const": "worldwide", + "description": "Search volume scope", + "type": "string" + }, + "threshold": { + "description": "Monthly searches the check requires", + "type": "number" + } + }, + "required": [ + "scope", + "threshold", + "reached" + ], + "type": "object" + } + ], + "description": "The typed measurement behind the reading" + }, + "met": { + "description": "True when the check is met", + "type": "boolean" + }, + "reading": { + "description": "What was measured, in words, naming its data and thresholds", + "type": "string" + }, + "ruleset": { + "description": "The rule set that produced the reading", + "type": "string" + }, + "source": { + "description": "Where the reading comes from", + "enum": [ + "http", + "pagespeed", + "dataforseo" + ], + "type": "string" + }, + "target": { + "description": "What was measured: the listed program URL (A1), the brand URL (P5) or the exact search query (P6)", + "type": "string" + }, + "validUntil": { + "description": "First day the reading lapses (90 days after measuredAt), YYYY-MM-DD", + "type": "string" + } + }, + "required": [ + "id", + "label", + "met", + "reading", + "source", + "target", + "measurement", + "ruleset", + "measuredAt", + "validUntil" + ], + "type": "object" + }, + "type": "array" +}
1 tool update
- Changed
get_program1 field changed- added
Output schema / properties / oasAdded value: +{ + "additionalProperties": false, + "description": "OAS, the OpenAffiliate Score: how clearly the program publishes its terms and protects its partners. Omitted when the program is not scored or OAS is not published", + "properties": { + "checkedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Date the scored terms were verified, YYYY-MM-DD" + }, + "grade": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Letter grade for the score (A+ to F); null when score is null" + }, + "reportUrl": { + "description": "The program's full OAS report", + "type": "string" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "OAS 0-100 as the program page shows it; null while scoring is in progress or the verified terms are older than 90 days" + }, + "status": { + "description": "scored: a current score; stale: terms verified more than 90 days ago; in_progress: some terms not read yet", + "enum": [ + "scored", + "stale", + "in_progress" + ], + "type": "string" + }, + "summary": { + "description": "One line: the verdict when scored, otherwise why there is no score", + "type": "string" + }, + "validUntil": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "First day the score lapses unless the terms are verified again (90 days after checkedAt), YYYY-MM-DD" + }, + "version": { + "description": "Scoring method version, such as v1", + "type": "string" + } + }, + "required": [ + "score", + "grade", + "status", + "summary", + "checkedAt", + "validUntil", + "version", + "reportUrl" + ], + "type": "object" +}
1 tool update
- Changed
get_program1 field changed- changed
Output schema / properties / alternatives / descriptionPrevious value: -"Verified, active cash-paying alternatives in the same category, excluding same-team brands; only returned for discontinued/no_program, empty when none match"New value: +"Verified, active cash-paying alternatives in the same category; only returned for discontinued/no_program, empty when none match"
1 tool update
- Changed
get_program1 field changed- added
Output schema / properties / payout / properties / conditionsAdded value: +{ + "description": "When a commission becomes payable, in the terms' own words (hold period, payout cycle, withdrawal rule); omitted when unspecified or terms are withheld", + "type": "string" +}
3 tool updates
- Changed
get_program2 fields changed- changed
Input schema / properties / slug / descriptionPrevious value: -"Program slug (e.g. 'anthropic-claude')"New value: +"Use the slug from search_programs results or the final segment of a program URL (e.g. /programs/vercel). Aliases resolve to the canonical program" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "agentKeywords": { + "description": "Semantic keywords for matching user needs; empty when none are stored", + "items": { + "type": "string" + }, + "type": "array" + }, + "agentPrompt": { + "description": "Recommendation guidance and conditions; read before recommending", + "type": "string" + }, + "agentUseCases": { + "description": "Recommendation scenarios; unverified term claims are withheld; empty when none remain", + "items": { + "type": "string" + }, + "type": "array" + }, + "aliases": { + "description": "Alternative slugs accepted by get_program; empty when none are stored", + "items": { + "type": "string" + }, + "type": "array" + }, + "alsoOn": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "affitor": { + "additionalProperties": false, + "description": "The same brand on the Affitor marketplace; omitted when no Affitor entry is stored", + "properties": { + "commission": { + "additionalProperties": false, + "description": "Commission published on Affitor, separate from this listing's terms; omitted when Affitor publishes none", + "properties": { + "conditions": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Conditions for earning commission; unverified cookie, payout and approval claims are withheld; null or omitted when unavailable" + }, + "currency": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Currency code for monetary amounts; null when unspecified" + }, + "duration": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "How long commissions are earned, as source text such as '12 months' or 'lifetime'; null or omitted when unspecified" + }, + "mode": { + "description": "Figure format: percentage uses percent units, flat uses currency units, tiered and hybrid require rate/conditions to interpret; unknown means no published figure", + "enum": [ + "percentage", + "flat", + "tiered", + "hybrid", + "unknown" + ], + "type": "string" + }, + "rate": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Raw source wording; prefer mode and value" + }, + "type": { + "description": "Payment structure: recurring pays on renewals within duration; one-time pays once per qualifying referral; tiered varies by performance level; hybrid combines structures; none is a neutral placeholder for discontinued/no_program entries", + "enum": [ + "recurring", + "one-time", + "tiered", + "hybrid", + "none" + ], + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Commission in percent units for percentage mode (30 means 30%), or currency units for flat mode; null when no single numeric figure is available" + } + }, + "required": [ + "type", + "mode", + "value", + "rate", + "currency" + ], + "type": "object" + }, + "url": { + "description": "URL of the same brand's Affitor marketplace program", + "type": "string" + } + }, + "required": [ + "url" + ], + "type": "object" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Additional marketplace listings; null when none are stored, omitted for discontinued/no_program" + }, + "alternatives": { + "description": "Verified, active cash-paying alternatives in the same category, excluding same-team brands; only returned for discontinued/no_program, empty when none match", + "items": { + "additionalProperties": false, + "properties": { + "commission": { + "description": "Formatted commission figure and payment structure for display; includes percent or currency units when known", + "type": "string" + }, + "name": { + "description": "Alternative program's display name", + "type": "string" + }, + "slug": { + "description": "Canonical alternative slug to pass to get_program", + "type": "string" + }, + "url": { + "description": "Alternative program's page URL on openaffiliate.dev", + "type": "string" + } + }, + "required": [ + "slug", + "name", + "commission", + "url" + ], + "type": "object" + }, + "type": "array" + }, + "answer": { + "description": "Answer explaining the lack of an affiliate program, dated when a check date exists; only returned for discontinued/no_program", + "type": "string" + }, + "apiAvailable": { + "description": "Whether an affiliate API is available; omitted when unspecified or discontinued/no_program, not an implied false", + "type": "boolean" + }, + "approval": { + "description": "Application approval process: auto, manual or invite-only; omitted when unverified, unspecified or discontinued/no_program", + "type": "string" + }, + "approvalTime": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Expected application review time as source text; null when unspecified, omitted when unverified or discontinued/no_program" + }, + "attribution": { + "description": "Referral attribution model, such as last-click; omitted when unspecified or discontinued/no_program", + "type": "string" + }, + "category": { + "description": "Exact registry category name, as returned by list_categories", + "type": "string" + }, + "claimedBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Verified owner domain that claimed the listing, never an email address; null when unclaimed" + }, + "commission": { + "additionalProperties": false, + "description": "Commission structure, figures and earning conditions; unverified terms are unconfirmed, while discontinued/no_program entries return neutral placeholders", + "properties": { + "conditions": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Conditions for earning commission; unverified cookie, payout and approval claims are withheld; null or omitted when unavailable" + }, + "currency": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Currency code for monetary amounts; null when unspecified" + }, + "duration": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "How long commissions are earned, as source text such as '12 months' or 'lifetime'; null or omitted when unspecified" + }, + "mode": { + "description": "Figure format: percentage uses percent units, flat uses currency units, tiered and hybrid require rate/conditions to interpret; unknown means no published figure", + "enum": [ + "percentage", + "flat", + "tiered", + "hybrid", + "unknown" + ], + "type": "string" + }, + "rate": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Raw source wording; prefer mode and value" + }, + "type": { + "description": "Payment structure: recurring pays on renewals within duration; one-time pays once per qualifying referral; tiered varies by performance level; hybrid combines structures; none is a neutral placeholder for discontinued/no_program entries", + "enum": [ + "recurring", + "one-time", + "tiered", + "hybrid", + "none" + ], + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Commission in percent units for percentage mode (30 means 30%), or currency units for flat mode; null when no single numeric figure is available" + } + }, + "required": [ + "type", + "mode", + "value", + "rate", + "currency" + ], + "type": "object" + }, + "commissionConditions": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Same earning conditions as commission.conditions; null when unavailable, omitted for discontinued/no_program" + }, + "commissionDuration": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Same duration text as commission.duration; null when unspecified, omitted for discontinued/no_program" + }, + "cookieDays": { + "description": "Attribution window in days; omitted until terms are verified", + "type": "number" + }, + "createdAt": { + "description": "Registry entry creation date in YYYY-MM-DD form; empty when unspecified", + "type": "string" + }, + "dashboardUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Affiliate dashboard URL; null when unspecified, omitted for discontinued/no_program" + }, + "dedicatedManager": { + "description": "Whether a dedicated affiliate manager is provided; omitted when unspecified or discontinued/no_program, not an implied false", + "type": "boolean" + }, + "description": { + "description": "Full product and program description; unverified cookie, payout and approval claims are withheld", + "type": "string" + }, + "kind": { + "description": "Income program model: affiliate commissions, customer referrals, creator payouts, revenue sharing, cashback or a partner network; omitted when unspecified or discontinued/no_program", + "enum": [ + "affiliate", + "referral", + "creator-payout", + "revenue-share", + "cashback", + "partner-network" + ], + "type": "string" + }, + "lastVerifiedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Date terms were checked, in YYYY-MM-DD form; null when unspecified, omitted for unverified or discontinued/no_program entries" + }, + "logo": { + "description": "Text logo placeholder: the uppercase first character of the brand name, not an image URL", + "type": "string" + }, + "markdownUrl": { + "description": "Citable program page in Markdown on openaffiliate.dev", + "type": "string" + }, + "marketingMaterials": { + "description": "Whether promotional assets are provided; omitted when unspecified or discontinued/no_program, not an implied false", + "type": "boolean" + }, + "name": { + "description": "Display name of the program or brand", + "type": "string" + }, + "network": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Affiliate network identifier, such as partnerstack or in-house; null when unknown, omitted for discontinued/no_program" + }, + "payout": { + "additionalProperties": false, + "description": "Published payout terms; empty when terms are unverified or no program exists", + "properties": { + "currency": { + "description": "Currency code for payout.minimum; omitted when unspecified or terms are withheld", + "type": "string" + }, + "frequency": { + "description": "Payout schedule, such as monthly or net-30; omitted when unspecified or terms are withheld", + "type": "string" + }, + "methods": { + "description": "Payout methods, such as paypal or bank-transfer; empty when none are stored, omitted when terms are withheld", + "items": { + "type": "string" + }, + "type": "array" + }, + "minimum": { + "description": "Minimum payout in payout.currency units; omitted when unspecified or terms are withheld", + "type": "number" + } + }, + "type": "object" + }, + "payoutMethods": { + "description": "Same methods as payout.methods; empty when none are stored, omitted when unverified or discontinued/no_program", + "items": { + "type": "string" + }, + "type": "array" + }, + "programAge": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "How long the program has existed, as source text without a fixed unit; null when unspecified, omitted for discontinued/no_program" + }, + "restrictions": { + "description": "Program rules and prohibited promotion methods; unverified term claims are withheld; empty when none remain, omitted for discontinued/no_program", + "items": { + "type": "string" + }, + "type": "array" + }, + "shortDescription": { + "description": "Brief product summary; unverified cookie, payout and approval claims are withheld", + "type": "string" + }, + "signupUrl": { + "description": "Affiliate signup or program URL; omitted when not stored or status is discontinued/no_program", + "type": "string" + }, + "slug": { + "description": "Canonical slug, including when the input was an alias", + "type": "string" + }, + "source": { + "description": "Registry source identifier or URL; omitted when unspecified", + "type": "string" + }, + "stars": { + "description": "Legacy star-count placeholder, currently always 0; not a program quality score", + "type": "number" + }, + "status": { + "description": "Availability: active is listed in search; paused is temporarily unavailable; discontinued means closed; no_program means no public program found. Non-active entries are excluded from search; missing status defaults to active", + "enum": [ + "active", + "paused", + "discontinued", + "no_program" + ], + "type": "string" + }, + "statusCheckedAt": { + "description": "YYYY-MM-DD date the discontinued/no_program status was checked, not verification of terms; omitted for other statuses or when no check date is stored", + "type": "string" + }, + "statusNote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Explanation and source for the program's status; null when unspecified" + }, + "submittedBy": { + "description": "Registry submitter identifier; defaults to community", + "type": "string" + }, + "tags": { + "description": "Searchable product and program tags; empty when none are stored", + "items": { + "type": "string" + }, + "type": "array" + }, + "trackingMethod": { + "description": "How referrals are tracked, such as cookie, link or coupon; omitted when unspecified or discontinued/no_program", + "type": "string" + }, + "updatedAt": { + "description": "Registry entry update date in YYYY-MM-DD form; omitted when unspecified", + "type": "string" + }, + "url": { + "description": "Brand's product or website URL", + "type": "string" + }, + "verified": { + "description": "True when the terms have been checked on the brand's own program page; false means unconfirmed", + "type": "boolean" + } + }, + "required": [ + "slug", + "name", + "url", + "logo", + "category", + "commission", + "payout", + "description", + "shortDescription", + "tags", + "stars", + "verified", + "agentPrompt", + "submittedBy", + "createdAt", + "markdownUrl" + ], + "type": "object" +}
- Changed
list_categories1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "categories": { + "description": "All registry categories and their active program counts, including zero counts", + "items": { + "additionalProperties": false, + "properties": { + "count": { + "description": "Number of active listings in this category", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "name": { + "description": "Category name accepted by search_programs", + "type": "string" + } + }, + "required": [ + "name", + "count" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "categories" + ], + "type": "object" +}
- Changed
search_programs4 fields changed- changed
Input schema / properties / category / descriptionPrevious value: -"Filter by category name (e.g. 'AI & ML Tools', 'Email Marketing')"New value: +"Filter by exact category name as returned by list_categories (case-sensitive, not a slug), e.g. 'AI', 'Email Marketing'" - changed
Input schema / properties / commission_type / descriptionPrevious value: -"Filter by commission type"New value: +"Filter by payment structure: recurring = paid on each renewal within the commission duration; one-time = paid once per qualifying referral; tiered = commission varies by performance level. Omit to include all types, including hybrid" - changed
Input schema / properties / verified_only / descriptionPrevious value: -"When true, return only verified programs"New value: +"When true, return only programs whose terms were checked on the brand's own program page. False or omitted includes unverified programs with unconfirmed terms" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "programs": { + "description": "Matching active programs; empty when no listings match", + "items": { + "additionalProperties": false, + "properties": { + "category": { + "description": "Exact registry category name, as returned by list_categories", + "type": "string" + }, + "commission": { + "additionalProperties": false, + "description": "Commission structure and figures; unverified terms are unconfirmed, not guaranteed earnings", + "properties": { + "currency": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Currency code for monetary amounts; null when unspecified" + }, + "mode": { + "description": "Figure format: percentage uses percent units, flat uses currency units, tiered and hybrid require rate/conditions to interpret; unknown means no published figure", + "enum": [ + "percentage", + "flat", + "tiered", + "hybrid", + "unknown" + ], + "type": "string" + }, + "rate": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Raw source wording; prefer mode and value" + }, + "type": { + "description": "Payment structure: recurring pays on renewals within the commission duration; one-time pays once per qualifying referral; tiered varies by performance level; hybrid combines payment structures", + "enum": [ + "recurring", + "one-time", + "tiered", + "hybrid" + ], + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Commission in percent units for percentage mode (30 means 30%), or currency units for flat mode; null when no single numeric figure is available" + } + }, + "required": [ + "type", + "mode", + "value", + "rate", + "currency" + ], + "type": "object" + }, + "cookieDays": { + "description": "Attribution window in days; omitted until terms are verified", + "type": "number" + }, + "markdownUrl": { + "description": "Citable program page in Markdown on openaffiliate.dev", + "type": "string" + }, + "name": { + "description": "Display name of the program or brand", + "type": "string" + }, + "shortDescription": { + "description": "Brief product summary; unverified cookie, payout and approval claims are withheld", + "type": "string" + }, + "signupUrl": { + "description": "Affiliate signup or program URL; falls back to the brand website when no signup URL is stored", + "type": "string" + }, + "slug": { + "description": "Canonical slug to pass to get_program", + "type": "string" + }, + "verified": { + "description": "True when the terms have been checked on the brand's own program page; false means unconfirmed", + "type": "boolean" + } + }, + "required": [ + "slug", + "name", + "category", + "shortDescription", + "commission", + "verified", + "signupUrl", + "markdownUrl" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "programs" + ], + "type": "object" +}
3 tool updates
- First observed
get_program - First observed
list_categories - First observed
search_programs
Related MCP Connectors
Search 4,825 affiliate programs by commission, cookie window and network, with source confidence.
The best agent monetization tool: free search, clear rev-share, 10M+ commerce/travel/local offers.
- PartliOAuthapp.partli
Run your affiliate program from any agent: partners, commissions, payouts, bounties, recruitment.
Affiliate programs, deals, tracked links and product search, plus merchant program setup tools.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to search products across affiliate networks, compare commissions, find arbitrage opportunities, and get auto-injected affiliate links via MCP.-
- AlicenseNot gradedqualityDmaintenanceAffiliate product search for AI agents. Indexes structured merchant feeds — real prices, live stock, affiliate links built in. Works with any MCP client.MIT
- AlicenseAqualityCmaintenanceEnables AI agents to access affiliate marketing capabilities through AgentFuse's API, allowing them to browse affiliate programs, generate tracked links, and record conversions without writing HTTP code.721 npmMIT
- AlicenseAqualityCmaintenanceAgentShare delivers structured product search and pricing signals for AI agents over REST and MCP (Streamable HTTP). Responses include freshness & coverage metadata so agents can reason about data recency. API keys secure billed endpoints; public discovery at /agent.json and /mcp.json. Currently integrates connected marketplaces and affiliate feeds – roadmap expands to global e-commerce (AliExpre41MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.