@apex-inc/mcp-server 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Apex Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # @apex-inc/mcp-server
2
+
3
+ Persistent growth intelligence for AI agents and developer tools.
4
+
5
+ The Apex MCP server gives your AI agent a persistent growth brain — beliefs, predictions, experiments, and calibration that compound across every session. Instead of starting from zero, your AI draws on everything your team has ever learned: which beliefs have been validated, which predictions were accurate, and what to test next.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @apex-inc/mcp-server
11
+ ```
12
+
13
+ ## Configure
14
+
15
+ Add to `.cursor/mcp.json`:
16
+
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "apex": {
21
+ "command": "npx",
22
+ "args": ["@apex-inc/mcp-server"],
23
+ "env": {
24
+ "APEX_URL": "https://your-apex-instance.com",
25
+ "APEX_API_URL": "https://your-apex-instance.com",
26
+ "APEX_API_KEY": "apex_key_your_key_here",
27
+ "APEX_PROJECT_KEY": "your-project-key"
28
+ }
29
+ }
30
+ }
31
+ }
32
+ ```
33
+
34
+ ### Environment Variables
35
+
36
+ | Variable | Required | Description |
37
+ |----------|----------|-------------|
38
+ | `APEX_URL` | No | Base URL of the Apex app (default: `http://localhost:3001`) |
39
+ | `APEX_API_KEY` | Recommended | API key for authenticated access |
40
+ | `APEX_PROJECT_KEY` | No | Project key for multi-project setups (default: `default`) |
41
+
42
+ ## MCP Tools (19)
43
+
44
+ ### Growth Intelligence
45
+
46
+ Query the persistent knowledge system — beliefs, predictions, calibration, and recommendations.
47
+
48
+ | Tool | Description |
49
+ |------|-------------|
50
+ | `suggest_experiment` | Context-aware experiment recommendations based on beliefs, past results, and confidence gaps |
51
+ | `predict_impact` | Decision guardrail — predict impact using historical experiment data before committing |
52
+ | `evaluate_feature` | Pre-build intelligence — evaluate a feature idea against the belief graph |
53
+ | `create_belief` | Record a belief (confirms statement and confidence with user first) |
54
+ | `log_prediction` | Log a prediction — feeds the calibration loop tracking team accuracy |
55
+ | `record_outcome` | Record outcome with Bayesian belief update |
56
+
57
+ ### Experiment Engine
58
+
59
+ Design, run, and measure controlled experiments.
60
+
61
+ | Tool | Description |
62
+ |------|-------------|
63
+ | `plan_experiment` | Analyze a goal against beliefs and experiments, returns structured options |
64
+ | `start_reasoning` | Record a belief → hypothesis chain |
65
+ | `create_experiment` | Create an A/B test — supports `preview=true` for dry run |
66
+ | `activate_experiment` | Launch an experiment (changes draft → running) |
67
+ | `pause_experiment` | Pause a running experiment (all visitors see control) |
68
+ | `list_experiments` | List experiments with status and results. Pass `status: "archived"` or `"all"` |
69
+ | `get_results` | Detailed results for a specific experiment |
70
+ | `promote_winner` | Mark the winning variant and complete the experiment |
71
+ | `archive_experiment` | Archive an experiment (preserves all data and belief connections) |
72
+
73
+ ### Deployment & Tracking
74
+
75
+ | Tool | Description |
76
+ |------|-------------|
77
+ | `track_deployment` | Record that experiment code has been committed and pushed |
78
+ | `check_deployment` | Verify the experiment assignment endpoint is reachable |
79
+ | `track_event` | Track a custom event (identical to SDK `track()` and snippet `apex.track()`) |
80
+ | `identify_user` | Identify a user by email for identity stitching |
81
+
82
+ ## Shipped skills (Cursor / AI assistants)
83
+
84
+ Markdown skills ship in **`skills/`** inside this package (e.g. `skills/apex-experimentation/SKILL.md`). Copy each skill folder into **`.cursor/skills/<skill-name>/`** so your assistant learns when to suggest experiments and how to instrument tracking.
85
+
86
+ Your Apex app also serves the same files at **`/shipped-skills/<skill-id>/SKILL.md`** (see **Install → JSON** response from `/api/mcp-install` for URLs and install steps).
87
+
88
+ Set **`APEX_URL`** to your Apex base URL (the MCP client uses this; **`APEX_API_URL`** is accepted for compatibility).
89
+
90
+ ## MCP Resources (6)
91
+
92
+ | URI | Name | Description |
93
+ |-----|------|-------------|
94
+ | `apex://beliefs` | Assumptions | All tracked assumptions with certainty scores and test status |
95
+ | `apex://experiments/active` | Running Experiments | Currently running experiments with results and assumption linkages |
96
+ | `apex://ledger` | Learning Log | History of everything learned from experiments — decisions, reasoning, belief updates |
97
+ | `apex://intelligence-score` | Learning Rate | How much of what you assume has been tested, and how fast you're learning |
98
+ | `apex://intelligence` | Growth Intelligence | Full intelligence metrics: score breakdown, revenue data, learning velocity |
99
+ | `apex://calibration` | Prediction Calibration | Prediction accuracy and calibration data — how well predictions match reality |
100
+
101
+ ## MCP Prompts (2)
102
+
103
+ | Prompt | Description |
104
+ |--------|-------------|
105
+ | `new-experiment` | Interactive experiment setup — guides through belief selection, prediction, variant design, and deployment |
106
+ | `experiment-review` | Review results, update beliefs, promote winners, and plan next steps |
107
+
108
+ ## Example Workflows
109
+
110
+ ### Interactive experiment creation
111
+
112
+ ```
113
+ You: "I want to test a new headline on the landing page"
114
+
115
+ Step 1 — AI calls plan_experiment({ goal: "test headline on landing page" })
116
+ → Returns: suggested beliefs, metrics, confidence levels, traffic splits
117
+ → AI presents these as structured choices
118
+
119
+ Step 2 — You choose belief, confidence, and metric
120
+ → AI calls start_reasoning with your choices
121
+ → AI asks: "Want to log a prediction?"
122
+
123
+ Step 3 — You pick metric and expected impact
124
+ → AI calls log_prediction with your inputs
125
+
126
+ Step 4 — AI proposes variant headlines for you to choose
127
+ → You pick one or write your own
128
+
129
+ Step 5 — AI calls create_experiment({ ..., preview: true })
130
+ → Shows the full plan — you confirm → create_experiment({ ..., preview: false })
131
+ ```
132
+
133
+ ### Decision guardrail before a change
134
+
135
+ ```
136
+ Developer: "Let's increase signup form fields from 3 to 5"
137
+ → AI calls predict_impact({ description: "increase signup form fields from 3 to 5" })
138
+ → Returns: "Similar experiments decreased activation by 18%. Recommendation: RECONSIDER"
139
+ ```
140
+
141
+ ### Pre-build feature evaluation
142
+
143
+ ```
144
+ Developer: "Should we build a freemium tier?"
145
+ → AI calls evaluate_feature({ feature: "freemium pricing tier", targetMetric: "activation" })
146
+ → Returns: belief graph analysis, historical evidence, confidence gaps, and suggestion
147
+ ```
148
+
149
+ ## License
150
+
151
+ MIT — see [LICENSE](./LICENSE)
@@ -0,0 +1,5 @@
1
+ export declare function apiGet<T>(path: string): Promise<T>;
2
+ export declare function apiPost<T>(path: string, body: unknown): Promise<T>;
3
+ export declare function apiDelete(path: string): Promise<void>;
4
+ export declare function apiPatch<T>(path: string, body: unknown): Promise<T>;
5
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AASA,wBAAsB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CASxD;AAED,wBAAsB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAWxE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS3D;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAWzE"}
@@ -0,0 +1,53 @@
1
+ const BASE_URL = process.env.APEX_URL || "http://localhost:3001";
2
+ function authHeaders() {
3
+ const key = process.env.APEX_API_KEY;
4
+ const headers = { "x-apex-source": "mcp-server" };
5
+ if (key)
6
+ headers["x-api-key"] = key;
7
+ return headers;
8
+ }
9
+ export async function apiGet(path) {
10
+ const res = await fetch(`${BASE_URL}${path}`, {
11
+ headers: { ...authHeaders() },
12
+ });
13
+ if (!res.ok) {
14
+ const body = await res.text().catch(() => "");
15
+ throw new Error(`GET ${path} failed (${res.status}): ${body}`);
16
+ }
17
+ return res.json();
18
+ }
19
+ export async function apiPost(path, body) {
20
+ const res = await fetch(`${BASE_URL}${path}`, {
21
+ method: "POST",
22
+ headers: { "Content-Type": "application/json", ...authHeaders() },
23
+ body: JSON.stringify(body),
24
+ });
25
+ if (!res.ok) {
26
+ const text = await res.text().catch(() => "");
27
+ throw new Error(`POST ${path} failed (${res.status}): ${text}`);
28
+ }
29
+ return res.json();
30
+ }
31
+ export async function apiDelete(path) {
32
+ const res = await fetch(`${BASE_URL}${path}`, {
33
+ method: "DELETE",
34
+ headers: { ...authHeaders() },
35
+ });
36
+ if (!res.ok) {
37
+ const text = await res.text().catch(() => "");
38
+ throw new Error(`DELETE ${path} failed (${res.status}): ${text}`);
39
+ }
40
+ }
41
+ export async function apiPatch(path, body) {
42
+ const res = await fetch(`${BASE_URL}${path}`, {
43
+ method: "PATCH",
44
+ headers: { "Content-Type": "application/json", ...authHeaders() },
45
+ body: JSON.stringify(body),
46
+ });
47
+ if (!res.ok) {
48
+ const text = await res.text().catch(() => "");
49
+ throw new Error(`PATCH ${path} failed (${res.status}): ${text}`);
50
+ }
51
+ return res.json();
52
+ }
53
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ import { toolDefinitions } from "./tools.js";
6
+ import { resourceDefinitions } from "./resources.js";
7
+ import { promptDefinitions } from "./prompts.js";
8
+ const server = new McpServer({
9
+ name: "apex",
10
+ version: "0.1.0",
11
+ });
12
+ // --- Register tools ---
13
+ for (const [name, def] of Object.entries(toolDefinitions)) {
14
+ server.tool(name, def.description, def.schema.shape, async (args) => {
15
+ try {
16
+ return await def.handler(args);
17
+ }
18
+ catch (err) {
19
+ const message = err instanceof Error ? err.message : String(err);
20
+ return {
21
+ content: [{ type: "text", text: `Error: ${message}` }],
22
+ isError: true,
23
+ };
24
+ }
25
+ });
26
+ }
27
+ // --- Register resources ---
28
+ for (const def of Object.values(resourceDefinitions)) {
29
+ server.resource(def.name, def.uri, { description: def.description, mimeType: def.mimeType }, async () => {
30
+ return await def.handler();
31
+ });
32
+ }
33
+ // --- Register prompts ---
34
+ server.prompt("new-experiment", "Walk through setting up a new experiment: goal, assumption, expected outcome, and test design", { decision: z.string().optional().describe("What you want to improve") }, (args) => promptDefinitions["new-experiment"].handler(args));
35
+ server.prompt("experiment-review", "Review experiment results, see what you learned, and decide what to do next", { experimentId: z.string().describe("The experiment ID to review") }, (args) => promptDefinitions["experiment-review"].handler(args));
36
+ // --- Start ---
37
+ async function main() {
38
+ const transport = new StdioServerTransport();
39
+ await server.connect(transport);
40
+ }
41
+ main().catch((err) => {
42
+ console.error("Apex MCP server failed to start:", err);
43
+ process.exit(1);
44
+ });
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,yBAAyB;AAEzB,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;IAC1D,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE;QAC3F,IAAI,CAAC;YACH,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,IAAa,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;gBAC/D,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,6BAA6B;AAE7B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC;IACrD,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,KAAK,IAAI,EAAE;QACtG,OAAO,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,2BAA2B;AAE3B,MAAM,CAAC,MAAM,CACX,gBAAgB,EAChB,+FAA+F,EAC/F,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,EACxE,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,IAA8B,CAAC,CACtF,CAAC;AAEF,MAAM,CAAC,MAAM,CACX,mBAAmB,EACnB,6EAA6E,EAC7E,EAAE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC,EAAE,EACpE,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,IAA8B,CAAC,CACzF,CAAC;AAEF,gBAAgB;AAEhB,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,39 @@
1
+ export declare const promptDefinitions: {
2
+ "new-experiment": {
3
+ name: string;
4
+ description: string;
5
+ arguments: {
6
+ name: string;
7
+ description: string;
8
+ required: boolean;
9
+ }[];
10
+ handler: (args: Record<string, string>) => {
11
+ messages: {
12
+ role: "user";
13
+ content: {
14
+ type: "text";
15
+ text: string;
16
+ };
17
+ }[];
18
+ };
19
+ };
20
+ "experiment-review": {
21
+ name: string;
22
+ description: string;
23
+ arguments: {
24
+ name: string;
25
+ description: string;
26
+ required: boolean;
27
+ }[];
28
+ handler: (args: Record<string, string>) => {
29
+ messages: {
30
+ role: "user";
31
+ content: {
32
+ type: "text";
33
+ text: string;
34
+ };
35
+ }[];
36
+ };
37
+ };
38
+ };
39
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB;;;;;;;;;wBAYV,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;;;;;;;;;;;;;;wBA6KtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;;;;;;CAqCzC,CAAC"}
@@ -0,0 +1,220 @@
1
+ export const promptDefinitions = {
2
+ "new-experiment": {
3
+ name: "new-experiment",
4
+ description: "Launch a new experiment with Apex. Interactive setup with code-level implementation.",
5
+ arguments: [
6
+ {
7
+ name: "decision",
8
+ description: "What you want to improve (optional — will ask if not provided)",
9
+ required: false,
10
+ },
11
+ ],
12
+ handler: (args) => {
13
+ const decision = args.decision;
14
+ const intro = decision
15
+ ? `The user wants to improve: "${decision}"\n\n`
16
+ : "";
17
+ return {
18
+ messages: [
19
+ {
20
+ role: "user",
21
+ content: {
22
+ type: "text",
23
+ text: `${intro}You are helping me launch an experiment using **Apex** (Apex).
24
+
25
+ ## MANDATORY UX RULES
26
+
27
+ You MUST use the \`AskQuestion\` tool for EVERY decision point. Never ask the user to type a number or free-text response unless they explicitly request it.
28
+
29
+ ### AskQuestion formatting rules:
30
+ - **title**: Always start with "Apex —" followed by the step name (e.g. "Apex — Pick a Belief")
31
+ - **ONE question per call** — never batch multiple questions. One step, one poll.
32
+ - **Options must be self-explanatory** — include enough context in the label that the user doesn't need to read chat history
33
+ - **Do NOT add "Custom", "I'll write my own", or any free-text escape hatch option** — Cursor's AskQuestion already provides an "Other..." option automatically. Adding a redundant one clutters the UI.
34
+ - **Every step is mandatory — never offer a "Skip" option** — predictions, confidence, and all other inputs are required. Skipping undermines the calibration loop and the scientific rigor of Apex.
35
+ - **Never auto-fill values the user should choose** — confidence, predictions, and variant text are THEIR inputs
36
+ - **Match the Apex dashboard UI** — poll options must use the same terminology and choices as the web dashboard (e.g. "Adaptive Traffic Allocation" not "Thompson Sampling", same confidence tiers, same split options)
37
+
38
+ ### Branding:
39
+ Every message you write should make it clear the user is working with Apex. Start messages with "Apex" when presenting results or summaries. The user should always know their selections are feeding the Apex intelligence layer.
40
+
41
+ ## Architecture
42
+
43
+ Apex uses two experiment modes:
44
+ - **SDK mode** (default via MCP): You make real code changes using \`useApexVariant\` hook. Pixel-perfect previews, requires deploy.
45
+ - **Snippet mode**: Runtime DOM manipulation via JS snippet. No code changes, but limited to text swaps.
46
+
47
+ For MCP workflows, always use SDK mode unless the user explicitly requests snippet mode.
48
+
49
+ ## Flow — one AskQuestion at a time
50
+
51
+ ### Step 1: Understand the Goal
52
+ ${decision ? `I want to improve: "${decision}". ` : "Use AskQuestion to ask what the user wants to improve. "}Call \`plan_experiment\` with the goal. Then use AskQuestion to present beliefs:
53
+
54
+ \`\`\`
55
+ AskQuestion:
56
+ title: "Apex — Pick a Belief"
57
+ prompt: "Which assumption should this experiment test?"
58
+ options: [related beliefs from plan_experiment] + [suggested new beliefs]
59
+ \`\`\`
60
+
61
+ ### Step 2: Confidence Level
62
+ After the user picks a belief, use AskQuestion BEFORE calling start_reasoning:
63
+
64
+ \`\`\`
65
+ AskQuestion:
66
+ title: "Apex — Your Confidence"
67
+ prompt: "How confident are you that: \"[belief statement]\"?"
68
+ options:
69
+ - "Low (30%) — Gut feeling, no supporting data yet"
70
+ - "Medium (55%) — Some signals, but hasn't been tested"
71
+ - "High (75%) — Strong evidence from past experiments or data"
72
+ - "Very High (90%) — Near-certain, well-established pattern"
73
+ \`\`\`
74
+
75
+ Only call \`start_reasoning\` AFTER the user picks confidence.
76
+
77
+ ### Step 3: Prediction
78
+ \`\`\`
79
+ AskQuestion:
80
+ title: "Apex — Log a Prediction"
81
+ prompt: "What lift do you expect? Apex tracks prediction accuracy over time to sharpen your forecasting."
82
+ options:
83
+ - "Small lift (+5%) — Incremental improvement"
84
+ - "Moderate lift (+10%) — Meaningful change"
85
+ - "Large lift (+15-20%) — High-conviction bet"
86
+ \`\`\`
87
+
88
+ ### Step 4: Variant Design
89
+ Present ONE question at a time:
90
+
91
+ First — what to change:
92
+ \`\`\`
93
+ AskQuestion:
94
+ title: "Apex — What to Change"
95
+ prompt: "Which element should we test? (Current page: [url])"
96
+ options: [2-3 specific elements from the page]
97
+ \`\`\`
98
+
99
+ Then — variant text:
100
+ \`\`\`
101
+ AskQuestion:
102
+ title: "Apex — Variant Content"
103
+ prompt: "What should the variant say? (Current: [original text])"
104
+ options: [2-3 suggestions based on the belief]
105
+ \`\`\`
106
+
107
+ Then — traffic allocation:
108
+ \`\`\`
109
+ AskQuestion:
110
+ title: "Apex — Traffic Allocation"
111
+ prompt: "How should Apex allocate traffic?"
112
+ options:
113
+ - "Adaptive (recommended) — Automatically shifts traffic toward the winning variant using Thompson Sampling"
114
+ - "Balanced 50/50 — Equal split, fastest to reach significance"
115
+ - "Conservative 80/20 — Minimal exposure to variant, lower risk"
116
+ \`\`\`
117
+ NOTE: "Adaptive" is the default and recommended option. It starts at 50/50 and Thompson Sampling adjusts automatically. These options must match what the Apex dashboard UI offers.
118
+
119
+ ### Step 5: Preview & Create
120
+ Call \`create_experiment\` with preview=true. Present summary, then:
121
+
122
+ \`\`\`
123
+ AskQuestion:
124
+ title: "Apex — Confirm Experiment"
125
+ prompt: "[summary of experiment]"
126
+ options: Create it | Change variant text | Change traffic split | Cancel
127
+ \`\`\`
128
+
129
+ If confirmed, call \`create_experiment\` with preview=false.
130
+
131
+ ### Step 6: Implement (SDK mode)
132
+ The create_experiment response contains an \`sdk\` recipe. Make the code changes:
133
+ 1. Import \`useApexVariant\` from \`@/lib/apex-sdk\`
134
+ 2. Add \`const variant = useApexVariant("<experimentId>")\`
135
+ 3. Wrap the target content in a variant conditional
136
+ 4. Show the diff, then:
137
+
138
+ \`\`\`
139
+ AskQuestion:
140
+ title: "Apex — Review Code Changes"
141
+ prompt: "Code changes ready. What's next?"
142
+ options: Preview locally | Edit the changes | Cancel
143
+ \`\`\`
144
+
145
+ ### Step 7: Preview & Deploy
146
+ After preview approval:
147
+
148
+ \`\`\`
149
+ AskQuestion:
150
+ title: "Apex — Deploy"
151
+ prompt: "Preview looks good?"
152
+ options: Commit & push | Make changes | Cancel
153
+ \`\`\`
154
+
155
+ Commit, push, call \`track_deployment\`.
156
+
157
+ ### Step 8: Activate
158
+ \`\`\`
159
+ AskQuestion:
160
+ title: "Apex — Go Live"
161
+ prompt: "Experiment deployed. Ready to start collecting data?"
162
+ options: Activate now | Keep as draft
163
+ \`\`\`
164
+
165
+ Start now.`,
166
+ },
167
+ },
168
+ ],
169
+ };
170
+ },
171
+ },
172
+ "experiment-review": {
173
+ name: "experiment-review",
174
+ description: "Review experiment results with Apex. See what happened, what it means, and decide what to do next.",
175
+ arguments: [
176
+ {
177
+ name: "experimentId",
178
+ description: "The ID of the experiment to review",
179
+ required: true,
180
+ },
181
+ ],
182
+ handler: (args) => {
183
+ return {
184
+ messages: [
185
+ {
186
+ role: "user",
187
+ content: {
188
+ type: "text",
189
+ text: `Review experiment ${args.experimentId} using Apex (Apex).
190
+
191
+ ## MANDATORY UX RULES
192
+ Use \`AskQuestion\` tool for every decision. One question at a time. Title always starts with "Apex —".
193
+
194
+ ## Steps
195
+
196
+ 1. Call \`get_results\` to pull current data
197
+ 2. Present results clearly as a text summary (winner, lift, confidence, data volume)
198
+ 3. Use AskQuestion:
199
+
200
+ \`\`\`
201
+ AskQuestion:
202
+ title: "Apex — Experiment Results"
203
+ prompt: "[experiment name]: [summary of results]"
204
+ options:
205
+ - Promote winner (graduates the experiment)
206
+ - Keep running (need more data)
207
+ - Pause (stop collecting temporarily)
208
+ - Record outcome (log learnings to belief graph)
209
+ - Suggest next experiment
210
+ \`\`\`
211
+
212
+ If promoting a winner, the \`promote_winner\` response includes a code cleanup recipe for SDK experiments. Follow those instructions to graduate the code (remove useApexVariant conditional, keep only the winner).`,
213
+ },
214
+ },
215
+ ],
216
+ };
217
+ },
218
+ },
219
+ };
220
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,gBAAgB,EAAE;QAChB,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,sFAAsF;QACxF,SAAS,EAAE;YACT;gBACE,IAAI,EAAE,UAAU;gBAChB,WAAW,EAAE,gEAAgE;gBAC7E,QAAQ,EAAE,KAAK;aAChB;SACF;QACD,OAAO,EAAE,CAAC,IAA4B,EAAE,EAAE;YACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC/B,MAAM,KAAK,GAAG,QAAQ;gBACpB,CAAC,CAAC,+BAA+B,QAAQ,OAAO;gBAChD,CAAC,CAAC,EAAE,CAAC;YAEP,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAe;wBACrB,OAAO,EAAE;4BACP,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,GAAG,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6B1B,QAAQ,CAAC,CAAC,CAAC,uBAAuB,QAAQ,KAAK,CAAC,CAAC,CAAC,yDAAyD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAiHlG;yBACE;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;KACF;IAED,mBAAmB,EAAE;QACnB,IAAI,EAAE,mBAAmB;QACzB,WAAW,EACT,oGAAoG;QACtG,SAAS,EAAE;YACT;gBACE,IAAI,EAAE,cAAc;gBACpB,WAAW,EAAE,oCAAoC;gBACjD,QAAQ,EAAE,IAAI;aACf;SACF;QACD,OAAO,EAAE,CAAC,IAA4B,EAAE,EAAE;YACxC,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAe;wBACrB,OAAO,EAAE;4BACP,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,qBAAqB,IAAI,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;qNAuB2J;yBACxM;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;KACF;CACF,CAAC"}
@@ -0,0 +1,81 @@
1
+ export declare const resourceDefinitions: {
2
+ beliefs: {
3
+ uri: string;
4
+ name: string;
5
+ description: string;
6
+ mimeType: string;
7
+ handler: () => Promise<{
8
+ contents: {
9
+ uri: string;
10
+ text: string;
11
+ mimeType: string;
12
+ }[];
13
+ }>;
14
+ };
15
+ activeExperiments: {
16
+ uri: string;
17
+ name: string;
18
+ description: string;
19
+ mimeType: string;
20
+ handler: () => Promise<{
21
+ contents: {
22
+ uri: string;
23
+ text: string;
24
+ mimeType: string;
25
+ }[];
26
+ }>;
27
+ };
28
+ ledger: {
29
+ uri: string;
30
+ name: string;
31
+ description: string;
32
+ mimeType: string;
33
+ handler: () => Promise<{
34
+ contents: {
35
+ uri: string;
36
+ text: string;
37
+ mimeType: string;
38
+ }[];
39
+ }>;
40
+ };
41
+ intelligenceScore: {
42
+ uri: string;
43
+ name: string;
44
+ description: string;
45
+ mimeType: string;
46
+ handler: () => Promise<{
47
+ contents: {
48
+ uri: string;
49
+ text: string;
50
+ mimeType: string;
51
+ }[];
52
+ }>;
53
+ };
54
+ intelligence: {
55
+ uri: string;
56
+ name: string;
57
+ description: string;
58
+ mimeType: string;
59
+ handler: () => Promise<{
60
+ contents: {
61
+ uri: string;
62
+ text: string;
63
+ mimeType: string;
64
+ }[];
65
+ }>;
66
+ };
67
+ calibration: {
68
+ uri: string;
69
+ name: string;
70
+ description: string;
71
+ mimeType: string;
72
+ handler: () => Promise<{
73
+ contents: {
74
+ uri: string;
75
+ text: string;
76
+ mimeType: string;
77
+ }[];
78
+ }>;
79
+ };
80
+ };
81
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AA2DA,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqM/B,CAAC"}