stackprep-pro 0.2.22__tar.gz → 0.2.25__tar.gz

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.
@@ -49,3 +49,5 @@ jobs:
49
49
  - name: Publish to PyPI
50
50
  if: steps.tag_check.outputs.EXISTS == 'false'
51
51
  uses: pypa/gh-action-pypi-publish@release/v1
52
+ with:
53
+ attestations: false
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stackprep-pro
3
- Version: 0.2.22
3
+ Version: 0.2.25
4
4
  Summary: stackprep-pro — interview & certification prep MCP server for any AI client
5
5
  Project-URL: Homepage, https://github.com/youngpada1/stackprep-pro
6
6
  Project-URL: Repository, https://github.com/youngpada1/stackprep-pro
@@ -52,11 +52,28 @@ uvx stackprep-pro
52
52
 
53
53
  ## Configure your MCP client
54
54
 
55
- The config is the same for every client — just point to `uvx stackprep-pro`.
55
+ The config is the same for every client — just point to `uvx stackprep-pro`. No API keys, no
56
+ authentication, no accounts — stackprep stores everything as plain files on your own machine.
57
+
58
+ > **Prerequisite:** install [uv](https://docs.astral.sh/uv/) (it provides `uvx`):
59
+ > ```bash
60
+ > curl -LsSf https://astral.sh/uv/install.sh | sh
61
+ > ```
56
62
 
57
63
  ### Claude Code
58
64
 
59
- Create `.mcp.json` in your project root:
65
+ **Recommended register it globally** so it works from any directory (the normal way you'd use it):
66
+
67
+ ```bash
68
+ claude mcp add stackprep --scope user -- uvx stackprep-pro
69
+ ```
70
+
71
+ Then launch Claude Code from anywhere with `claude` and type `start`.
72
+
73
+ <details>
74
+ <summary>Alternative: per-project config</summary>
75
+
76
+ If you'd rather scope it to a single project, create `.mcp.json` in that project's root instead:
60
77
 
61
78
  ```json
62
79
  {
@@ -68,10 +85,11 @@ Create `.mcp.json` in your project root:
68
85
  }
69
86
  }
70
87
  ```
88
+ </details>
71
89
 
72
90
  ### Cursor
73
91
 
74
- Create `~/.cursor/mcp.json`:
92
+ Create `~/.cursor/mcp.json` (global — works from any directory):
75
93
 
76
94
  ```json
77
95
  {
@@ -166,6 +184,7 @@ Point this at any Dropbox, Google Drive, or OneDrive folder for cross-platform s
166
184
  | `submit_answer` | Record the result of an answered question. | `session_id`, `result`, `question` |
167
185
  | `flag_for_study` | Manually flag the current question for the study pack. | `session_id`, `question` |
168
186
  | `save_session` | Save an in-progress session so the user can continue it later. | `session_id`, `session_name` |
187
+ | `exit_session` | ALWAYS call this the moment the user wants to leave a session in progress — any of: "exit", "quit", | `session_id` |
169
188
  | `discard_session` | Permanently delete a session. Call this when the user is exiting and answers NO to saving the | `session_id` |
170
189
  | `end_session` | End the session. Returns the score and flagged topics so the AI can generate a study plan and study pack. | `session_id` |
171
190
  | `save_study_pack` | Save the study pack content to disk. | `session_id`, `name`, `content` |
@@ -32,11 +32,28 @@ uvx stackprep-pro
32
32
 
33
33
  ## Configure your MCP client
34
34
 
35
- The config is the same for every client — just point to `uvx stackprep-pro`.
35
+ The config is the same for every client — just point to `uvx stackprep-pro`. No API keys, no
36
+ authentication, no accounts — stackprep stores everything as plain files on your own machine.
37
+
38
+ > **Prerequisite:** install [uv](https://docs.astral.sh/uv/) (it provides `uvx`):
39
+ > ```bash
40
+ > curl -LsSf https://astral.sh/uv/install.sh | sh
41
+ > ```
36
42
 
37
43
  ### Claude Code
38
44
 
39
- Create `.mcp.json` in your project root:
45
+ **Recommended register it globally** so it works from any directory (the normal way you'd use it):
46
+
47
+ ```bash
48
+ claude mcp add stackprep --scope user -- uvx stackprep-pro
49
+ ```
50
+
51
+ Then launch Claude Code from anywhere with `claude` and type `start`.
52
+
53
+ <details>
54
+ <summary>Alternative: per-project config</summary>
55
+
56
+ If you'd rather scope it to a single project, create `.mcp.json` in that project's root instead:
40
57
 
41
58
  ```json
42
59
  {
@@ -48,10 +65,11 @@ Create `.mcp.json` in your project root:
48
65
  }
49
66
  }
50
67
  ```
68
+ </details>
51
69
 
52
70
  ### Cursor
53
71
 
54
- Create `~/.cursor/mcp.json`:
72
+ Create `~/.cursor/mcp.json` (global — works from any directory):
55
73
 
56
74
  ```json
57
75
  {
@@ -146,6 +164,7 @@ Point this at any Dropbox, Google Drive, or OneDrive folder for cross-platform s
146
164
  | `submit_answer` | Record the result of an answered question. | `session_id`, `result`, `question` |
147
165
  | `flag_for_study` | Manually flag the current question for the study pack. | `session_id`, `question` |
148
166
  | `save_session` | Save an in-progress session so the user can continue it later. | `session_id`, `session_name` |
167
+ | `exit_session` | ALWAYS call this the moment the user wants to leave a session in progress — any of: "exit", "quit", | `session_id` |
149
168
  | `discard_session` | Permanently delete a session. Call this when the user is exiting and answers NO to saving the | `session_id` |
150
169
  | `end_session` | End the session. Returns the score and flagged topics so the AI can generate a study plan and study pack. | `session_id` |
151
170
  | `save_study_pack` | Save the study pack content to disk. | `session_id`, `name`, `content` |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "stackprep-pro"
3
- version = "0.2.22"
3
+ version = "0.2.25"
4
4
  description = "stackprep-pro — interview & certification prep MCP server for any AI client"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -98,11 +98,28 @@ uvx stackprep-pro
98
98
 
99
99
  ## Configure your MCP client
100
100
 
101
- The config is the same for every client — just point to `uvx stackprep-pro`.
101
+ The config is the same for every client — just point to `uvx stackprep-pro`. No API keys, no
102
+ authentication, no accounts — stackprep stores everything as plain files on your own machine.
103
+
104
+ > **Prerequisite:** install [uv](https://docs.astral.sh/uv/) (it provides `uvx`):
105
+ > ```bash
106
+ > curl -LsSf https://astral.sh/uv/install.sh | sh
107
+ > ```
102
108
 
103
109
  ### Claude Code
104
110
 
105
- Create `.mcp.json` in your project root:
111
+ **Recommended register it globally** so it works from any directory (the normal way you'd use it):
112
+
113
+ ```bash
114
+ claude mcp add stackprep --scope user -- uvx stackprep-pro
115
+ ```
116
+
117
+ Then launch Claude Code from anywhere with `claude` and type `start`.
118
+
119
+ <details>
120
+ <summary>Alternative: per-project config</summary>
121
+
122
+ If you'd rather scope it to a single project, create `.mcp.json` in that project's root instead:
106
123
 
107
124
  ```json
108
125
  {{
@@ -114,10 +131,11 @@ Create `.mcp.json` in your project root:
114
131
  }}
115
132
  }}
116
133
  ```
134
+ </details>
117
135
 
118
136
  ### Cursor
119
137
 
120
- Create `~/.cursor/mcp.json`:
138
+ Create `~/.cursor/mcp.json` (global — works from any directory):
121
139
 
122
140
  ```json
123
141
  {{
@@ -19,11 +19,17 @@ PRESENTATION (every message): always respond as elegant RENDERED markdown blocks
19
19
  dividers, clean tables/lists. NEVER output flat plain text.
20
20
 
21
21
  After the user picks a mode, silently call BOTH list_sessions(mode=<chosen mode>) and
22
- list_study_packs(mode=<chosen mode>). Then show ONE single "What would you like to do?" block — a single
23
- numbered table — listing, as rows: each saved session to continue (by its name), each saved study pack to
24
- open (by its name), and a final "Start a brand-new prep" row. Do NOT show separate "saved sessions" and
25
- "saved study packs" tables on top of the options table only the one combined options table. The user
26
- replies with a number. Collect inputs and call start_session.
22
+ list_study_packs(mode=<chosen mode>).
23
+
24
+ - If there are NO saved sessions AND NO saved study packs for that mode: do NOT ask anything about
25
+ continuing or opening go straight to collecting inputs and starting a brand-new session.
26
+ - Only if there IS at least one saved session or study pack: show ONE single "What would you like to do?"
27
+ block — a single numbered table listing each saved session to continue (by its name), each saved study
28
+ pack to open (by its name), and a final "Start a brand-new prep" row. Do NOT show separate "saved
29
+ sessions" / "saved study packs" tables on top of it — only the one combined options table.
30
+
31
+ Never show empty tables or "none found" messages to the user. The user replies with a number (when a table
32
+ is shown). Collect inputs and call start_session.
27
33
  Follow the skill rules returned by start_session exactly — the skill is the source of truth."""
28
34
 
29
35
  # Hardcoded so the very first block is guaranteed, not AI-guessed.
@@ -296,6 +302,33 @@ def save_session(session_id: str, session_name: str) -> str:
296
302
  return f"Session saved as '{name}'. You can continue it later."
297
303
 
298
304
 
305
+ @mcp.tool()
306
+ def exit_session(session_id: str) -> str:
307
+ """ALWAYS call this the moment the user wants to leave a session in progress — any of: "exit", "quit",
308
+ "stop", "leave", "X", "done for now", "bye", "that's enough". Do NOT end the conversation yourself on an
309
+ exit intent; call this first and relay its instructions. It returns the exact save prompt to show.
310
+
311
+ Args:
312
+ session_id: The session ID
313
+ """
314
+ session = _sessions.get(session_id) or _restore_session(session_id)
315
+ if not session:
316
+ return f"ERROR: No session found with ID '{session_id}'."
317
+
318
+ score = session.get("score", {})
319
+ return "\n".join([
320
+ "=== EXIT REQUESTED — you MUST ask this before ending ===",
321
+ f"Progress so far: {score.get('correct','?')}/{score.get('total','?')}.",
322
+ "",
323
+ 'Ask the user, exactly: "Do you want to save this session so you can continue later? (y/n)"',
324
+ " - If YES: ask \"What would you like to name this session?\" (the user MUST provide the name — never",
325
+ " auto-generate). Then call save_session(session_id='{}', session_name=<name>). It stays resumable.".format(session_id),
326
+ " - If NO: call discard_session(session_id='{}'). It is permanently deleted and won't appear later.".format(session_id),
327
+ "",
328
+ "Do NOT skip this question. Do NOT end the conversation until the user has answered y or n.",
329
+ ])
330
+
331
+
299
332
  @mcp.tool()
300
333
  def discard_session(session_id: str) -> str:
301
334
  """Permanently delete a session. Call this when the user is exiting and answers NO to saving the
@@ -10,7 +10,8 @@ Adaptive certification exam prep — one question at a time, with instant feedba
10
10
  ## ⛔ EXIT RULE (READ FIRST — NEVER SKIP)
11
11
 
12
12
  The instant the user says ANYTHING meaning they want to stop — "exit", "quit", "stop", "leave", "X",
13
- "done for now", "bye", "that's enough" — you MUST NOT just end the conversation. You MUST first ask:
13
+ "done for now", "bye", "that's enough" — you MUST NOT just end the conversation. You MUST FIRST call the
14
+ `exit_session(session_id)` tool and follow the instructions it returns. Those instructions are:
14
15
 
15
16
  > "Do you want to save this session so you can continue later? (y/n)"
16
17
 
@@ -18,7 +19,7 @@ The instant the user says ANYTHING meaning they want to stop — "exit", "quit",
18
19
  then call `save_session(session_id, session_name=<that name>)`. It stays resumable under that name.
19
20
  - **No** → call `discard_session(session_id)` to permanently delete it, then end. It will NOT appear later.
20
21
 
21
- This is mandatory EVERY time, no matter how few questions were answered.
22
+ This is mandatory EVERY time, no matter how few questions were answered. Never skip calling `exit_session`.
22
23
 
23
24
  ## Session setup
24
25
 
@@ -10,7 +10,8 @@ Adaptive technical interview prep — one question at a time, with instant feedb
10
10
  ## ⛔ EXIT RULE (READ FIRST — NEVER SKIP)
11
11
 
12
12
  The instant the user says ANYTHING meaning they want to stop — "exit", "quit", "stop", "leave", "X",
13
- "done for now", "bye", "that's enough" — you MUST NOT just end the conversation. You MUST first ask:
13
+ "done for now", "bye", "that's enough" — you MUST NOT just end the conversation. You MUST FIRST call the
14
+ `exit_session(session_id)` tool and follow the instructions it returns. Those instructions are:
14
15
 
15
16
  > "Do you want to save this session so you can continue later? (y/n)"
16
17
 
@@ -18,7 +19,7 @@ The instant the user says ANYTHING meaning they want to stop — "exit", "quit",
18
19
  then call `save_session(session_id, session_name=<that name>)`. It stays resumable under that name.
19
20
  - **No** → call `discard_session(session_id)` to permanently delete it, then end. It will NOT appear later.
20
21
 
21
- This is mandatory EVERY time, no matter how few questions were answered.
22
+ This is mandatory EVERY time, no matter how few questions were answered. Never skip calling `exit_session`.
22
23
 
23
24
  ## Session setup
24
25
 
@@ -723,7 +723,7 @@ wheels = [
723
723
 
724
724
  [[package]]
725
725
  name = "stackprep-pro"
726
- version = "0.2.22"
726
+ version = "0.2.25"
727
727
  source = { editable = "." }
728
728
  dependencies = [
729
729
  { name = "mcp", extra = ["cli"] },
File without changes
File without changes