hevy-coach 0.2.0 → 1.0.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +42 -146
  3. package/dist/cli.mjs +16 -0
  4. package/dist/http.mjs +133 -0
  5. package/dist/index.d.mts +6 -0
  6. package/dist/index.mjs +2 -0
  7. package/dist/src-BxQx3e_u.mjs +651 -0
  8. package/package.json +32 -33
  9. package/CHATGPT.md +0 -388
  10. package/GEMINI.md +0 -416
  11. package/dist/cli.d.ts +0 -3
  12. package/dist/cli.d.ts.map +0 -1
  13. package/dist/cli.js +0 -16
  14. package/dist/cli.js.map +0 -1
  15. package/dist/http.d.ts +0 -3
  16. package/dist/http.d.ts.map +0 -1
  17. package/dist/http.js +0 -174
  18. package/dist/http.js.map +0 -1
  19. package/dist/index.d.ts +0 -3
  20. package/dist/index.d.ts.map +0 -1
  21. package/dist/index.js +0 -23
  22. package/dist/index.js.map +0 -1
  23. package/dist/tools/body-measurements.d.ts +0 -4
  24. package/dist/tools/body-measurements.d.ts.map +0 -1
  25. package/dist/tools/body-measurements.js +0 -88
  26. package/dist/tools/body-measurements.js.map +0 -1
  27. package/dist/tools/coaching.d.ts +0 -4
  28. package/dist/tools/coaching.d.ts.map +0 -1
  29. package/dist/tools/coaching.js +0 -353
  30. package/dist/tools/coaching.js.map +0 -1
  31. package/dist/tools/exercises.d.ts +0 -4
  32. package/dist/tools/exercises.d.ts.map +0 -1
  33. package/dist/tools/exercises.js +0 -121
  34. package/dist/tools/exercises.js.map +0 -1
  35. package/dist/tools/routines.d.ts +0 -4
  36. package/dist/tools/routines.d.ts.map +0 -1
  37. package/dist/tools/routines.js +0 -150
  38. package/dist/tools/routines.js.map +0 -1
  39. package/dist/tools/users.d.ts +0 -4
  40. package/dist/tools/users.d.ts.map +0 -1
  41. package/dist/tools/users.js +0 -16
  42. package/dist/tools/users.js.map +0 -1
  43. package/dist/tools/workouts.d.ts +0 -4
  44. package/dist/tools/workouts.d.ts.map +0 -1
  45. package/dist/tools/workouts.js +0 -134
  46. package/dist/tools/workouts.js.map +0 -1
  47. package/dist/utils/hevy-client.d.ts +0 -212
  48. package/dist/utils/hevy-client.d.ts.map +0 -1
  49. package/dist/utils/hevy-client.js +0 -178
  50. package/dist/utils/hevy-client.js.map +0 -1
  51. package/dist/utils/response.d.ts +0 -21
  52. package/dist/utils/response.d.ts.map +0 -1
  53. package/dist/utils/response.js +0 -22
  54. package/dist/utils/response.js.map +0 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,35 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0 (unreleased)
4
+
5
+ ### Breaking
6
+
7
+ - Node 22.18+ required.
8
+ - `hevy-coach-http` requires `MCP_AUTH_TOKEN`, binds to `127.0.0.1` by default, and needs `MCP_ALLOWED_HOSTS` to bind elsewhere. CORS is off unless `MCP_ALLOWED_ORIGINS` lists browser origins.
9
+ - `create-body-measurement` and `update-body-measurement` replaced by `log-body-measurement` (create or overwrite).
10
+ - `create-routine` and `update-routine` take `folder_id` (snake_case). `update-routine` moves a routine when `folder_id` is given (null = "My Routines") and keeps the folder when it is omitted. `rpe` is no longer accepted on routine sets (Hevy rejects it).
11
+ - Error results include Hevy's HTTP status, error code and message instead of a generic axios message.
12
+
13
+ ### Fixed
14
+
15
+ - `get-exercise-progression` threw on live data: exercise history is flat (one row per set), not nested.
16
+ - `get-workout` and `analyze-workout` returned "not found" for valid workouts because the response was assumed to be wrapped.
17
+ - `batch-find-exercises` and `find-exercise` prefer an exact title match and rank partial matches by shortest title, so "Squat" no longer resolves to an arbitrary variant.
18
+ - RPE inputs validated against Hevy's allowed values.
19
+ - `get-exercise-progression` trends bodyweight exercises on max reps (was always "plateau") and reports a true all-time best; `progressionKg` is now `progression` with a `trendMetric` field.
20
+ - `analyze-workout` judges "reps hit" on the weakest working set, not the mean; `get-training-summary` counts sessions per workout, not per exercise entry.
21
+ - `find-exercise` matches muscle groups written with spaces ("upper back").
22
+ - `create-exercise-template` invalidates the exercise cache so the new exercise is immediately findable.
23
+
24
+ ### Changed
25
+
26
+ - Built on `@furkantanyol/hevy-client`; axios removed.
27
+ - Coaching prompts moved to `prompts/` (`COACH.md`, `CHATGPT.md`, `GEMINI.md`).
28
+
29
+ ## 0.2.0 (2026-05-31)
30
+
31
+ - Body measurement tools. Fixed exercise-history path, custom exercise body fields, routine folder handling.
32
+
33
+ ## 0.1.x
34
+
35
+ - Initial MCP server with workout, routine, exercise and coaching tools.
package/README.md CHANGED
@@ -1,30 +1,12 @@
1
- # HevyCoach
1
+ # hevy-coach
2
2
 
3
- AI personal training system that connects to [Hevy](https://hevyapp.com) via MCP (Model Context Protocol). Not just another API wrapper HevyCoach adds coaching intelligence on top of workout data.
3
+ MCP server that turns an AI assistant into a strength coach with access to your [Hevy](https://hevyapp.com) account. Every read endpoint, routine and workout writes, and coaching tools built on top: workout-vs-plan analysis, exercise progression with estimated 1RM, training summaries, exercise name resolution.
4
4
 
5
- **What makes this different from existing Hevy MCP servers:** Other servers give you CRUD operations. HevyCoach adds the brain — workout analysis, progression tracking with Epley 1RM estimation, training summaries, and exercise search. Combined with the CLAUDE.md coaching prompt, it turns Claude into a full athletic coach covering strength, hypertrophy, VO2max, mobility, flexibility, and longevity.
5
+ Requires Node 22.18+ and a Hevy API key (Hevy Settings API).
6
6
 
7
- ## What You Get
7
+ ## Install
8
8
 
9
- - **Complete athletic programming** strength, hypertrophy, VO2max, mobility, flexibility, stamina, longevity
10
- - **Coaching intelligence** — workout analysis, progression tracking, automatic adaptation recommendations
11
- - **Auto-pushed to Hevy** — routines appear in your app, ready to log
12
- - **Daily briefings** — morning message with today's workout + conditioning + mobility
13
- - **Adaptive coaching** — reads your completed workouts and adjusts programming
14
- - **Weekly reviews** — volume tracking, PR highlights, conditioning adherence, program adjustments
15
-
16
- ## Setup
17
-
18
- ### Prerequisites
19
-
20
- - [Hevy Pro](https://hevyapp.com) subscription (required for API access)
21
- - API key from Hevy Settings → API
22
- - Node.js 18+
23
- - [Claude Desktop](https://claude.ai/download) (or any MCP-compatible client)
24
-
25
- ### Quick Start (npx)
26
-
27
- Add to your Claude Desktop MCP config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
9
+ **Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
28
10
 
29
11
  ```json
30
12
  {
@@ -32,145 +14,59 @@ Add to your Claude Desktop MCP config (`~/Library/Application Support/Claude/cla
32
14
  "hevy-coach": {
33
15
  "command": "npx",
34
16
  "args": ["-y", "hevy-coach"],
35
- "env": {
36
- "HEVY_API_KEY": "your-hevy-api-key"
37
- }
17
+ "env": { "HEVY_API_KEY": "your-hevy-api-key" }
38
18
  }
39
19
  }
40
20
  }
41
21
  ```
42
22
 
43
- Restart Claude Desktop. The tools appear in the MCP tools list.
44
-
45
- ### Install from Source
23
+ **Claude Code:**
46
24
 
47
25
  ```bash
48
- git clone https://github.com/furkantanyol/hevy-coach.git
49
- cd hevy-coach
50
- npm install
51
- npm run build
52
- ```
53
-
54
- Then use the local path in your MCP config:
55
-
56
- ```json
57
- {
58
- "mcpServers": {
59
- "hevy-coach": {
60
- "command": "node",
61
- "args": ["/absolute/path/to/hevy-coach/dist/cli.js"],
62
- "env": {
63
- "HEVY_API_KEY": "your-hevy-api-key"
64
- }
65
- }
66
- }
67
- }
26
+ claude mcp add hevy-coach -e HEVY_API_KEY=your-hevy-api-key -- npx -y hevy-coach
68
27
  ```
69
28
 
70
- ### Add the Coaching Brain
71
-
72
- Create a Claude Project called **"HevyCoach"**:
73
-
74
- 1. Open Claude Desktop → Projects → New Project
75
- 2. Name it "HevyCoach"
76
- 3. In Project Instructions, paste the contents of `CLAUDE.md`
77
- 4. Add `training-history.md` as a project file
78
-
79
- ### Start Training
80
-
81
- Open the HevyCoach project and say:
82
-
83
- > "I want to start training with you. Let's do the onboarding."
84
-
85
- Claude will ask about your body, training history, goals, and preferences. Then it generates your full program (strength + conditioning + mobility) and pushes routines to Hevy.
86
-
87
- ### Daily Automation (Optional)
88
-
89
- Create two Claude Desktop scheduled tasks:
90
-
91
- **Morning briefing (7 AM):**
92
- > Read my HevyCoach program. Tell me today's workout with warmup, exercises, sets/reps/weights, conditioning if scheduled, and daily mobility drills.
93
-
94
- **Evening sync (11:59 PM):**
95
- > Fetch my latest Hevy workout. Analyze it against today's plan. Summarize performance, note progressions or missed targets, and adjust upcoming sessions if needed.
29
+ Then add the coaching persona from the repository's `prompts/COACH.md` to your project instructions and say "let's do the onboarding".
96
30
 
97
31
  ## Tools
98
32
 
99
- ### User Tools
100
- | Tool | Description |
101
- |------|-------------|
102
- | `get-user-info` | Get authenticated user's profile (ID, name, Hevy URL) |
103
-
104
- ### Workout Tools
105
- | Tool | Description |
106
- |------|-------------|
107
- | `get-workouts` | List recent workouts (paginated) |
108
- | `get-workout` | Get specific workout by ID |
109
- | `create-workout` | Create a new workout with exercises and sets |
110
- | `update-workout` | Update an existing workout by ID |
111
- | `get-workout-count` | Total logged workouts |
112
- | `get-workout-events` | Track changes since a date |
113
-
114
- ### Routine Tools
115
- | Tool | Description |
116
- |------|-------------|
117
- | `get-routines` | List saved routines |
118
- | `get-routine` | Get routine details |
119
- | `create-routine` | Push routine to Hevy |
120
- | `update-routine` | Modify existing routine |
121
- | `get-routine-folder` | Get a single routine folder by ID |
122
- | `get-routine-folders` | List routine folders |
123
- | `create-routine-folder` | Create folder |
124
-
125
- ### Exercise Tools
126
- | Tool | Description |
127
- |------|-------------|
128
- | `get-exercise-templates` | Browse exercise library |
129
- | `get-exercise-template` | Get exercise details |
130
- | `get-exercise-history` | Past performance data |
131
- | `create-exercise-template` | Create custom exercise |
132
-
133
- ### Coaching Tools
134
- | Tool | Description |
135
- |------|-------------|
136
- | `analyze-workout` | Compare completed vs planned workout. Returns per-exercise analysis with progression recommendations. |
137
- | `get-training-summary` | Aggregate last N workouts: volume, frequency, consistency, duration trends. |
138
- | `get-exercise-progression` | Track exercise over time: weight/rep trends, estimated 1RM (Epley), plateau detection. |
139
- | `find-exercise` | Search exercises by name or muscle group. Returns compact id + title pairs. |
140
- | `batch-find-exercises` | Look up multiple exercises at once. Loads library once, returns map of query → match. Use this when creating routines. |
141
-
142
- ## Architecture
143
-
144
- ```
145
- hevy-coach/
146
- ├── src/
147
- │ ├── index.ts # Server factory
148
- │ ├── cli.ts # CLI entry point (stdio transport)
149
- │ ├── tools/
150
- │ │ ├── users.ts # User profile
151
- │ │ ├── workouts.ts # Workout CRUD
152
- │ │ ├── routines.ts # Routine CRUD
153
- │ │ ├── exercises.ts # Exercise templates
154
- │ │ └── coaching.ts # Coaching intelligence (the differentiator)
155
- │ └── utils/
156
- │ ├── hevy-client.ts # Hevy API client
157
- │ └── response.ts # MCP response helpers
158
- ├── CLAUDE.md # Coaching brain + user profile + program
159
- ├── training-history.md # Long-term tracking template
160
- └── package.json
161
- ```
162
-
163
- ## Development
33
+ | Tool | Purpose |
34
+ |---|---|
35
+ | `get-user-info` | Profile |
36
+ | `get-workouts`, `get-workout`, `get-workout-count`, `get-workout-events` | Logged workouts and change feed |
37
+ | `create-workout`, `update-workout` | Log or replace a workout |
38
+ | `get-routines`, `get-routine`, `create-routine`, `update-routine` | Routines (templates) |
39
+ | `get-routine-folders`, `get-routine-folder`, `create-routine-folder` | Folders |
40
+ | `get-exercise-templates`, `get-exercise-template`, `create-exercise-template` | Exercise library |
41
+ | `get-exercise-history` | Every set of one exercise |
42
+ | `get-body-measurements`, `get-body-measurement`, `log-body-measurement` | Body measurements |
43
+ | `analyze-workout` | Completed workout vs plan per-exercise recommendation |
44
+ | `get-training-summary` | Volume, frequency, duration over the last N workouts |
45
+ | `get-exercise-progression` | Session-by-session weight, reps, Epley 1RM, trend |
46
+ | `find-exercise`, `batch-find-exercises` | Resolve names to template ids |
47
+
48
+ Errors come back with Hevy's HTTP status, error code and message so the assistant can react (e.g. `routine-limit-exceeded` on free accounts).
49
+
50
+ ## HTTP transport
51
+
52
+ For assistants that connect over HTTP (ChatGPT, Gemini), run `hevy-coach-http`. It proxies your Hevy account, so it is locked down by default:
53
+
54
+ | Variable | Required | Meaning |
55
+ |---|---|---|
56
+ | `HEVY_API_KEY` | yes | Hevy API key |
57
+ | `MCP_AUTH_TOKEN` | yes | Bearer token clients must send. Use a long random secret. |
58
+ | `PORT` | no | Default 3000 |
59
+ | `HOST` | no | Default `127.0.0.1`. Anything else requires `MCP_ALLOWED_HOSTS`. |
60
+ | `MCP_ALLOWED_HOSTS` | when exposed | Comma-separated hostnames accepted in `Host` (DNS-rebinding protection) |
61
+ | `MCP_ALLOWED_ORIGINS` | no | Comma-separated browser origins allowed by CORS. Off otherwise. |
164
62
 
165
63
  ```bash
166
- npm run build # Compile TypeScript
167
- npm run dev # Watch mode
64
+ HEVY_API_KEY=... MCP_AUTH_TOKEN=$(openssl rand -hex 32) npx -p hevy-coach hevy-coach-http
65
+ # MCP endpoint: http://127.0.0.1:3000/mcp Health: /health
168
66
  ```
169
67
 
170
- ## Credits
171
-
172
- Inspired by [chrisdoc/hevy-mcp](https://github.com/chrisdoc/hevy-mcp) and [tomtorggler/hevy-mcp-server](https://github.com/tomtorggler/hevy-mcp-server). Built from scratch with coaching intelligence as the core focus.
68
+ Put it behind HTTPS (a tunnel or reverse proxy) before pointing a hosted assistant at it.
173
69
 
174
70
  ## License
175
71
 
176
- MIT — Furkan Tanyol
72
+ MIT
package/dist/cli.mjs ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { n as createServer } from "./src-BxQx3e_u.mjs";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ //#region src/cli.ts
5
+ const apiKey = process.env.HEVY_API_KEY;
6
+ if (!apiKey) {
7
+ console.error("HEVY_API_KEY environment variable is required.");
8
+ console.error("Get your API key from Hevy Settings → API.");
9
+ process.exit(1);
10
+ }
11
+ createServer({ apiKey }).connect(new StdioServerTransport()).catch((error) => {
12
+ console.error("Failed to start hevy-coach:", error);
13
+ process.exit(1);
14
+ });
15
+ //#endregion
16
+ export {};
package/dist/http.mjs ADDED
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env node
2
+ import { n as createServer } from "./src-BxQx3e_u.mjs";
3
+ import { randomUUID, timingSafeEqual } from "node:crypto";
4
+ import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
5
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
6
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
7
+ //#region src/utils/auth.ts
8
+ /** Constant-time bearer check. An empty or missing header never matches. */
9
+ function isAuthorized(authorizationHeader, token) {
10
+ const presented = Buffer.from((authorizationHeader ?? "").replace(/^Bearer\s+/i, ""));
11
+ const expected = Buffer.from(token);
12
+ if (presented.length === 0 || presented.length !== expected.length) return false;
13
+ return timingSafeEqual(presented, expected);
14
+ }
15
+ //#endregion
16
+ //#region src/http.ts
17
+ const log = (message) => console.error(`[hevy-coach] ${message}`);
18
+ const fail = (message) => {
19
+ log(message);
20
+ process.exit(1);
21
+ };
22
+ const DEFAULT_PORT = 3e3;
23
+ const LOCALHOST = "127.0.0.1";
24
+ const LOCALHOST_ALIASES = /* @__PURE__ */ new Set([
25
+ LOCALHOST,
26
+ "localhost",
27
+ "::1"
28
+ ]);
29
+ const csv = (value) => (value ?? "").split(",").map((s) => s.trim()).filter(Boolean);
30
+ const apiKey = process.env.HEVY_API_KEY || fail("HEVY_API_KEY environment variable is required.");
31
+ const authToken = process.env.MCP_AUTH_TOKEN || fail("MCP_AUTH_TOKEN is required: this server proxies your Hevy account. Generate a long random secret.");
32
+ if (authToken.length < 32) fail(`MCP_AUTH_TOKEN must be at least 32 characters, e.g. openssl rand -hex 32.`);
33
+ const port = Number(process.env.PORT ?? DEFAULT_PORT);
34
+ if (!Number.isInteger(port) || port <= 0) fail(`PORT must be a positive integer, got "${process.env.PORT}".`);
35
+ const host = process.env.HOST ?? LOCALHOST;
36
+ const allowedHosts = csv(process.env.MCP_ALLOWED_HOSTS);
37
+ const allowedOrigins = csv(process.env.MCP_ALLOWED_ORIGINS);
38
+ const isLocal = LOCALHOST_ALIASES.has(host);
39
+ if (!isLocal && allowedHosts.length === 0) fail(`HOST=${host} exposes the server beyond localhost; set MCP_ALLOWED_HOSTS to your public hostname(s).`);
40
+ const app = createMcpExpressApp(isLocal ? { host } : {
41
+ host,
42
+ allowedHosts
43
+ });
44
+ app.use((req, res, next) => {
45
+ const origin = req.headers.origin;
46
+ if (origin && allowedOrigins.includes(origin)) {
47
+ res.setHeader("Access-Control-Allow-Origin", origin);
48
+ res.setHeader("Vary", "Origin");
49
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, mcp-session-id");
50
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
51
+ res.setHeader("Access-Control-Expose-Headers", "mcp-session-id");
52
+ }
53
+ if (req.method === "OPTIONS") {
54
+ res.sendStatus(204);
55
+ return;
56
+ }
57
+ next();
58
+ });
59
+ function bearerAuth(req, res, next) {
60
+ if (isAuthorized(req.headers.authorization, authToken)) {
61
+ next();
62
+ return;
63
+ }
64
+ res.status(401).json({ error: "Unauthorized" });
65
+ }
66
+ const transports = /* @__PURE__ */ new Map();
67
+ const jsonRpcError = (res, status, message) => res.status(status).json({
68
+ jsonrpc: "2.0",
69
+ error: {
70
+ code: -32e3,
71
+ message
72
+ },
73
+ id: null
74
+ });
75
+ function existingTransport(req, res) {
76
+ const sessionId = req.headers["mcp-session-id"];
77
+ const transport = typeof sessionId === "string" ? transports.get(sessionId) : void 0;
78
+ if (!transport) jsonRpcError(res, 400, "Missing or unknown mcp-session-id");
79
+ return transport;
80
+ }
81
+ async function startSession(req, res) {
82
+ const transport = new StreamableHTTPServerTransport({
83
+ sessionIdGenerator: () => randomUUID(),
84
+ onsessioninitialized: (sid) => {
85
+ transports.set(sid, transport);
86
+ log(`session started ${sid}`);
87
+ }
88
+ });
89
+ transport.onclose = () => {
90
+ if (transport.sessionId) {
91
+ transports.delete(transport.sessionId);
92
+ log(`session closed ${transport.sessionId}`);
93
+ }
94
+ };
95
+ await createServer({ apiKey }).connect(transport);
96
+ await transport.handleRequest(req, res, req.body);
97
+ }
98
+ app.get("/health", (_req, res) => {
99
+ res.json({
100
+ status: "ok",
101
+ server: "hevy-coach"
102
+ });
103
+ });
104
+ app.post("/mcp", bearerAuth, async (req, res) => {
105
+ try {
106
+ if (req.headers["mcp-session-id"]) await existingTransport(req, res)?.handleRequest(req, res, req.body);
107
+ else if (isInitializeRequest(req.body)) await startSession(req, res);
108
+ else jsonRpcError(res, 400, "Bad Request: missing session ID or not an initialize request");
109
+ } catch (error) {
110
+ log(`POST /mcp failed: ${String(error)}`);
111
+ if (!res.headersSent) jsonRpcError(res, 500, "Internal server error");
112
+ }
113
+ });
114
+ for (const method of ["get", "delete"]) app[method]("/mcp", bearerAuth, async (req, res) => {
115
+ const transport = existingTransport(req, res);
116
+ if (!transport) return;
117
+ try {
118
+ await transport.handleRequest(req, res);
119
+ } catch (error) {
120
+ log(`${method.toUpperCase()} /mcp failed: ${String(error)}`);
121
+ if (!res.headersSent) res.status(500).send("Internal server error");
122
+ }
123
+ });
124
+ app.listen(port, host, () => {
125
+ log(`listening on http://${host}:${port}/mcp (bearer auth on)`);
126
+ }).on("error", (error) => fail(`could not listen on ${host}:${port}: ${error.message}`));
127
+ for (const signal of ["SIGINT", "SIGTERM"]) process.on(signal, async () => {
128
+ log("shutting down");
129
+ await Promise.all([...transports.values()].map((t) => t.close().catch(() => void 0)));
130
+ process.exit(0);
131
+ });
132
+ //#endregion
133
+ export {};
@@ -0,0 +1,6 @@
1
+ import { HevyClientOptions } from "@furkantanyol/hevy-client";
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ //#region src/index.d.ts
4
+ export declare const SERVER_VERSION = "1.0.0";
5
+ export declare function createServer(options: HevyClientOptions): McpServer;
6
+ //#endregion
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { n as createServer, t as SERVER_VERSION } from "./src-BxQx3e_u.mjs";
2
+ export { SERVER_VERSION, createServer };