diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index 9d0b8381..7ba0480f 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -307,6 +307,11 @@ "name": "xero", "source": "third_party/xero", "description": "Read and write invoices, contacts, reports, and payroll." + }, + { + "name": "mida-so", + "source": "third_party/mida-so", + "description": "Create A/B tests, check results, and roll out winners on your site." } ] } diff --git a/README.md b/README.md index bbe4867f..3afe2379 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ Official Cursor plugins for popular developer tools, frameworks, and SaaS produc | `readwise` | [Readwise](third_party/readwise/) | Cursor | Integrations | Search highlights and Reader documents, save articles. | | `similarweb` | [Similarweb](third_party/similarweb/) | Cursor | Integrations | Analyze website traffic, audiences, and competitors. | | `xero` | [Xero](third_party/xero/) | Cursor | Integrations | Read and write invoices, contacts, reports, and payroll. | +| `mida-so` | [Mida](third_party/mida-so/) | Mida | Integrations | Create A/B tests, check results, and roll out winners on your site. | Author values match each plugin’s `plugin.json` `author.name` (Cursor lists `plugins@cursor.com` in the manifest). ## Repository structure diff --git a/third_party/mida-so/.cursor-plugin/plugin.json b/third_party/mida-so/.cursor-plugin/plugin.json new file mode 100644 index 00000000..0b373895 --- /dev/null +++ b/third_party/mida-so/.cursor-plugin/plugin.json @@ -0,0 +1,30 @@ +{ + "name": "mida-so", + "displayName": "Mida", + "version": "1.0.2", + "description": "Create A/B tests, check results, and roll out winners on your site.", + "author": { + "name": "Mida" + }, + "homepage": "https://www.mida.so/mcp", + "repository": "https://github.com/cursor/plugins", + "license": "MIT", + "logo": "assets/logo.svg", + "keywords": [ + "mida", + "ab-testing", + "experimentation", + "personalization", + "cro", + "mcp" + ], + "category": "integrations", + "tags": [ + "mida", + "ab-testing", + "experimentation", + "analytics" + ], + "skills": "./skills/", + "mcpServers": "./mcp.json" +} diff --git a/third_party/mida-so/CHANGELOG.md b/third_party/mida-so/CHANGELOG.md new file mode 100644 index 00000000..3764b91c --- /dev/null +++ b/third_party/mida-so/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog + +## 1.0.2 + +- Renamed the plugin to `mida-so`, matching the GitHub org and repo prefix. + +## 1.0.0 + +- Initial release: Mida MCP server (hosted, OAuth) plus the `mida` and + `mida-experiments` skills. diff --git a/third_party/mida-so/LICENSE b/third_party/mida-so/LICENSE new file mode 100644 index 00000000..2a0d3252 --- /dev/null +++ b/third_party/mida-so/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Mida + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/third_party/mida-so/README.md b/third_party/mida-so/README.md new file mode 100644 index 00000000..7b3c04d3 --- /dev/null +++ b/third_party/mida-so/README.md @@ -0,0 +1,72 @@ +# Mida + +**Test everything. Personalize everyone.** + +Run A/B tests and personalizations on your own website, from Cursor. + +[Mida](https://www.mida.so) is an A/B testing and personalization platform. A +small JavaScript tag on your site puts visitors into variants and reports +conversions. This plugin connects Cursor to your Mida account, so you can build +a test, launch it, read the result, conclude it, and roll the winner out while +you're still in the code the test is changing. + +``` +"What's running on the pricing page right now?" +"Create a test for a shorter signup form and preview variant B" +"Has the homepage hero test reached significance yet?" +"Conclude experiment #208, variant B won, we're shipping it" +``` + +## Setup + +On first use, Cursor opens a browser to sign in to Mida with OAuth. There is no +API key to paste and nothing is written to your machine. + +You need a [Mida account](https://www.mida.so) and the Mida tag installed on the +site you want to test. Ask for the install snippet once you're connected. + +## What's included + +**MCP server.** The hosted Mida MCP server, covering experiments (create, +launch, update, conclude, reopen), results and statistics, goals and custom +events, hypotheses, exclusion groups, personalization campaigns, project +configuration, and team access. + +**Skills** + +| Skill | Covers | +|---|---| +| `mida` | Entry point: picking the right project, reading Bayesian vs. frequentist results, and the order of operations for concluding a test and serving a winner | +| `mida-experiments` | The workflow: hypothesis, variants, goal, preview, launch, then calling the result | + +The skills are here because a few Mida behaviours are easy to get wrong from the +tool schemas alone. An experiment's display number is not its API id. A +concluded test stops serving even while its status still reads active. Setting a +test's status clears a conclusion written before it. Each one is documented with +the correct sequence. + +## Network and credentials + +| | | +|---|---| +| **Endpoints called** | `https://mcp.mida.so/mcp`, the hosted Mida MCP server, and the only host this plugin contacts. It reaches Mida's API server-side. | +| **Credentials** | OAuth to your Mida account, handled by the MCP client. No API keys, no environment variables, no local credential files. | +| **Scope** | Your own Mida organizations and projects. The plugin reads and writes experiment configuration and reads result data for those projects. | +| **Local execution** | None. No hooks, no commands, no scripts. One remote MCP server plus Markdown skills. | + +## About Mida + +[Mida](https://www.mida.so) is A/B testing and personalization in one engine. +Testing answers which version works. Personalization answers who it works for. +Both run as real variants in a real test, so personalization is something you +can actually prove rather than take on faith. + +- [Mida](https://www.mida.so), A/B testing on any site, with a tag that loads in about 20ms +- [Mida dashboard](https://app.mida.so) for results, goals, and rollouts +- [Public API docs](https://github.com/mida-so/api-docs) +- [MCP setup guide](https://www.mida.so/mcp) for every client +- [Plugin source](https://github.com/mida-so/mida-plugin) + +## License + +MIT, see [LICENSE](LICENSE). diff --git a/third_party/mida-so/assets/logo.svg b/third_party/mida-so/assets/logo.svg new file mode 100644 index 00000000..c211ea2a --- /dev/null +++ b/third_party/mida-so/assets/logo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/third_party/mida-so/mcp.json b/third_party/mida-so/mcp.json new file mode 100644 index 00000000..090ff199 --- /dev/null +++ b/third_party/mida-so/mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "mida": { + "type": "http", + "url": "https://mcp.mida.so/mcp" + } + } +} diff --git a/third_party/mida-so/skills/mida-experiments/SKILL.md b/third_party/mida-so/skills/mida-experiments/SKILL.md new file mode 100644 index 00000000..6b1142ea --- /dev/null +++ b/third_party/mida-so/skills/mida-experiments/SKILL.md @@ -0,0 +1,98 @@ +--- +name: mida-experiments +description: >- + Build and launch a Mida A/B test end to end: writing the hypothesis, creating + the experiment and its variants, attaching a goal, previewing the variant + before it goes live, launching, and deciding when there is enough data to + call it. Use when the user asks to test, try, or experiment with a change to + their site ("test a new headline", "try a different CTA", "does the shorter + form convert better"), or to review a test someone has already set up. +--- + +# Running an experiment in Mida + +Read the `mida` skill first for project selection and result-reading rules. This +skill is the workflow. + +## 1. Start from a hypothesis, not a change + +A test is only worth running if you can say in advance what you expect and how +you would know. Push for the shape: + +> Changing **X** for **audience Y** will improve **metric Z**, because **reason**. + +`create_hypothesis` stores it, and `link_hypothesis_to_experiment` ties it to the +test so the conclusion can be read against what was actually predicted. Before +writing a new one, `find_similar_tests` and `get_my_testing_history` will show +whether this account has already run something close. A repeat of a test that +already lost is the most common waste. + +## 2. Change one thing + +If a variant changes the headline, the button colour, and the form length at +once, a win tells you nothing about which of the three did it, and a loss tells +you nothing about which to keep. When a user describes a bundle of changes, say +so and offer to split it, unless they are deliberately testing a whole new +page, which is a legitimate and different kind of test. + +Keep the control as-is. Never "improve" the control while building the variant. + +## 3. Create the experiment + +`create_experiment` takes the target URL rule, the variants, and the traffic +split. Two things to get right at creation time: + +- **The URL rule is a pattern.** A test meant for every product page needs a + rule that matches them all; a rule pasted from one specific URL will match + that page only. Confirm which the user means. +- **Query strings are matched literally.** An entry URL written with `?param=x` + will only match visitors whose URL carries that exact query string, which + usually is not what someone wants. + +`get_experiment_distribution` after launch confirms traffic is actually splitting +the way you configured it. + +## 4. Attach the goal before launching + +An experiment with no goal collects visitors and measures nothing. Check +`list_goals` for an existing goal that already tracks the action, and reuse it +rather than creating a near-duplicate. Duplicates split the same conversions +across two metrics. + +Pick a primary goal that the change could plausibly move. A headline test +measured only on checkout completion will almost never reach significance; +measure the click the headline is trying to earn, and keep the downstream metric +as a secondary via `update_experiment`. + +## 5. Preview before you launch + +`generate_preview_url` returns a link that forces a given variant, so the user +can see the change on their real site before a single visitor does. Always offer +it. Broken variant markup that ships to 50% of traffic is the expensive failure +mode here, and it is entirely avoidable. + +## 6. Launch and leave it alone + +`update_experiment_status` starts delivery. Then: + +- **Do not read the result on day one.** Early numbers swing hard and reading + them invites stopping on noise. +- **Run at least one full business cycle**, usually a week, so every weekday is + represented in both arms. A test stopped on Wednesday inherits Wednesday's + traffic mix. +- **Do not edit a running test.** Changing the variant, the goal, or the + targeting mid-flight mixes two different experiments into one dataset. If the + change is necessary, stop the test and start a fresh one. + +## 7. Call it + +Use `get_experiment_result` with `compute_experiment_statistics`, and check +`get_experiment_timeseries` to see whether the result has settled or is still +moving. Then `conclude_experiment` with a written conclusion: what changed, +what happened, and what to do next. That write-up is what makes the account's +history worth anything later; a concluded test with an empty conclusion is a +test nobody can learn from. + +If the winner should keep serving while the change gets built for real, use +`serve_experiment_winner`, and see the ordering rules in the `mida` skill +before deploying that variant to source. diff --git a/third_party/mida-so/skills/mida/SKILL.md b/third_party/mida-so/skills/mida/SKILL.md new file mode 100644 index 00000000..32eba3fb --- /dev/null +++ b/third_party/mida-so/skills/mida/SKILL.md @@ -0,0 +1,121 @@ +--- +name: mida +description: >- + Working with Mida: A/B testing, split tests, and personalization on a live + website. Use whenever "Mida" is mentioned, and as the entry point for any + request to create, launch, check, pause, conclude, or roll out an experiment + on a site that runs the Mida tag. Also covers reading Mida results correctly + (Bayesian "chance to beat original" vs. p-value), goals and events, and the + order of operations that keeps a test's data clean. +--- + +# Mida + +Mida is an A/B testing and personalization platform. A JavaScript tag on the +customer's site assigns visitors to variants and reports conversions; the Mida +MCP server exposes that account so you can run the whole loop, from building a +test to serving the winner, without leaving the conversation. + +This plugin bundles the hosted Mida MCP server (`https://mcp.mida.so/mcp`, +OAuth). On first use Cursor opens a browser to sign in to Mida. Nothing is +stored locally and no API key is needed. + +## Always select a project first + +A Mida login can own several organizations and projects. The MCP session opens +on a **default project**, which is very often not the one the user means. + +Calls scoped to another project return `Mida API error 404: Experiment not +found`, which reads like a deleted test, not a scoping miss. Do not report a +404 as "that experiment doesn't exist" until you have selected the right +project. + +Start every Mida session with: + +1. `list_organizations` → `select_organization` (only if the user has more than one) +2. `list_projects` → `select_project` + +Then work. If a lookup 404s mid-session, re-check the selected project before +anything else. + +## "Experiment #208" is not `test_id` 208 + +Each account numbers its own experiments, and that number lives at the **start +of the experiment's name**, e.g. `#208 | Pricing page | Annual toggle default`. +It is not the global id the API uses. + +When a user says "experiment #208", call `list_experiments` and match the name +prefix. Passing `208` to `get_experiment` will either 404 or silently return an +unrelated test. + +## Reading results + +`get_experiment_result` reports against whichever statistics mode the project is +set to, and the two modes are read in opposite directions: + +| Mode | Column | How to read it | +|---|---|---| +| Bayesian (default) | Chance to Beat Original / Chance to be Best | **Higher is better.** 95% means a 95% probability the variant beats control. | +| Frequentist | P-value | **Lower is better.** 0.05 is the conventional bar. | + +Two things to hold onto before you call a result: + +- **Chance-to-beat is one-directional.** It answers "is the variant better?" A + low value means "not shown to be better", *not* "shown to be worse", and it + cannot rank how bad a loser is. To speak about a loss, use the observed lift + and the sample size, not the inverse of the probability. +- **Check power before calling anything.** A test with a few hundred visitors + per arm will swing wildly day to day. `compute_experiment_statistics` and + `get_experiment_timeseries` are there to show whether the number has settled; + use them rather than reporting the headline figure alone. + +Related tools: `get_experiment_metrics` (per-goal breakdown), +`get_experiment_distribution` (traffic split sanity check), +`get_testing_benchmarks` (how this result compares to typical outcomes). + +## Order of operations + +These sequences matter: getting them backwards silently corrupts a test. + +**Concluding a test.** `update_experiment_status` resets the completed flag. So +if you are both stopping and concluding a test, set the status **first** and +call `conclude_experiment` **last**, or the write-up is dropped. + +**Serving a winner.** `conclude_experiment` ends delivery on its own. A +concluded test stops serving even while its status still reads active. The one +exception is a test with a served winner: `serve_experiment_winner` keeps that +variant serving to everyone after the test is concluded, which is usually what +the user wants while they ship the change for real. + +**Hardcoding a winner into the site.** Stop the test *before* deploying the +winning copy to source. Deploy first and the control arm starts serving the new +copy too. Both arms become identical and the rest of the data is noise. + +## Goals and events + +A test measures nothing until a goal is attached. `list_goals` /`create_goal` +manage them; `list_events` / `create_event` handle custom events the tag fires. +`update_experiment` can attach secondary metrics to a test that is already live. + +When creating a click goal, the element selector is matched as a **pattern**, +not an exact string. Check `list_goals` for an existing goal that already +covers the element before adding a near-duplicate. + +## Before anything runs: the tag + +Nothing works until Mida's tag is on the site. `get_install_snippet` returns the +snippet for the selected project. If a live test reports no visitors at all, the +tag is the first thing to check, not the targeting. + +## Tool map + +- **Setup:** `get_mida_api_context`, `get_install_snippet`, `get_my_access`, `get_project_configuration` +- **Build & launch:** `create_experiment`, `update_experiment`, `generate_preview_url`, `update_experiment_status` +- **Measure:** `get_experiment_result`, `get_experiment_metrics`, `get_experiment_timeseries`, `compute_experiment_statistics` +- **Finish:** `conclude_experiment`, `serve_experiment_winner`, `update_serving_rollout`, `stop_experiment_serving`, `reopen_experiment` +- **Plan:** `list_hypotheses`, `create_hypothesis`, `link_hypothesis_to_experiment`, `find_similar_tests`, `get_my_testing_history` +- **Personalization:** `suggest_pages_to_personalize`, `create_persona_campaign`, `create_target_account_campaign` + +## Docs + +https://www.mida.so for product and pricing. The dashboard is https://app.mida.so.