Kunkafa
Server Details
Market forecasts with their own track record, inside Claude, ChatGPT and other MCP apps.
- Status
- Healthy
- Uptime
- 100.0% over 23 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- Kareemfarid/kunkafa-mcp
- GitHub Stars
- 0
TDQS
Scored across 9 tools
Most tools have clearly distinct purposes: follow/unfollow_market handle subscriptions, list_markets enumerates markets, and the get_* tools target different data (outlooks, performance, results, usage, glossary, account links). The only mild overlap is between get_performance (aggregate hit rates) and get_results (example forecasts with outcomes), but the descriptions clarify the distinction.
All nine tools follow a strict verb_noun snake_case pattern (follow_market, unfollow_market, list_markets, get_outlooks, get_performance, get_results, get_usage, get_glossary, get_account_links). No deviations or mixed conventions.
Nine tools is well-scoped for a market forecast API covering discovery, subscription management, data retrieval, and metadata. Each tool earns its place with no obvious redundancy.
The surface covers the core lifecycle: list markets, follow/unfollow, read forecasts, check performance and sample results, plus usage and glossary helpers. Minor gaps exist (no way to retrieve a full historical record — get_results is explicitly partial — and outlooks are restricted to one market per call by design), but agents can work around these.
Available Tools
9 toolsfollow_marketFollow a marketADestructiveIdempotentInspect
Follow a market for this account. Check canFollow in get_usage first. Replacing a followed market is allowed once every 30 days: ask the user, then call with confirmReplacement true.
| Name | Required | Description | Default |
|---|---|---|---|
| market | Yes | Market slug from list_markets, for example bitcoin | |
| confirmReplacement | No | Set true only after the user agreed to replace a market they already follow |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| usage | Yes | |
| dataUse | Yes | Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model. |
| notices | Yes | |
| following | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true. The description adds the critical behavioral context that replacement is allowed only once every 30 days and requires user confirmation via confirmReplacement. It does not elaborate on what 'replacement' destroys, but the rate limit and confirmation requirement go beyond annotations.
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 short sentences, front-loaded with the action, then prerequisites, then the edge-case workflow. No waste.
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 core action, prerequisite check, and the replacement edge case. With an output schema present, return values need not be explained. Minor gap: does not state what happens on success or how follow relates to unfollow_market, but sufficient for correct invocation.
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 both parameters are fully documented in the schema. The description reinforces the confirmReplacement semantics ('ask the user, then call with confirmReplacement true') but adds no new format or constraint detail beyond the schema. Baseline 3 is appropriate.
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?
Clear verb+resource: 'Follow a market for this account.' Distinguishes from unfollow_market by name. Does not explicitly contrast with siblings like list_markets, but the action is unambiguous.
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?
Explicitly says to check canFollow in get_usage first, names the alternative workflow, and states the 30-day rule with the required user confirmation step. This is exactly the kind of conditional routing an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_account_linksKunkafa account linksCRead-onlyInspect
Links to create an account, sign in and manage connections.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| mcp | Yes | |
| links | Yes | |
| disclosureUnits | Yes | |
| mcpAvailability | Yes | Public availability follows release controls. |
| availabilityMessage | Yes | |
| browserConfirmationRequired | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, and the description adds nothing behavioral on top of that — no indication of what the returned links are for, whether they expire, or whether auth is required. The phrase 'create an account, sign in' could even be misread as a write operation, though it most plausibly describes the purpose of the returned links.
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?
A single short sentence with no padding, but it is under-specified rather than genuinely concise — the sentence is ambiguous about what is returned and does not front-load a clear action verb.
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 return values need not be described, and there are no parameters to document. However, for a discovery tool the description still leaves the core question — what these links are and when an agent should fetch them — unresolved.
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, so the schema carries the full contract and the description has nothing to compensate for. Baseline 4 applies for a no-parameter tool.
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 name and description both center on 'links', but the description is a bare noun phrase with no verb and ambiguous grammar: it is unclear whether the tool returns URLs for account creation/sign-in/connection management or performs those actions itself. It conveys the resource loosely but does not clearly distinguish it from siblings like get_usage or get_performance.
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?
No when-to-use guidance, no prerequisites, and no mention of any alternative tool. The agent is left to infer that this is a discovery/helper call with no stated trigger condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_glossaryGlossaryARead-onlyInspect
What every Kunkafa term and number means and how to read them. Call once before explaining results. No sign-in needed.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| glossary | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, non-destructive and closed-world, so safety is covered. The description adds two pieces of non-structured behavior: no authentication is required, and the call is a one-time lookup (implying the content is static/cacheable). That is genuine added context beyond the annotations.
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 short sentences, front-loaded with what the tool is, followed by the when and the auth note. Every sentence earns its place with no 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 need not describe return values, and it correctly covers purpose, timing and auth. For a zero-param reference tool this is essentially complete, with only marginal room to say anything more.
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. Nothing in the description could add parameter meaning, and none is needed.
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 that the tool returns the meaning of Kunkafa terms and numbers plus how to read them, which is a specific resource and clearly not one of the data-retrieval siblings (get_performance, get_results, etc.). It stops short of literally naming it a glossary lookup, but the intent is unambiguous.
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?
"Call once before explaining results" gives an explicit trigger and a usage cadence, which is exactly the context an agent needs to decide when to invoke it. It doesn't name alternatives, but no sibling overlaps this reference-lookup function, so no exclusion is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_outlooksCurrent forecastsARead-onlyInspect
Current forecasts for one market; one market per call by design, so data is not pulled in bulk. Choose durations (exact or a range) and optionally direction, confidence or target filters. At most 6 durations and 72 forecasts per call; calls can run in parallel.
| Name | Required | Description | Default |
|---|---|---|---|
| market | Yes | Market slug from list_markets, for example bitcoin | |
| direction | No | Default both | |
| durations | No | Exact duration labels from list_markets, for example ["1 hour", "6 hours"] | |
| maxDuration | No | Longest duration to include, for example "1 day" | |
| minDuration | No | Shortest duration to include, for example "1 hour" | |
| maxTargetPercent | No | Only targets at most this far from the reference price, in percent | |
| minTargetPercent | No | Only targets at least this far from the reference price, in percent | |
| maxDurationExclusive | No | true for "less than maxDuration"; default includes maxDuration | |
| maxProbabilityPercent | No | Only forecasts whose probability is at most this | |
| minProbabilityPercent | No | Only forecasts whose probability (Kunkafa's confidence) is at least this |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| usage | Yes | |
| dataUse | Yes | Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model. |
| notices | Yes | |
| fieldGuide | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds genuinely useful non-annotation behavior: hard limits of 6 durations and 72 forecasts per call, the single-market constraint, and that calls may be parallelized. It does not describe ordering or truncation behavior when the 72-forecast cap bites.
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, front-loaded with the purpose and cardinality constraint before the filtering and limit details. No sentence is filler; the 'so data is not pulled in bulk' clause earns its place by pre-empting a bulk-query attempt.
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, return values need no explanation, and all 10 parameters are schema-documented, so the core is complete. What is still missing is the relationship to adjacent tools (get_results, get_performance) and any note on result ordering or what happens at the 72-forecast ceiling.
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 every parameter is already documented in the schema, which sets the baseline at 3. The description paraphrases the filter dimensions (duration exact-or-range, direction, confidence, target) but adds no syntax, default, or interaction detail beyond what the schema states.
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 resource (current forecasts) and a specific scope (one market per call), which immediately separates it from list_markets or get_results. The 'one market per call by design' clause clarifies the cardinality an agent might otherwise guess wrong. It does not explicitly name a sibling tool, so it stops short of a 5.
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 concrete guidance on how to shape a call ('choose durations (exact or a range) and optionally direction, confidence or target filters'), which is usable context. However it never says when to prefer this tool over get_results, get_performance, or list_markets, so the routing decision 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.
get_performancePast performanceBRead-onlyInspect
How often past forecasts touched their target, by confidence level and period. Pass probabilityPercent for the matching row (headline).
| Name | Required | Description | Default |
|---|---|---|---|
| market | Yes | Market slug from list_markets, for example bitcoin | |
| probabilityPercent | No | A forecast's confidence; the headline shows past results at the nearest published level at or below it |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| usage | Yes | |
| dataUse | Yes | Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model. |
| notices | Yes | |
| headline | Yes | |
| fieldGuide | Yes | Plain meanings of the returned fields. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered without description help. The description adds the behavioral nuance that results are grouped by confidence level and period, but says nothing about auth, rate limits, or pagination; with an output schema present, return-shape disclosure is not required.
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 short sentences with the primary purpose front-loaded and no filler. The trailing parenthetical '(headline)' is slightly cryptic but does not bloat the text.
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?
For a two-parameter read-only lookup with a full output schema and complete annotation coverage, the description supplies the essential framing plus the optional-parameter usage hint. The only real omission is routing guidance relative to sibling tools, which is a minor gap at this complexity level.
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 both parameters are already documented, including the 'nearest published level at or below it' rounding rule. The description's remark about probabilityPercent selects the 'headline' row, which adds only marginal framing beyond what the schema already states.
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 names a specific resource (past forecast performance) and its dimensions of aggregation (confidence level and period), which is more informative than the title 'Past performance'. It does not, however, distinguish itself from near-neighbors like get_results or get_outlooks, so an agent must infer the boundary.
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?
There is no statement of when to call this versus the sibling tools, and no prerequisites. The only usage-like sentence ('Pass probabilityPercent for the matching row') is really a parameter hint, not guidance on selecting this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_resultsPast resultsCRead-onlyInspect
Recent example forecasts with their outcomes; not a full record.
| Name | Required | Description | Default |
|---|---|---|---|
| market | Yes | Market slug from list_markets, for example bitcoin | |
| durations | No | Only these duration labels, for example ["1 hour", "1 day"]; default every duration |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| usage | Yes | |
| dataUse | Yes | Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model. |
| notices | Yes | |
| fieldGuide | Yes | Plain meanings of the returned fields. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description's phrase 'not a full record' adds genuine value by signalling that results are partial or sampled, but it does not say how many results come back, whether they are paginated, or how 'recent' is bounded.
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?
A single front-loaded sentence with no wasted words, and the scoping caveat is placed immediately after the core statement. It is efficient, though arguably terse enough that a little more substance would have been warranted.
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 return values need not be explained, and annotations cover the safety profile. What remains missing is any sense of result volume, recency window, or relationship to sibling performance/outlook tools, leaving the definition minimally adequate for a two-parameter read tool.
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 both 'market' (slug from list_markets) and 'durations' (labels with defaults) are fully documented in the schema. The description adds no parameter meaning beyond that, so the 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?
The description conveys that the tool returns recent example forecasts along with their outcomes, which is a real purpose statement, but it omits a clear verb and never names the resource as 'results' in a way that distinguishes it from siblings like get_performance or get_outlooks. An agent can guess the intent but cannot confidently tell it apart from those siblings from the description alone.
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?
There is no statement of when to call this tool versus alternatives such as get_performance, nor any prerequisite or exclusion guidance. The only hint is the scope qualifier 'not a full record,' which hints at limited use but does not route the agent to another tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_usageUsage and limitsBRead-onlyInspect
Remaining allowances, what one get_outlooks call returns, and this connection's permissions, canFollow and expiry. Uses no allowance.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Items per page, 1 to 50; default 50 | |
| cursor | No | page.nextCursor from the previous reply, to read the next page; omit for the first page |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| page | Yes | |
| usage | Yes | |
| dataUse | Yes | Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model. |
| notices | Yes | |
| following | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds one genuinely useful behavioral fact — that this call consumes no allowance — which is not derivable from annotations or schema. It does not discuss auth requirements or return-format details beyond naming fields; given annotations carry the safety burden, a 3 is fair.
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?
It is compact and front-loads the content list, then closes with the allowance note. But the syntax is compressed to the edge of ambiguity ('what one get_outlooks call returns'), and the list-like structure makes the intended primary payload less clear than a single declarative sentence would.
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 return-value shape need not be restated, and annotations cover safety. The description is minimally complete for a zero-required-param read tool. It does not, however, clarify the difference between 'this connection's permissions' and 'remaining allowances,' leaving some ambiguity for a caller deciding what to do with the result.
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% (limit and cursor are both documented in the schema), so the baseline is 3. The description mentions no parameters and adds no syntax, defaults, or pagination guidance beyond what is already in the schema.
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 enumerates what get_usage surfaces — remaining allowances, the payload shape of a sibling call (get_outlooks), and connection details like canFollow and expiry. But the phrasing is clipped and list-like, so the core purpose (fetch usage/quota metadata) has to be inferred. It is distinguishable from siblings only because it happens to name get_outlooks.
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?
The clause 'Uses no allowance' is the only usage signal, and it does imply this call is cheap/free, which is a helpful cue for pacing. However, there is no explicit when-to-use vs alternatives, no exclusions, and no routing to siblings. Adequate but thin; usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_marketsAvailable marketsARead-onlyInspect
Markets this account can read, each with the durations that have forecasts now, and what it follows. Page with page.nextCursor.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Items per page, 1 to 50; default 50 | |
| cursor | No | page.nextCursor from the previous reply, to read the next page; omit for the first page |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| page | Yes | |
| usage | Yes | |
| dataUse | Yes | Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model. |
| notices | Yes | |
| following | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, openWorldHint=false, so the safety profile is fully covered without the description. The description adds the useful behavioral detail that results are scoped to what the account can read and that pagination is cursor-based, but says nothing about ordering, page size limits, or auth requirements.
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 tight sentences with zero filler, and the resource scope is front-loaded before the pagination note. Every clause earns its place.
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 and annotations cover safety, so the description only needs to orient the agent, which it does. The one remaining gap is the absence of any routing hint to sibling tools like follow_market or get_outlooks for an agent scanning the tool list.
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% for both parameters, so limit bounds and the cursor provenance are already documented. The description's mention of 'page.nextCursor' merely echoes the cursor schema description, adding no syntax or format meaning beyond it.
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 ('Markets this account can read') plus the shape of each item (durations with forecasts, follow state). It is unambiguous what the tool returns, but it never contrasts itself with the closely named siblings follow_market/unfollow_market, so an agent gets no explicit differentiation.
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?
Usage is only implied: 'Page with page.nextCursor' tells the agent how to continue, but there is no statement of when to call this versus get_outlooks, follow_market, or get_glossary. The agent must infer that this is the discovery/listing entry point.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unfollow_marketUnfollow a marketADestructiveIdempotentInspect
Stop following a market; its data stops being readable. Check canFollow in get_usage first.
| Name | Required | Description | Default |
|---|---|---|---|
| market | Yes | Market slug from list_markets, for example bitcoin |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| usage | Yes | |
| dataUse | Yes | Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model. |
| notices | Yes | |
| following | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is covered structurally. The description adds real value beyond that by stating the concrete effect (market data stops being readable) and a prerequisite check via get_usage, which an agent could not derive from the annotations alone.
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 short sentences with zero filler; the action and its consequence come first, followed by the prerequisite. Every clause carries actionable 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, so return values need not be explained, and the destructive/idempotent traits are covered by annotations plus the description's effect statement. The only minor gap is not stating whether the unfollow is reversible or how to undo it via follow_market.
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 market parameter is fully documented in the schema (slug, pattern, example "bitcoin"). The description adds no syntax, format, or sourcing detail beyond what the schema already provides, so the 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 and resource ("Stop following a market") and adds the consequence ("its data stops being readable"), which makes the effect unambiguous. It does not explicitly name follow_market as the inverse, but the inverse relationship is trivially inferable from the name and sibling list.
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: "Check canFollow in get_usage first," naming the sibling tool to consult. It stops short of stating when-not-to-use or what to do if canFollow is false, so it is clear guidance rather than full routing logic.
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.
1 tool update
- Changed
get_account_links2 fields changed- changed
Output schema / descriptionPrevious value: -"MCP get_account_links result: official links for account creation, sign-in, account management and comparing plans, with a pointer to kunkafa.com."New value: +"MCP get_account_links result: official links to create an account, sign in, manage connections and read the documentation, with a pointer to kunkafa.com." - changed
Output schema / properties / mcpAvailability / descriptionPrevious value: -"Public availability follows release controls. Plan MCP capabilities may be listed before public availability."New value: +"Public availability follows release controls."
9 tool updates
- Changed
follow_market1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "IntegrationFollowing": { + "additionalProperties": false, + "description": "What the account follows and can still follow. Following decides which markets can be read; it happens in the Kunkafa app.", + "properties": { + "canFollow": { + "description": "Whether this connection may follow and unfollow markets.", + "type": "boolean" + }, + "canFollowMore": { + "description": "How many more markets can be followed; null when the account reads every market.", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "followInApp": { + "description": "Where the user follows markets in the Kunkafa app.", + "format": "uri", + "type": "string" + }, + "followLimit": { + "description": "The plan's Following count; null when the account reads every market.", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "followed": { + "description": "Markets on the account's following list, as the app counts them.", + "minimum": 0, + "type": "integer" + }, + "howToAllowFollowing": { + "description": "Present when canFollow is false.", + "minLength": 1, + "type": "string" + }, + "message": { + "description": "Plain explanation for the user, including for accounts that read every market.", + "type": "string" + }, + "otherMarkets": { + "description": "Catalogue markets the account does not follow, by English name, sorted by name; at most 100 (otherMarketsTotal gives the full count). Any market can still be followed by its slug.", + "items": { + "additionalProperties": false, + "properties": { + "market": { + "$ref": "#/$defs/IntegrationMarketSlug" + }, + "name": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "market", + "name" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "otherMarketsTotal": { + "description": "How many catalogue markets the account does not follow.", + "minimum": 0, + "type": "integer" + }, + "readsEveryMarket": { + "type": "boolean" + } + }, + "required": [ + "followed", + "followLimit", + "canFollowMore", + "readsEveryMarket", + "message", + "followInApp", + "otherMarkets", + "otherMarketsTotal" + ], + "type": "object" + }, + "IntegrationFollowingChange": { + "additionalProperties": false, + "properties": { + "action": { + "enum": [ + "followed", + "unfollowed", + "unchanged" + ] + }, + "market": { + "$ref": "#/$defs/IntegrationMarketSlug" + }, + "nextChangeAllowedAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ], + "description": "When a followed market may next be replaced; null while no replacement window runs." + } + }, + "required": [ + "market", + "action", + "nextChangeAllowedAt" + ], + "type": "object" + }, + "IntegrationMarketSlug": { + "description": "Published English-name market slug returned by authorized discovery.", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "type": "string" + }, + "IntegrationNotice": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "kind": { + "enum": [ + "approaching_limit", + "limit_reached" + ] + }, + "limit": { + "minimum": 0, + "type": "integer" + }, + "message": { + "type": "string" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "id", + "period", + "kind", + "message", + "used", + "limit", + "remaining", + "nextCapacityAt" + ], + "type": "object" + }, + "IntegrationTimestamp": { + "description": "ISO 8601 UTC timestamp supplied by Kunkafa.", + "format": "date-time", + "type": "string" + }, + "IntegrationUsage": { + "additionalProperties": false, + "properties": { + "adjustment": { + "additionalProperties": false, + "description": "An owner-approved account allowance increase. A null expiration is permanent until changed. Usage is never reset; market access and credential eligibility still follow the current plan.", + "properties": { + "expiresAt": { + "format": "date-time", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "expiresAt" + ], + "type": "object" + }, + "calculatedAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "concurrency": { + "additionalProperties": false, + "description": "Private requests that can run at the same time. Requests from one connection run side by side up to this limit (the plan burst); a request from another connection waits until they finish.", + "properties": { + "limit": { + "maximum": 100, + "minimum": 1, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "remaining": { + "maximum": 100, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "limit", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "requests": { + "additionalProperties": false, + "description": "Steady request rate with bounded burst capacity; metadata and repeated summaries still count toward request protection.", + "properties": { + "burst": { + "minimum": 0, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "perMinute": { + "minimum": 0, + "type": "integer" + }, + "remaining": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "perMinute", + "burst", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "tier": { + "enum": [ + "free", + "starter", + "core", + "pro", + "publisher" + ] + }, + "windows": { + "items": { + "$ref": "#/$defs/IntegrationWindowUsage" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + }, + "required": [ + "calculatedAt", + "tier", + "requests", + "concurrency", + "windows" + ], + "type": "object" + }, + "IntegrationWindowUsage": { + "additionalProperties": false, + "description": "Rolling 24-hour, 7-day or 30-day allowance, not a midnight reset. Used can exceed the current limit after a downgrade; remaining is never negative.", + "properties": { + "limit": { + "minimum": 0, + "type": "integer" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "notice": { + "enum": [ + "approaching_limit", + "limit_reached", + null + ] + }, + "noticeId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "period", + "used", + "limit", + "remaining", + "nextCapacityAt", + "notice", + "noticeId" + ], + "type": "object" + } + }, + "additionalProperties": false, + "description": "The change and the account's following after it. The Kunkafa app shows the same list immediately.", + "properties": { + "data": { + "$ref": "#/$defs/IntegrationFollowingChange" + }, + "dataUse": { + "description": "Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model.", + "type": "string" + }, + "following": { + "$ref": "#/$defs/IntegrationFollowing" + }, + "notices": { + "items": { + "$ref": "#/$defs/IntegrationNotice" + }, + "maxItems": 3, + "type": "array" + }, + "usage": { + "$ref": "#/$defs/IntegrationUsage" + } + }, + "required": [ + "data", + "following", + "usage", + "notices", + "dataUse" + ], + "type": "object" +}
- Changed
get_account_links1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": false, + "description": "MCP get_account_links result: official links for account creation, sign-in, account management and comparing plans, with a pointer to kunkafa.com.", + "properties": { + "availabilityMessage": { + "type": "string" + }, + "browserConfirmationRequired": { + "const": true + }, + "disclosureUnits": { + "const": 0 + }, + "links": { + "additionalProperties": false, + "properties": { + "documentation": { + "pattern": "^https://kunkafa\\.com/", + "type": "string" + }, + "manage": { + "pattern": "^https://kunkafa\\.com/", + "type": "string" + }, + "signin": { + "pattern": "^https://kunkafa\\.com/", + "type": "string" + }, + "signup": { + "pattern": "^https://kunkafa\\.com/", + "type": "string" + } + }, + "required": [ + "signup", + "signin", + "manage", + "documentation" + ], + "type": "object" + }, + "mcp": { + "const": "https://kunkafa.com/mcp" + }, + "mcpAvailability": { + "description": "Public availability follows release controls. Plan MCP capabilities may be listed before public availability.", + "enum": [ + "coming_soon", + "available" + ] + } + }, + "required": [ + "mcp", + "links", + "browserConfirmationRequired", + "disclosureUnits", + "mcpAvailability", + "availabilityMessage" + ], + "type": "object" +}
- Changed
get_glossary1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": false, + "description": "What every term in Kunkafa replies means and how to read them. Public, static, English.", + "properties": { + "glossary": { + "additionalProperties": false, + "properties": { + "terms": { + "items": { + "additionalProperties": false, + "properties": { + "fields": { + "description": "Reply fields the term explains.", + "type": "string" + }, + "meaning": { + "type": "string" + }, + "term": { + "type": "string" + } + }, + "required": [ + "term", + "meaning" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "title": { + "type": "string" + } + }, + "required": [ + "title", + "terms" + ], + "type": "object" + } + }, + "required": [ + "glossary" + ], + "type": "object" +}
- Changed
get_outlooks1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "IntegrationMarketSlug": { + "description": "Published English-name market slug returned by authorized discovery.", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "type": "string" + }, + "IntegrationNotice": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "kind": { + "enum": [ + "approaching_limit", + "limit_reached" + ] + }, + "limit": { + "minimum": 0, + "type": "integer" + }, + "message": { + "type": "string" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "id", + "period", + "kind", + "message", + "used", + "limit", + "remaining", + "nextCapacityAt" + ], + "type": "object" + }, + "IntegrationOutlookFieldGuide": { + "additionalProperties": false, + "properties": { + "counts": { + "type": "string" + }, + "forecastAt": { + "type": "string" + }, + "interpretation": { + "type": "string" + }, + "label": { + "type": "string" + }, + "more": { + "type": "string" + }, + "movePercent": { + "type": "string" + }, + "probabilityPercent": { + "type": "string" + }, + "referencePrice": { + "type": "string" + }, + "sourceAt": { + "type": "string" + }, + "withoutForecasts": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "probabilityPercent", + "movePercent", + "referencePrice", + "sourceAt", + "forecastAt", + "label", + "counts", + "interpretation", + "more" + ], + "type": "object" + }, + "IntegrationOutlookSelection": { + "additionalProperties": false, + "description": "The requested selection of one market's current forecasts. Historical performance and selected past results are read with their own operations.", + "properties": { + "availableDurations": { + "description": "Durations of this market that have forecasts now; a duration with none is left out.", + "items": { + "type": "string" + }, + "maxItems": 40, + "type": "array" + }, + "counts": { + "additionalProperties": false, + "properties": { + "forecasts": { + "maximum": 72, + "minimum": 0, + "type": "integer" + }, + "withoutProbability": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "forecasts", + "withoutProbability" + ], + "type": "object" + }, + "forecasts": { + "items": { + "$ref": "#/$defs/IntegrationSelectedSource" + }, + "type": "array" + }, + "market": { + "$ref": "#/$defs/IntegrationMarketSlug" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "selection": { + "additionalProperties": false, + "properties": { + "direction": { + "enum": [ + "up", + "down", + "both" + ] + }, + "durations": { + "items": { + "type": "string" + }, + "maxItems": 6, + "minItems": 1, + "type": "array" + }, + "maxProbabilityPercent": { + "type": "number" + }, + "maxTargetPercent": { + "type": [ + "number", + "null" + ] + }, + "minProbabilityPercent": { + "type": "number" + }, + "minTargetPercent": { + "type": "number" + } + }, + "required": [ + "durations", + "direction", + "minProbabilityPercent", + "maxProbabilityPercent", + "minTargetPercent", + "maxTargetPercent" + ], + "type": "object" + }, + "sourceAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "url": { + "format": "uri", + "pattern": "^https://kunkafa\\.com/markets/[a-z0-9-]+/$", + "type": "string" + }, + "withoutForecasts": { + "description": "Asked-for durations with no forecasts: none_now (none at the moment) or no_match (none match the filters). Left out when every duration has forecasts.", + "items": { + "additionalProperties": false, + "properties": { + "duration": { + "minLength": 1, + "type": "string" + }, + "reason": { + "enum": [ + "none_now", + "no_match" + ] + } + }, + "required": [ + "duration", + "reason" + ], + "type": "object" + }, + "maxItems": 40, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "market", + "name", + "url", + "sourceAt", + "selection", + "availableDurations", + "forecasts", + "counts" + ], + "type": "object" + }, + "IntegrationSelectedOutput": { + "additionalProperties": false, + "description": "One target-touch forecast. probabilityPercent is Kunkafa's confidence; outputs without one are counted in counts.withoutProbability, not listed.", + "properties": { + "direction": { + "enum": [ + "up", + "down" + ] + }, + "movePercent": { + "type": "number" + }, + "probabilityPercent": { + "maximum": 100, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "direction", + "movePercent", + "probabilityPercent" + ], + "type": "object" + }, + "IntegrationSelectedSource": { + "additionalProperties": false, + "description": "A source group within the selection; several can share a duration. Only groups with forecasts are listed; forecastAt is left out when unknown.", + "properties": { + "duration": { + "minLength": 1, + "type": "string" + }, + "forecastAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "label": { + "description": "Names the source within its duration (A, B, C…): forecasts made together. Sources are read side by side, never merged.", + "pattern": "^[A-Z]$", + "type": "string" + }, + "outputs": { + "items": { + "$ref": "#/$defs/IntegrationSelectedOutput" + }, + "maxItems": 72, + "minItems": 1, + "type": "array" + }, + "referencePrice": { + "exclusiveMinimum": 0, + "type": "number" + }, + "sourceAt": { + "$ref": "#/$defs/IntegrationTimestamp" + } + }, + "required": [ + "duration", + "sourceAt", + "referencePrice", + "outputs", + "label" + ], + "type": "object" + }, + "IntegrationTimestamp": { + "description": "ISO 8601 UTC timestamp supplied by Kunkafa.", + "format": "date-time", + "type": "string" + }, + "IntegrationUsage": { + "additionalProperties": false, + "properties": { + "adjustment": { + "additionalProperties": false, + "description": "An owner-approved account allowance increase. A null expiration is permanent until changed. Usage is never reset; market access and credential eligibility still follow the current plan.", + "properties": { + "expiresAt": { + "format": "date-time", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "expiresAt" + ], + "type": "object" + }, + "calculatedAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "concurrency": { + "additionalProperties": false, + "description": "Private requests that can run at the same time. Requests from one connection run side by side up to this limit (the plan burst); a request from another connection waits until they finish.", + "properties": { + "limit": { + "maximum": 100, + "minimum": 1, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "remaining": { + "maximum": 100, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "limit", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "requests": { + "additionalProperties": false, + "description": "Steady request rate with bounded burst capacity; metadata and repeated summaries still count toward request protection.", + "properties": { + "burst": { + "minimum": 0, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "perMinute": { + "minimum": 0, + "type": "integer" + }, + "remaining": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "perMinute", + "burst", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "tier": { + "enum": [ + "free", + "starter", + "core", + "pro", + "publisher" + ] + }, + "windows": { + "items": { + "$ref": "#/$defs/IntegrationWindowUsage" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + }, + "required": [ + "calculatedAt", + "tier", + "requests", + "concurrency", + "windows" + ], + "type": "object" + }, + "IntegrationWindowUsage": { + "additionalProperties": false, + "description": "Rolling 24-hour, 7-day or 30-day allowance, not a midnight reset. Used can exceed the current limit after a downgrade; remaining is never negative.", + "properties": { + "limit": { + "minimum": 0, + "type": "integer" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "notice": { + "enum": [ + "approaching_limit", + "limit_reached", + null + ] + }, + "noticeId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "period", + "used", + "limit", + "remaining", + "nextCapacityAt", + "notice", + "noticeId" + ], + "type": "object" + } + }, + "additionalProperties": false, + "description": "One market's selected forecasts. Each distinct selection is one disclosure against the allowance; repeating the same selection on unchanged data is not charged again.", + "properties": { + "data": { + "$ref": "#/$defs/IntegrationOutlookSelection" + }, + "dataUse": { + "description": "Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model.", + "type": "string" + }, + "fieldGuide": { + "$ref": "#/$defs/IntegrationOutlookFieldGuide" + }, + "notices": { + "items": { + "$ref": "#/$defs/IntegrationNotice" + }, + "maxItems": 3, + "type": "array" + }, + "usage": { + "$ref": "#/$defs/IntegrationUsage" + } + }, + "required": [ + "data", + "fieldGuide", + "usage", + "notices", + "dataUse" + ], + "type": "object" +}
- Changed
get_performance1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "IntegrationMarketSlug": { + "description": "Published English-name market slug returned by authorized discovery.", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "type": "string" + }, + "IntegrationNotice": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "kind": { + "enum": [ + "approaching_limit", + "limit_reached" + ] + }, + "limit": { + "minimum": 0, + "type": "integer" + }, + "message": { + "type": "string" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "id", + "period", + "kind", + "message", + "used", + "limit", + "remaining", + "nextCapacityAt" + ], + "type": "object" + }, + "IntegrationPerformance": { + "additionalProperties": false, + "description": "Market-wide historical evidence at each published classifier probability threshold and reporting period. Sample counts and missing rates are preserved; this is not evidence matched to each current output.", + "properties": { + "defaultProbabilityThresholdPercent": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "latestReport": { + "$ref": "#/$defs/IntegrationReportEvidence" + }, + "market": { + "$ref": "#/$defs/IntegrationMarketSlug" + }, + "periods": { + "items": { + "additionalProperties": false, + "properties": { + "period": { + "enum": [ + "d1", + "d7", + "d30", + "all_time" + ] + }, + "points": { + "items": { + "$ref": "#/$defs/IntegrationPerformancePoint" + }, + "type": "array" + } + }, + "required": [ + "period", + "points" + ], + "type": "object" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "sourceAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "url": { + "description": "The market's page on kunkafa.com.", + "format": "uri", + "pattern": "^https://kunkafa\\.com/markets/[a-z0-9-]+/$", + "type": "string" + } + }, + "required": [ + "market", + "sourceAt", + "defaultProbabilityThresholdPercent", + "periods" + ], + "type": "object" + }, + "IntegrationPerformanceHeadline": { + "additionalProperties": false, + "description": "The row to read first: past results at one published confidence level for each reporting period. basis is default (the market's default level) or requested (the nearest level at or below probabilityPercent).", + "properties": { + "basis": { + "enum": [ + "default", + "requested" + ] + }, + "periods": { + "items": { + "additionalProperties": false, + "properties": { + "period": { + "enum": [ + "d1", + "d7", + "d30", + "all_time" + ] + }, + "sampleCount": { + "minimum": 0, + "type": "integer" + }, + "status": { + "enum": [ + "available", + "insufficient" + ] + }, + "targetsReachedPercent": { + "anyOf": [ + { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "period", + "sampleCount", + "targetsReachedPercent", + "status" + ], + "type": "object" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "probabilityThresholdPercent": { + "maximum": 100, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "probabilityThresholdPercent", + "basis", + "periods" + ], + "type": "object" + }, + "IntegrationPerformancePoint": { + "additionalProperties": false, + "description": "Published classifier probability threshold and observed target-touch rate. Rates are null for fewer than 100 examples or missing evidence; classifier probability is separate from historical success.", + "properties": { + "probabilityThresholdPercent": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "sampleCount": { + "minimum": 0, + "type": "integer" + }, + "status": { + "enum": [ + "available", + "insufficient" + ] + }, + "targetsReachedPercent": { + "anyOf": [ + { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "probabilityThresholdPercent", + "sampleCount", + "targetsReachedPercent", + "status" + ], + "type": "object" + }, + "IntegrationReportBreakdown": { + "additionalProperties": false, + "description": "The market's latest full published report: every settled forecast placed in one of eight bands by how far price travelled toward its target within the duration, as a percent of the distance to the target (100 is the target itself; 300 is three times that distance, not a price change). All eight bands are always present.", + "properties": { + "bands": { + "items": { + "additionalProperties": false, + "properties": { + "fromPct": { + "type": "number" + }, + "key": { + "type": "string" + }, + "toPct": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "key", + "fromPct", + "toPct" + ], + "type": "object" + }, + "maxItems": 8, + "minItems": 8, + "type": "array" + }, + "edition": { + "const": "full" + }, + "floors": { + "items": { + "additionalProperties": false, + "properties": { + "bandsPercent": { + "description": "Share of the settled forecasts in each band, in the order of bands; sums to 100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 8, + "minItems": 8, + "type": "array" + }, + "down": { + "$ref": "#/$defs/IntegrationReportShares" + }, + "minimumProbabilityPercent": { + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "settledForecasts": { + "minimum": 0, + "type": "integer" + }, + "up": { + "$ref": "#/$defs/IntegrationReportShares" + } + }, + "required": [ + "minimumProbabilityPercent", + "settledForecasts", + "bandsPercent", + "up", + "down" + ], + "type": "object" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "generatedAt": { + "type": "string" + }, + "market": { + "type": "string" + }, + "reportUrl": { + "pattern": "^https://kunkafa\\.com/reports/", + "type": "string" + }, + "window": { + "additionalProperties": false, + "properties": { + "from": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "to": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + } + }, + "required": [ + "from", + "to" + ], + "type": "object" + } + }, + "required": [ + "market", + "edition", + "window", + "generatedAt", + "reportUrl", + "bands", + "floors" + ], + "type": "object" + }, + "IntegrationReportEvidence": { + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "data": { + "$ref": "#/$defs/IntegrationReportBreakdown" + }, + "status": { + "const": "available" + } + }, + "required": [ + "status", + "data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "data": { + "type": "null" + }, + "status": { + "const": "unavailable" + } + }, + "required": [ + "status", + "data" + ], + "type": "object" + } + ] + }, + "IntegrationReportShares": { + "additionalProperties": false, + "properties": { + "bandsPercent": { + "description": "Share of the settled forecasts in each band, in the order of bands; sums to 100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 8, + "minItems": 8, + "type": "array" + }, + "settledForecasts": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "settledForecasts", + "bandsPercent" + ], + "type": "object" + }, + "IntegrationTimestamp": { + "description": "ISO 8601 UTC timestamp supplied by Kunkafa.", + "format": "date-time", + "type": "string" + }, + "IntegrationUsage": { + "additionalProperties": false, + "properties": { + "adjustment": { + "additionalProperties": false, + "description": "An owner-approved account allowance increase. A null expiration is permanent until changed. Usage is never reset; market access and credential eligibility still follow the current plan.", + "properties": { + "expiresAt": { + "format": "date-time", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "expiresAt" + ], + "type": "object" + }, + "calculatedAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "concurrency": { + "additionalProperties": false, + "description": "Private requests that can run at the same time. Requests from one connection run side by side up to this limit (the plan burst); a request from another connection waits until they finish.", + "properties": { + "limit": { + "maximum": 100, + "minimum": 1, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "remaining": { + "maximum": 100, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "limit", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "requests": { + "additionalProperties": false, + "description": "Steady request rate with bounded burst capacity; metadata and repeated summaries still count toward request protection.", + "properties": { + "burst": { + "minimum": 0, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "perMinute": { + "minimum": 0, + "type": "integer" + }, + "remaining": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "perMinute", + "burst", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "tier": { + "enum": [ + "free", + "starter", + "core", + "pro", + "publisher" + ] + }, + "windows": { + "items": { + "$ref": "#/$defs/IntegrationWindowUsage" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + }, + "required": [ + "calculatedAt", + "tier", + "requests", + "concurrency", + "windows" + ], + "type": "object" + }, + "IntegrationWindowUsage": { + "additionalProperties": false, + "description": "Rolling 24-hour, 7-day or 30-day allowance, not a midnight reset. Used can exceed the current limit after a downgrade; remaining is never negative.", + "properties": { + "limit": { + "minimum": 0, + "type": "integer" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "notice": { + "enum": [ + "approaching_limit", + "limit_reached", + null + ] + }, + "noticeId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "period", + "used", + "limit", + "remaining", + "nextCapacityAt", + "notice", + "noticeId" + ], + "type": "object" + } + }, + "additionalProperties": false, + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/$defs/IntegrationPerformance" + }, + { + "required": [ + "url" + ] + } + ] + }, + "dataUse": { + "description": "Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model.", + "type": "string" + }, + "fieldGuide": { + "additionalProperties": false, + "description": "Plain meanings of the returned fields.", + "properties": { + "latestReport": { + "type": "string" + }, + "periods": { + "type": "string" + }, + "probabilityThresholdPercent": { + "type": "string" + }, + "sampleCount": { + "type": "string" + }, + "targetsReachedPercent": { + "type": "string" + } + }, + "required": [ + "periods", + "probabilityThresholdPercent", + "targetsReachedPercent", + "sampleCount", + "latestReport" + ], + "type": "object" + }, + "headline": { + "$ref": "#/$defs/IntegrationPerformanceHeadline" + }, + "notices": { + "items": { + "$ref": "#/$defs/IntegrationNotice" + }, + "maxItems": 3, + "type": "array" + }, + "usage": { + "$ref": "#/$defs/IntegrationUsage" + } + }, + "required": [ + "data", + "usage", + "notices", + "dataUse", + "fieldGuide", + "headline" + ], + "type": "object" +}
- Changed
get_results1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "IntegrationMarketSlug": { + "description": "Published English-name market slug returned by authorized discovery.", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "type": "string" + }, + "IntegrationNotice": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "kind": { + "enum": [ + "approaching_limit", + "limit_reached" + ] + }, + "limit": { + "minimum": 0, + "type": "integer" + }, + "message": { + "type": "string" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "id", + "period", + "kind", + "message", + "used", + "limit", + "remaining", + "nextCapacityAt" + ], + "type": "object" + }, + "IntegrationResult": { + "additionalProperties": false, + "description": "A selected completed result; confidence is the value recorded at prediction time, separate from aggregate performance.", + "properties": { + "closedAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "direction": { + "enum": [ + "up", + "down" + ] + }, + "durationLabel": { + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "ar": { + "type": "string" + }, + "en": { + "type": "string" + } + }, + "required": [ + "en", + "ar" + ], + "type": "object" + } + ], + "description": "English label in API and MCP replies; the app hand-off file keeps both languages." + }, + "id": { + "pattern": "^[a-f0-9]{24}$", + "type": "string" + }, + "mfePercent": { + "description": "Recorded furthest favorable price movement in percentage points.", + "minimum": 0, + "type": [ + "number", + "null" + ] + }, + "movePercent": { + "type": "number" + }, + "outcome": { + "enum": [ + "reached", + "not-reached" + ] + }, + "predictionAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "probabilityPercent": { + "description": "Rounded to two decimal places. Eligibility uses original confidence strictly above 80%; a qualifying value just above 80% can display as 80% after rounding.", + "maximum": 100, + "minimum": 80, + "type": "number" + }, + "targetProgressPercent": { + "description": "Favorable move as a percentage of target distance; can exceed 100. Missing is null.", + "minimum": 0, + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "id", + "direction", + "predictionAt", + "closedAt", + "probabilityPercent", + "movePercent", + "outcome", + "durationLabel", + "mfePercent", + "targetProgressPercent" + ], + "type": "object" + }, + "IntegrationResults": { + "additionalProperties": false, + "description": "Latest eligible completed result for every distinct original duration, across both directions, newest closure first. Previous 90 days; original duration strictly longer than 24 hours and recorded confidence strictly above 80%. Reached and missed targets both qualify. Selected results are not an aggregate success rate or full archive.", + "properties": { + "market": { + "$ref": "#/$defs/IntegrationMarketSlug" + }, + "results": { + "items": { + "$ref": "#/$defs/IntegrationResult" + }, + "type": "array" + }, + "sourceAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "url": { + "description": "The market's page on kunkafa.com.", + "format": "uri", + "pattern": "^https://kunkafa\\.com/markets/[a-z0-9-]+/$", + "type": "string" + } + }, + "required": [ + "market", + "sourceAt", + "results" + ], + "type": "object" + }, + "IntegrationTimestamp": { + "description": "ISO 8601 UTC timestamp supplied by Kunkafa.", + "format": "date-time", + "type": "string" + }, + "IntegrationUsage": { + "additionalProperties": false, + "properties": { + "adjustment": { + "additionalProperties": false, + "description": "An owner-approved account allowance increase. A null expiration is permanent until changed. Usage is never reset; market access and credential eligibility still follow the current plan.", + "properties": { + "expiresAt": { + "format": "date-time", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "expiresAt" + ], + "type": "object" + }, + "calculatedAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "concurrency": { + "additionalProperties": false, + "description": "Private requests that can run at the same time. Requests from one connection run side by side up to this limit (the plan burst); a request from another connection waits until they finish.", + "properties": { + "limit": { + "maximum": 100, + "minimum": 1, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "remaining": { + "maximum": 100, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "limit", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "requests": { + "additionalProperties": false, + "description": "Steady request rate with bounded burst capacity; metadata and repeated summaries still count toward request protection.", + "properties": { + "burst": { + "minimum": 0, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "perMinute": { + "minimum": 0, + "type": "integer" + }, + "remaining": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "perMinute", + "burst", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "tier": { + "enum": [ + "free", + "starter", + "core", + "pro", + "publisher" + ] + }, + "windows": { + "items": { + "$ref": "#/$defs/IntegrationWindowUsage" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + }, + "required": [ + "calculatedAt", + "tier", + "requests", + "concurrency", + "windows" + ], + "type": "object" + }, + "IntegrationWindowUsage": { + "additionalProperties": false, + "description": "Rolling 24-hour, 7-day or 30-day allowance, not a midnight reset. Used can exceed the current limit after a downgrade; remaining is never negative.", + "properties": { + "limit": { + "minimum": 0, + "type": "integer" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "notice": { + "enum": [ + "approaching_limit", + "limit_reached", + null + ] + }, + "noticeId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "period", + "used", + "limit", + "remaining", + "nextCapacityAt", + "notice", + "noticeId" + ], + "type": "object" + } + }, + "additionalProperties": false, + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/$defs/IntegrationResults" + }, + { + "required": [ + "url" + ] + } + ] + }, + "dataUse": { + "description": "Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model.", + "type": "string" + }, + "fieldGuide": { + "additionalProperties": false, + "description": "Plain meanings of the returned fields.", + "properties": { + "mfePercent": { + "type": "string" + }, + "movePercent": { + "type": "string" + }, + "outcome": { + "type": "string" + }, + "probabilityPercent": { + "type": "string" + }, + "results": { + "type": "string" + }, + "targetProgressPercent": { + "type": "string" + } + }, + "required": [ + "results", + "probabilityPercent", + "movePercent", + "outcome", + "mfePercent", + "targetProgressPercent" + ], + "type": "object" + }, + "notices": { + "items": { + "$ref": "#/$defs/IntegrationNotice" + }, + "maxItems": 3, + "type": "array" + }, + "usage": { + "$ref": "#/$defs/IntegrationUsage" + } + }, + "required": [ + "data", + "usage", + "notices", + "dataUse", + "fieldGuide" + ], + "type": "object" +}
- Changed
get_usage1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "IntegrationFollowing": { + "additionalProperties": false, + "description": "What the account follows and can still follow. Following decides which markets can be read; it happens in the Kunkafa app.", + "properties": { + "canFollow": { + "description": "Whether this connection may follow and unfollow markets.", + "type": "boolean" + }, + "canFollowMore": { + "description": "How many more markets can be followed; null when the account reads every market.", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "followInApp": { + "description": "Where the user follows markets in the Kunkafa app.", + "format": "uri", + "type": "string" + }, + "followLimit": { + "description": "The plan's Following count; null when the account reads every market.", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "followed": { + "description": "Markets on the account's following list, as the app counts them.", + "minimum": 0, + "type": "integer" + }, + "howToAllowFollowing": { + "description": "Present when canFollow is false.", + "minLength": 1, + "type": "string" + }, + "message": { + "description": "Plain explanation for the user, including for accounts that read every market.", + "type": "string" + }, + "otherMarkets": { + "description": "Catalogue markets the account does not follow, by English name, sorted by name; at most 100 (otherMarketsTotal gives the full count). Any market can still be followed by its slug.", + "items": { + "additionalProperties": false, + "properties": { + "market": { + "$ref": "#/$defs/IntegrationMarketSlug" + }, + "name": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "market", + "name" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "otherMarketsTotal": { + "description": "How many catalogue markets the account does not follow.", + "minimum": 0, + "type": "integer" + }, + "readsEveryMarket": { + "type": "boolean" + } + }, + "required": [ + "followed", + "followLimit", + "canFollowMore", + "readsEveryMarket", + "message", + "followInApp", + "otherMarkets", + "otherMarketsTotal" + ], + "type": "object" + }, + "IntegrationMarketSlug": { + "description": "Published English-name market slug returned by authorized discovery.", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "type": "string" + }, + "IntegrationNotice": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "kind": { + "enum": [ + "approaching_limit", + "limit_reached" + ] + }, + "limit": { + "minimum": 0, + "type": "integer" + }, + "message": { + "type": "string" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "id", + "period", + "kind", + "message", + "used", + "limit", + "remaining", + "nextCapacityAt" + ], + "type": "object" + }, + "IntegrationPage": { + "additionalProperties": false, + "description": "Follow nextCursor until null. Cursors are invalidated by relevant access or market-list changes; restart without a cursor.", + "properties": { + "nextCursor": { + "anyOf": [ + { + "maxLength": 256, + "minLength": 1, + "pattern": "^[A-Za-z0-9_-]+$", + "type": "string" + }, + { + "type": "null" + } + ] + }, + "returned": { + "maximum": 50, + "minimum": 0, + "type": "integer" + }, + "total": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "total", + "returned", + "nextCursor" + ], + "type": "object" + }, + "IntegrationTimestamp": { + "description": "ISO 8601 UTC timestamp supplied by Kunkafa.", + "format": "date-time", + "type": "string" + }, + "IntegrationUsage": { + "additionalProperties": false, + "properties": { + "adjustment": { + "additionalProperties": false, + "description": "An owner-approved account allowance increase. A null expiration is permanent until changed. Usage is never reset; market access and credential eligibility still follow the current plan.", + "properties": { + "expiresAt": { + "format": "date-time", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "expiresAt" + ], + "type": "object" + }, + "calculatedAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "concurrency": { + "additionalProperties": false, + "description": "Private requests that can run at the same time. Requests from one connection run side by side up to this limit (the plan burst); a request from another connection waits until they finish.", + "properties": { + "limit": { + "maximum": 100, + "minimum": 1, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "remaining": { + "maximum": 100, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "limit", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "requests": { + "additionalProperties": false, + "description": "Steady request rate with bounded burst capacity; metadata and repeated summaries still count toward request protection.", + "properties": { + "burst": { + "minimum": 0, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "perMinute": { + "minimum": 0, + "type": "integer" + }, + "remaining": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "perMinute", + "burst", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "tier": { + "enum": [ + "free", + "starter", + "core", + "pro", + "publisher" + ] + }, + "windows": { + "items": { + "$ref": "#/$defs/IntegrationWindowUsage" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + }, + "required": [ + "calculatedAt", + "tier", + "requests", + "concurrency", + "windows" + ], + "type": "object" + }, + "IntegrationWindowUsage": { + "additionalProperties": false, + "description": "Rolling 24-hour, 7-day or 30-day allowance, not a midnight reset. Used can exceed the current limit after a downgrade; remaining is never negative.", + "properties": { + "limit": { + "minimum": 0, + "type": "integer" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "notice": { + "enum": [ + "approaching_limit", + "limit_reached", + null + ] + }, + "noticeId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "period", + "used", + "limit", + "remaining", + "nextCapacityAt", + "notice", + "noticeId" + ], + "type": "object" + } + }, + "additionalProperties": false, + "properties": { + "data": { + "additionalProperties": false, + "properties": { + "connection": { + "additionalProperties": false, + "description": "This connection's permissions and expiry. An MCP (OAuth) connection stays connected while used: it expires after idleDays without use, at most one year after it was approved. A reconnect from the same app replaces it without using another connection.", + "properties": { + "canFollow": { + "description": "Whether this connection may follow and unfollow markets (the following:write permission).", + "type": "boolean" + }, + "expiresAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "howToAllowFollowing": { + "description": "Present only when canFollow is false: how the user allows following for this connection.", + "type": "string" + }, + "idleDays": { + "const": 90 + }, + "kind": { + "enum": [ + "oauth", + "personal_token" + ] + }, + "permissions": { + "items": { + "enum": [ + "markets:read", + "outlooks:read", + "performance:read", + "results:read", + "usage:read", + "following:write" + ] + }, + "maxItems": 6, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "staysConnectedWhileUsed": { + "const": true + } + }, + "required": [ + "kind", + "permissions", + "expiresAt", + "canFollow" + ], + "type": "object" + }, + "outlookLimits": { + "additionalProperties": false, + "description": "What one get_outlooks call can return.", + "properties": { + "marketsPerCall": { + "const": 1 + }, + "maxDurations": { + "const": 6 + }, + "maxForecasts": { + "const": 72 + } + }, + "required": [ + "marketsPerCall", + "maxDurations", + "maxForecasts" + ], + "type": "object" + }, + "permittedMarkets": { + "items": { + "$ref": "#/$defs/IntegrationMarketSlug" + }, + "maxItems": 50, + "type": "array" + } + }, + "required": [ + "permittedMarkets", + "outlookLimits", + "connection" + ], + "type": "object" + }, + "dataUse": { + "description": "Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model.", + "type": "string" + }, + "following": { + "$ref": "#/$defs/IntegrationFollowing" + }, + "notices": { + "items": { + "$ref": "#/$defs/IntegrationNotice" + }, + "maxItems": 3, + "type": "array" + }, + "page": { + "$ref": "#/$defs/IntegrationPage" + }, + "usage": { + "$ref": "#/$defs/IntegrationUsage" + } + }, + "required": [ + "data", + "following", + "usage", + "notices", + "page", + "dataUse" + ], + "type": "object" +}
- Changed
list_markets1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "IntegrationFollowing": { + "additionalProperties": false, + "description": "What the account follows and can still follow. Following decides which markets can be read; it happens in the Kunkafa app.", + "properties": { + "canFollow": { + "description": "Whether this connection may follow and unfollow markets.", + "type": "boolean" + }, + "canFollowMore": { + "description": "How many more markets can be followed; null when the account reads every market.", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "followInApp": { + "description": "Where the user follows markets in the Kunkafa app.", + "format": "uri", + "type": "string" + }, + "followLimit": { + "description": "The plan's Following count; null when the account reads every market.", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "followed": { + "description": "Markets on the account's following list, as the app counts them.", + "minimum": 0, + "type": "integer" + }, + "howToAllowFollowing": { + "description": "Present when canFollow is false.", + "minLength": 1, + "type": "string" + }, + "message": { + "description": "Plain explanation for the user, including for accounts that read every market.", + "type": "string" + }, + "otherMarkets": { + "description": "Catalogue markets the account does not follow, by English name, sorted by name; at most 100 (otherMarketsTotal gives the full count). Any market can still be followed by its slug.", + "items": { + "additionalProperties": false, + "properties": { + "market": { + "$ref": "#/$defs/IntegrationMarketSlug" + }, + "name": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "market", + "name" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "otherMarketsTotal": { + "description": "How many catalogue markets the account does not follow.", + "minimum": 0, + "type": "integer" + }, + "readsEveryMarket": { + "type": "boolean" + } + }, + "required": [ + "followed", + "followLimit", + "canFollowMore", + "readsEveryMarket", + "message", + "followInApp", + "otherMarkets", + "otherMarketsTotal" + ], + "type": "object" + }, + "IntegrationMarket": { + "additionalProperties": false, + "properties": { + "durations": { + "description": "Durations that have forecasts now, shortest first; use these labels in get_outlooks. Empty, with note, when the market has none at the moment.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 40, + "type": "array" + }, + "market": { + "$ref": "#/$defs/IntegrationMarketSlug" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "note": { + "description": "Present only when the market has no forecasts at the moment.", + "minLength": 1, + "type": "string" + }, + "url": { + "format": "uri", + "pattern": "^https://kunkafa\\.com/markets/[a-z0-9-]+/$", + "type": "string" + } + }, + "required": [ + "market", + "name", + "url", + "durations" + ], + "type": "object" + }, + "IntegrationMarketSlug": { + "description": "Published English-name market slug returned by authorized discovery.", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "type": "string" + }, + "IntegrationNotice": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "kind": { + "enum": [ + "approaching_limit", + "limit_reached" + ] + }, + "limit": { + "minimum": 0, + "type": "integer" + }, + "message": { + "type": "string" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "id", + "period", + "kind", + "message", + "used", + "limit", + "remaining", + "nextCapacityAt" + ], + "type": "object" + }, + "IntegrationPage": { + "additionalProperties": false, + "description": "Follow nextCursor until null. Cursors are invalidated by relevant access or market-list changes; restart without a cursor.", + "properties": { + "nextCursor": { + "anyOf": [ + { + "maxLength": 256, + "minLength": 1, + "pattern": "^[A-Za-z0-9_-]+$", + "type": "string" + }, + { + "type": "null" + } + ] + }, + "returned": { + "maximum": 50, + "minimum": 0, + "type": "integer" + }, + "total": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "total", + "returned", + "nextCursor" + ], + "type": "object" + }, + "IntegrationTimestamp": { + "description": "ISO 8601 UTC timestamp supplied by Kunkafa.", + "format": "date-time", + "type": "string" + }, + "IntegrationUsage": { + "additionalProperties": false, + "properties": { + "adjustment": { + "additionalProperties": false, + "description": "An owner-approved account allowance increase. A null expiration is permanent until changed. Usage is never reset; market access and credential eligibility still follow the current plan.", + "properties": { + "expiresAt": { + "format": "date-time", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "expiresAt" + ], + "type": "object" + }, + "calculatedAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "concurrency": { + "additionalProperties": false, + "description": "Private requests that can run at the same time. Requests from one connection run side by side up to this limit (the plan burst); a request from another connection waits until they finish.", + "properties": { + "limit": { + "maximum": 100, + "minimum": 1, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "remaining": { + "maximum": 100, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "limit", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "requests": { + "additionalProperties": false, + "description": "Steady request rate with bounded burst capacity; metadata and repeated summaries still count toward request protection.", + "properties": { + "burst": { + "minimum": 0, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "perMinute": { + "minimum": 0, + "type": "integer" + }, + "remaining": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "perMinute", + "burst", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "tier": { + "enum": [ + "free", + "starter", + "core", + "pro", + "publisher" + ] + }, + "windows": { + "items": { + "$ref": "#/$defs/IntegrationWindowUsage" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + }, + "required": [ + "calculatedAt", + "tier", + "requests", + "concurrency", + "windows" + ], + "type": "object" + }, + "IntegrationWindowUsage": { + "additionalProperties": false, + "description": "Rolling 24-hour, 7-day or 30-day allowance, not a midnight reset. Used can exceed the current limit after a downgrade; remaining is never negative.", + "properties": { + "limit": { + "minimum": 0, + "type": "integer" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "notice": { + "enum": [ + "approaching_limit", + "limit_reached", + null + ] + }, + "noticeId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "period", + "used", + "limit", + "remaining", + "nextCapacityAt", + "notice", + "noticeId" + ], + "type": "object" + } + }, + "additionalProperties": false, + "properties": { + "data": { + "items": { + "$ref": "#/$defs/IntegrationMarket" + }, + "maxItems": 50, + "type": "array" + }, + "dataUse": { + "description": "Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model.", + "type": "string" + }, + "following": { + "$ref": "#/$defs/IntegrationFollowing" + }, + "notices": { + "items": { + "$ref": "#/$defs/IntegrationNotice" + }, + "maxItems": 3, + "type": "array" + }, + "page": { + "$ref": "#/$defs/IntegrationPage" + }, + "usage": { + "$ref": "#/$defs/IntegrationUsage" + } + }, + "required": [ + "data", + "following", + "usage", + "notices", + "page", + "dataUse" + ], + "type": "object" +}
- Changed
unfollow_market1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "IntegrationFollowing": { + "additionalProperties": false, + "description": "What the account follows and can still follow. Following decides which markets can be read; it happens in the Kunkafa app.", + "properties": { + "canFollow": { + "description": "Whether this connection may follow and unfollow markets.", + "type": "boolean" + }, + "canFollowMore": { + "description": "How many more markets can be followed; null when the account reads every market.", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "followInApp": { + "description": "Where the user follows markets in the Kunkafa app.", + "format": "uri", + "type": "string" + }, + "followLimit": { + "description": "The plan's Following count; null when the account reads every market.", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "followed": { + "description": "Markets on the account's following list, as the app counts them.", + "minimum": 0, + "type": "integer" + }, + "howToAllowFollowing": { + "description": "Present when canFollow is false.", + "minLength": 1, + "type": "string" + }, + "message": { + "description": "Plain explanation for the user, including for accounts that read every market.", + "type": "string" + }, + "otherMarkets": { + "description": "Catalogue markets the account does not follow, by English name, sorted by name; at most 100 (otherMarketsTotal gives the full count). Any market can still be followed by its slug.", + "items": { + "additionalProperties": false, + "properties": { + "market": { + "$ref": "#/$defs/IntegrationMarketSlug" + }, + "name": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "market", + "name" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "otherMarketsTotal": { + "description": "How many catalogue markets the account does not follow.", + "minimum": 0, + "type": "integer" + }, + "readsEveryMarket": { + "type": "boolean" + } + }, + "required": [ + "followed", + "followLimit", + "canFollowMore", + "readsEveryMarket", + "message", + "followInApp", + "otherMarkets", + "otherMarketsTotal" + ], + "type": "object" + }, + "IntegrationFollowingChange": { + "additionalProperties": false, + "properties": { + "action": { + "enum": [ + "followed", + "unfollowed", + "unchanged" + ] + }, + "market": { + "$ref": "#/$defs/IntegrationMarketSlug" + }, + "nextChangeAllowedAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ], + "description": "When a followed market may next be replaced; null while no replacement window runs." + } + }, + "required": [ + "market", + "action", + "nextChangeAllowedAt" + ], + "type": "object" + }, + "IntegrationMarketSlug": { + "description": "Published English-name market slug returned by authorized discovery.", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "type": "string" + }, + "IntegrationNotice": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "kind": { + "enum": [ + "approaching_limit", + "limit_reached" + ] + }, + "limit": { + "minimum": 0, + "type": "integer" + }, + "message": { + "type": "string" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "id", + "period", + "kind", + "message", + "used", + "limit", + "remaining", + "nextCapacityAt" + ], + "type": "object" + }, + "IntegrationTimestamp": { + "description": "ISO 8601 UTC timestamp supplied by Kunkafa.", + "format": "date-time", + "type": "string" + }, + "IntegrationUsage": { + "additionalProperties": false, + "properties": { + "adjustment": { + "additionalProperties": false, + "description": "An owner-approved account allowance increase. A null expiration is permanent until changed. Usage is never reset; market access and credential eligibility still follow the current plan.", + "properties": { + "expiresAt": { + "format": "date-time", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "expiresAt" + ], + "type": "object" + }, + "calculatedAt": { + "$ref": "#/$defs/IntegrationTimestamp" + }, + "concurrency": { + "additionalProperties": false, + "description": "Private requests that can run at the same time. Requests from one connection run side by side up to this limit (the plan burst); a request from another connection waits until they finish.", + "properties": { + "limit": { + "maximum": 100, + "minimum": 1, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "remaining": { + "maximum": 100, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "limit", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "requests": { + "additionalProperties": false, + "description": "Steady request rate with bounded burst capacity; metadata and repeated summaries still count toward request protection.", + "properties": { + "burst": { + "minimum": 0, + "type": "integer" + }, + "nextRequestAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "perMinute": { + "minimum": 0, + "type": "integer" + }, + "remaining": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "perMinute", + "burst", + "remaining", + "nextRequestAt" + ], + "type": "object" + }, + "tier": { + "enum": [ + "free", + "starter", + "core", + "pro", + "publisher" + ] + }, + "windows": { + "items": { + "$ref": "#/$defs/IntegrationWindowUsage" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + }, + "required": [ + "calculatedAt", + "tier", + "requests", + "concurrency", + "windows" + ], + "type": "object" + }, + "IntegrationWindowUsage": { + "additionalProperties": false, + "description": "Rolling 24-hour, 7-day or 30-day allowance, not a midnight reset. Used can exceed the current limit after a downgrade; remaining is never negative.", + "properties": { + "limit": { + "minimum": 0, + "type": "integer" + }, + "nextCapacityAt": { + "anyOf": [ + { + "$ref": "#/$defs/IntegrationTimestamp" + }, + { + "type": "null" + } + ] + }, + "notice": { + "enum": [ + "approaching_limit", + "limit_reached", + null + ] + }, + "noticeId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "period": { + "enum": [ + "day", + "week", + "month" + ] + }, + "remaining": { + "minimum": 0, + "type": "integer" + }, + "used": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "period", + "used", + "limit", + "remaining", + "nextCapacityAt", + "notice", + "noticeId" + ], + "type": "object" + } + }, + "additionalProperties": false, + "description": "The change and the account's following after it. The Kunkafa app shows the same list immediately.", + "properties": { + "data": { + "$ref": "#/$defs/IntegrationFollowingChange" + }, + "dataUse": { + "description": "Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model.", + "type": "string" + }, + "following": { + "$ref": "#/$defs/IntegrationFollowing" + }, + "notices": { + "items": { + "$ref": "#/$defs/IntegrationNotice" + }, + "maxItems": 3, + "type": "array" + }, + "usage": { + "$ref": "#/$defs/IntegrationUsage" + } + }, + "required": [ + "data", + "following", + "usage", + "notices", + "dataUse" + ], + "type": "object" +}
9 tool updates
- First observed
follow_market - First observed
get_account_links - First observed
get_glossary - First observed
get_outlooks - First observed
get_performance - First observed
get_results - First observed
get_usage - First observed
list_markets - First observed
unfollow_market
Publisher details
- Operator
- Kunkafa Limited · Publisher source
- Operator website
- https://kunkafa.com · Publisher source
- Vendor relationship
- First-party · Publisher source
- Documentation
- https://kunkafa.com/developers/setup · Publisher source
- Trust center
- Not applicable
- Restrictions
- MCP is included in every plan, including Free. Forecast data needs a Kunkafa account (OAuth sign-in); the glossary and account links work without one. REST API access requires a Pro or Publisher plan. · Publisher source
Related MCP Connectors
Autonomous AI agents research market events and publish aggregated forecasts.
> TradingMCP puts a market analyst inside your AI assistant. Paste one URL into Claude, ChatGPT, Cursor, VS Code or any MCP client and ask in plain language: screen for breakouts, run a multi-timeframe analysis, backtest a strategy with walk-forward validation, scan for smart-money and volume signals, or get a one-prompt morning market brief. In clients that support MCP Apps, price charts and the Markets panel are drawn right in the chat. > 40+ tools covering crypto (real-time), stocks, ETFs, FX, futures and commodities across major global exchanges. > Hosted, nothing to install: Pro $9/month (2,500 tool calls) or Pro+ $29/month (10,000). Paid upfront with a 14-day money-back guarantee; your API key arrives right after checkout. > Built on the open-source tradingview-mcp core (MIT, ~5k GitHub stars): self-host it free, or use the hosted version with zero ops. > For research and education, not financial advice. Not affiliated with TradingView
Real SEC, 13F, insider, congress & macro data your AI agent can cite. Hosted MCP, 24 tools.
AI research on companies and industries — one MCP tool per research domain.
Related MCP Servers
- AlicenseAqualityBmaintenanceAI-powered financial intelligence for autonomous trading agents. 9 MCP tools for real-time trading signals, risk index, market regime detection, stock analysis, commodity scoring, sector radar, and geopolitical intelligence briefings.131MIT
- AlicenseAqualityBmaintenancePay-per-call MCP server for market data with USDC micro-payments, featuring unique ML market-regime forecasts, news catalyst radar, and a live-verified algorithmic trading track record.12427 npmMIT
- FlicenseNot gradedqualityBmaintenanceBeforeTheChart AI is a $79 local trading MCP server for Claude Desktop and Cursor. Analyze Marketaux stock and cryptocurrency news sentiment with timestamps and sources, then calculate deterministic risk-based position sizes. Decision-support only—no trade execution, investment advice, or return promises.-
- AlicenseAqualityDmaintenanceGeneva MCP brings production-grade forecasting directly into AI assistants and coding agents. Connect any MCP-compatible client to the Geneva Forecasting Engine and run rigorous time series forecasts through natural conversation.1MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.