@usercase/mcp 0.2.4-next.1 → 0.2.4-next.3
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/agents/condition.md +31 -31
- package/agents/steps.md +5 -1
- package/mcp/server.js +1 -1
- package/package.json +1 -1
package/agents/condition.md
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
A condition has a `page` (the screen the visitor is on when the card appears), `steps` in order, and a `moment`.
|
|
2
|
-
|
|
3
|
-
Step kinds (`do`): `arrive` · `back` · `click` · `input` · `submit` · `scroll` · `idle` · `hide` (tab hidden) · `error` (a JavaScript error).
|
|
4
|
-
Options on a step: `page`, `from` (arrive/back), `target` (click/input/submit), `atLeast`, `percent` (scroll), `seconds` (idle: a pause between two actions), `cleared` (input: typed then deleted), `absent` (this did not happen between the previous step and the moment).
|
|
5
|
-
Moment: `on_match` (as soon as the steps are met) · `idle` with `seconds` (then that long with no
|
|
6
|
-
|
|
7
|
-
Globs: `*` matches anything including `/`; `:name` matches one path segment (`/project/:slug`). Use the route parameter names from the code. Never put `?` or `#` in a glob.
|
|
8
|
-
|
|
9
|
-
Targets match the element's own text, field name or class — case does not matter, and the words only need to be contained. Prefer the words the visitor saw. Use `class:name` for buttons without text and `tag:BUTTON` only when the text differs every time (a list of names).
|
|
10
|
-
|
|
11
|
-
Steps happen in order, with anything allowed in between. All steps must happen; there is no "or" — two situations are two questions.
|
|
12
|
-
|
|
13
|
-
**It cannot see:** what is on the screen (an error message, an empty list, a price), the values typed (only length and whether it was cleared), time limits ("within 10 seconds"), who the visitor is (device, new or returning, campaign), or anything across visits. A visit is one tab; 30 minutes of nothing starts a new one. If the user asks for one of these, say so and offer the nearest thing it can do — usually a behavior that goes with it (a submit followed by no arrival at the next page, instead of "an error was shown").
|
|
14
|
-
|
|
15
|
-
Rules that make a card actually appear and mean something:
|
|
16
|
-
- The card must be shown on the screen where the trouble is. A click that opens another page ends the situation — use the `arrive` on the next page instead.
|
|
17
|
-
- Never ask while they are typing: the last step of an `on_match` condition must not be `input`. Use `idle` or the next step.
|
|
18
|
-
- Never ask the moment someone lands on a sign-in, sign-up or payment screen; use `idle` or `leave` there.
|
|
19
|
-
- The page must name a real screen, not only wildcards.
|
|
20
|
-
- Narrow enough to be one situation: a condition that matches a large share of all visits is too broad.
|
|
21
|
-
|
|
22
|
-
### Checking it
|
|
23
|
-
|
|
24
|
-
Call `question_check` with the condition. Read the result:
|
|
25
|
-
- **Problems**: fix them and check again. The server refuses the condition while there are any.
|
|
26
|
-
- **Does not match recent visits** (matched 0, a path or word not seen): usually a wrong path or word — compare with `question_context` and the code, and fix it. But the screen or button may be new or not live yet. Then tell the user it has not been seen in recent visits, and send it with `acceptWarnings: true` only if they say so.
|
|
27
|
-
- **Examples**: read what the matched visitors did. If it is not the situation the user meant, the condition is wrong even if it passes.
|
|
28
|
-
- **Overlaps**: an existing question fires at the same moment; only one card shows per visit. Tell the user.
|
|
29
|
-
- `idle` and `leave` moments are not counted by the check — it counts visits where the steps happened. Fewer people will actually see the card.
|
|
30
|
-
|
|
31
|
-
`triggerEn`: one plain sentence a product manager understands, saying when the card appears. No paths or class names.
|
|
1
|
+
A condition has a `page` (the screen the visitor is on when the card appears), `steps` in order, and a `moment`.
|
|
2
|
+
|
|
3
|
+
Step kinds (`do`): `arrive` · `back` · `click` · `input` · `submit` · `scroll` · `idle` · `hide` (tab hidden) · `error` (a JavaScript error).
|
|
4
|
+
Options on a step: `page`, `from` (arrive/back), `target` (click/input/submit), `atLeast`, `percent` (scroll), `seconds` (idle: a pause between two actions), `cleared` (input: typed then deleted), `absent` (this did not happen between the previous step and the moment).
|
|
5
|
+
Moment: `on_match` (as soon as the steps are met) · `idle` with `seconds` (then that long with no click, typing or page change; scrolling and reading still count as a pause) · `leave` (about to leave; on phones, a long pause instead).
|
|
6
|
+
|
|
7
|
+
Globs: `*` matches anything including `/`; `:name` matches one path segment (`/project/:slug`). Use the route parameter names from the code. Never put `?` or `#` in a glob.
|
|
8
|
+
|
|
9
|
+
Targets match the element's own text, field name or class — case does not matter, and the words only need to be contained. Prefer the words the visitor saw. Use `class:name` for buttons without text and `tag:BUTTON` only when the text differs every time (a list of names).
|
|
10
|
+
|
|
11
|
+
Steps happen in order, with anything allowed in between. All steps must happen; there is no "or" — two situations are two questions.
|
|
12
|
+
|
|
13
|
+
**It cannot see:** what is on the screen (an error message, an empty list, a price), the values typed (only length and whether it was cleared), time limits ("within 10 seconds"), who the visitor is (device, new or returning, campaign), or anything across visits. A visit is one tab; 30 minutes of nothing starts a new one. If the user asks for one of these, say so and offer the nearest thing it can do — usually a behavior that goes with it (a submit followed by no arrival at the next page, instead of "an error was shown").
|
|
14
|
+
|
|
15
|
+
Rules that make a card actually appear and mean something:
|
|
16
|
+
- The card must be shown on the screen where the trouble is. A click that opens another page ends the situation — use the `arrive` on the next page instead.
|
|
17
|
+
- Never ask while they are typing: the last step of an `on_match` condition must not be `input`. Use `idle` or the next step.
|
|
18
|
+
- Never ask the moment someone lands on a sign-in, sign-up or payment screen; use `idle` or `leave` there.
|
|
19
|
+
- The page must name a real screen, not only wildcards.
|
|
20
|
+
- Narrow enough to be one situation: a condition that matches a large share of all visits is too broad.
|
|
21
|
+
|
|
22
|
+
### Checking it
|
|
23
|
+
|
|
24
|
+
Call `question_check` with the condition. Read the result:
|
|
25
|
+
- **Problems**: fix them and check again. The server refuses the condition while there are any.
|
|
26
|
+
- **Does not match recent visits** (matched 0, a path or word not seen): usually a wrong path or word — compare with `question_context` and the code, and fix it. But the screen or button may be new or not live yet. Then tell the user it has not been seen in recent visits, and send it with `acceptWarnings: true` only if they say so.
|
|
27
|
+
- **Examples**: read what the matched visitors did. If it is not the situation the user meant, the condition is wrong even if it passes.
|
|
28
|
+
- **Overlaps**: an existing question fires at the same moment; only one card shows per visit. Tell the user.
|
|
29
|
+
- `idle` and `leave` moments are not counted by the check — it counts visits where the steps happened. Fewer people will actually see the card.
|
|
30
|
+
|
|
31
|
+
`triggerEn`: one plain sentence a product manager understands, saying when the card appears. No paths or class names.
|
package/agents/steps.md
CHANGED
|
@@ -31,7 +31,11 @@ Use their word for the card: a question when it is a question, an invite when it
|
|
|
31
31
|
Make sure the moment fits the card:
|
|
32
32
|
|
|
33
33
|
- **A question** appears when the visitor can answer it, right where the thing it asks about happened.
|
|
34
|
-
- **A research invite** asks for a few minutes of someone's time. It should reach the people the research is about — visitors who just went through the part of the site it covers — at a moment when they are free to say yes: after they finished
|
|
34
|
+
- **A research invite** asks for a few minutes of someone's time. It should reach the people the research is about — visitors who just went through the part of the site it covers — at a moment when they are free to say yes: right after they finished the action the research is about (`on_match` on that step), or as they are about to leave (`leave`). Do not wait for a long pause after the action; people keep scrolling and moving on, so such an invite rarely appears. Never in the middle of typing, paying or signing in.
|
|
35
|
+
|
|
36
|
+
When a research invite fires at the same moment as a live question, that is expected, not a conflict. A visitor sees only one card at a time and the question comes first; anyone who answers it is offered the research right after, in the same card, and the invite card reaches the visitors the question no longer reaches. Mention the overlap as information only. Never suggest turning a question off to make room for an invite.
|
|
37
|
+
|
|
38
|
+
When you list overlapping questions, quote each one exactly as the check returned it and say which moment it shares; do not refer to them by position.
|
|
35
39
|
|
|
36
40
|
## 4. Send it back
|
|
37
41
|
|
package/mcp/server.js
CHANGED
|
@@ -329,7 +329,7 @@ const QCondition = z.object({
|
|
|
329
329
|
page: z.string().describe("Path glob of the screen the visitor is on when the question appears"),
|
|
330
330
|
steps: z.array(QStep).describe("What happened, in order. Other actions may happen in between"),
|
|
331
331
|
moment: z.object({
|
|
332
|
-
type: z.enum(["on_match", "idle", "leave"]).describe("on_match = as soon as the steps are met · idle = after that, N seconds with no
|
|
332
|
+
type: z.enum(["on_match", "idle", "leave"]).describe("on_match = as soon as the steps are met · idle = after that, N seconds with no click, typing or page change (scrolling still counts as a pause) · leave = when about to leave"),
|
|
333
333
|
seconds: z.number().optional(),
|
|
334
334
|
}),
|
|
335
335
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usercase/mcp",
|
|
3
|
-
"version": "0.2.4-next.
|
|
3
|
+
"version": "0.2.4-next.3",
|
|
4
4
|
"description": "Virtual users that browse your website and tell you what they thought — an MCP server for Claude Code",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"homepage": "https://usercase.io",
|