standup-mr 0.7.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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,37 @@ All notable changes to standup-mr are recorded here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
5
5
  [semantic versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.0.0] - 2026-10-12
8
+
9
+ First stable release. From here on the CLI commands and flags, the JSON that
10
+ `fetch` and `get_standup_data` return, the MCP tool names and arguments, and
11
+ the environment variables follow semantic versioning: anything that would
12
+ break an existing setup waits for 2.0.
13
+
14
+ ### Added
15
+
16
+ - **Remote MCP server for claude.ai.** Add
17
+ `https://standup.ilkerbalcilar.com/mcp` as a custom connector, sign in with
18
+ GitHub or gitlab.com — or paste a token for a self-hosted host — and use
19
+ standup-mr from claude.ai on the web and on mobile, with no environment
20
+ variables. One connector can hold several accounts and an optional chat
21
+ webhook. The server lives in `remote/` and is not part of the npm package.
22
+ - **Sign in to your company's GitLab or GitHub Enterprise.** On the connect
23
+ page, type the host: if someone there already set up sign-in, use it;
24
+ otherwise register an OAuth application once, following the exact redirect
25
+ URI and scopes the page shows, and everyone at that host can sign in from
26
+ then on.
27
+ - `server.json` lists the remote endpoint, so registries show both the npm
28
+ package and the hosted server.
29
+ - Both servers declare the project icon in `serverInfo.icons`.
30
+
31
+ ### Fixed
32
+
33
+ - GitLab requests send the token as `Authorization: Bearer` instead of
34
+ `PRIVATE-TOKEN`. Personal access tokens work either way, but OAuth tokens —
35
+ from `glab`'s browser login or from the remote server's sign-in — were
36
+ rejected with 401.
37
+
7
38
  ## [0.7.0] - 2026-10-10
8
39
 
9
40
  ### Added
package/README.md CHANGED
@@ -66,12 +66,55 @@ So if you already use `gh` or `glab`, there is nothing to configure.
66
66
  npx standup-mr fetch --markdown | npx standup-mr post --slack "$SLACK_WEBHOOK_URL"
67
67
  ```
68
68
 
69
- ## The three surfaces
69
+ ## claude.ai (web and mobile)
70
+
71
+ No token, no config file — sign in instead. In claude.ai open **Settings →
72
+ Connectors → Add custom connector** and paste:
73
+
74
+ ```
75
+ https://standup.ilkerbalcilar.com/mcp
76
+ ```
77
+
78
+ Press **Connect**. A page opens where you link the accounts the note should
79
+ read:
80
+
81
+ - **GitHub** — sign in through the standup-mr GitHub App. It only sees the
82
+ repositories it is installed on, so install it on your org too; if the org
83
+ won't approve it, add github.com with a fine-grained token instead.
84
+ - **gitlab.com** — sign in with GitLab.
85
+ - **Your company's GitLab or GitHub Enterprise** — type the host. If someone
86
+ at your company already set up sign-in, you get a "Sign in with …" button.
87
+ Otherwise set it up once: the page shows the exact redirect URI and scopes
88
+ for an OAuth application on your host, you paste its ID and secret, and
89
+ everyone at that host can sign in from then on. A read-only token works too.
90
+ - **Chat webhook** _(optional)_ — Slack, Discord or Google Chat, so Claude can
91
+ post the finished note when you ask it to.
92
+
93
+ Link as many as you like — say, GitHub for side projects and your company's
94
+ GitLab for work — then ask for "my standup" or "my work standup". With
95
+ several accounts linked, Claude asks which one you mean.
96
+
97
+ The connector then works from the claude.ai mobile app as well.
98
+
99
+ **What is stored.** Your provider tokens and webhook URL, encrypted with
100
+ AES-256-GCM, and only to read your merge requests and post your note. The
101
+ access tokens Claude holds are stored as hashes. Disconnecting the connector
102
+ deletes everything; connections unused for 30 days are deleted. The server is
103
+ the code in [`remote/`](remote/).
104
+
105
+ **When to use the local server instead.** A GitLab behind a VPN or on a
106
+ private network is out of reach of a hosted server. Run the stdio server
107
+ below on your own machine — the token never leaves it.
108
+
109
+ ## The four surfaces
70
110
 
71
111
  **CLI** — the core. Emits JSON; zero runtime dependencies.
72
112
 
73
- **MCP server** (`mcp/`) — one tool, `get_standup_data`, for Claude Desktop,
74
- Cursor, or any MCP client. See [`mcp/README.md`](mcp/README.md).
113
+ **MCP server** (`mcp/`) — three tools for Claude Desktop, Claude Code, Cursor,
114
+ or any MCP client that runs a local process. See [`mcp/README.md`](mcp/README.md).
115
+
116
+ **Remote MCP server** (`remote/`) — the same tools over HTTPS with sign-in, for
117
+ claude.ai on the web and on mobile. See [above](#claudeai-web-and-mobile).
75
118
 
76
119
  **Claude Code plugin** — the note-writing playbook, shipped as the `standup`
77
120
  skill. From inside Claude Code:
@@ -205,6 +248,16 @@ that pipeline is red; this one opens the failed job's log and shows you the
205
248
  404 — and a 404 rather than a 403 usually means the token's scope is wrong, not
206
249
  that the package is missing.
207
250
 
251
+ ## Stability
252
+
253
+ Since 1.0.0 the CLI commands and flags, the JSON that `fetch` and
254
+ `get_standup_data` return, the MCP tool names and arguments, and the
255
+ environment variables follow [semantic versioning](https://semver.org/): a
256
+ change that would break an existing setup waits for a major release. New
257
+ fields in the JSON may appear in minor releases, so read it by name rather
258
+ than by position. The hosted server at `standup.ilkerbalcilar.com` is
259
+ updated continuously and is not tied to the npm version.
260
+
208
261
  ## Known limits
209
262
 
210
263
  - **GitHub's events feed is shallow.** It is capped at roughly 300 events over
@@ -810,7 +810,10 @@ var GitLabProvider = class {
810
810
  const response = await sendWithRetry(
811
811
  this.fetchImpl,
812
812
  url,
813
- { headers: { "PRIVATE-TOKEN": this.token } },
813
+ // Bearer, not PRIVATE-TOKEN: GitLab accepts personal access tokens
814
+ // either way, but OAuth tokens — glab's browser login, and the
815
+ // remote server's sign-in — only as a bearer.
816
+ { headers: { Authorization: `Bearer ${this.token}` } },
814
817
  this.host
815
818
  );
816
819
  assertUsable(response, this.host);
package/dist/cli.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  postWebhook,
9
9
  readStandupSkillBody,
10
10
  toMarkdown
11
- } from "./chunk-J5LAGA3U.js";
11
+ } from "./chunk-S7DAKN36.js";
12
12
 
13
13
  // src/cli/cli.ts
14
14
  import { realpathSync } from "fs";
package/dist/index.js CHANGED
@@ -45,7 +45,7 @@ import {
45
45
  toMarkdown,
46
46
  undiagnosed,
47
47
  unreachable
48
- } from "./chunk-J5LAGA3U.js";
48
+ } from "./chunk-S7DAKN36.js";
49
49
  export {
50
50
  ApiError,
51
51
  ConfigError,
@@ -842,7 +842,10 @@ var GitLabProvider = class {
842
842
  const response = await sendWithRetry(
843
843
  this.fetchImpl,
844
844
  url,
845
- { headers: { "PRIVATE-TOKEN": this.token } },
845
+ // Bearer, not PRIVATE-TOKEN: GitLab accepts personal access tokens
846
+ // either way, but OAuth tokens — glab's browser login, and the
847
+ // remote server's sign-in — only as a bearer.
848
+ { headers: { Authorization: `Bearer ${this.token}` } },
846
849
  this.host
847
850
  );
848
851
  assertUsable(response, this.host);
@@ -1277,22 +1280,48 @@ async function runPostTool(args, deps = {}) {
1277
1280
  async function runInstructionsTool() {
1278
1281
  return text(readStandupSkillBody());
1279
1282
  }
1283
+ var STANDUP_TOOL_ANNOTATIONS = {
1284
+ readOnlyHint: true,
1285
+ destructiveHint: false,
1286
+ idempotentHint: true,
1287
+ openWorldHint: true
1288
+ };
1289
+ var POST_TOOL_ANNOTATIONS = {
1290
+ readOnlyHint: false,
1291
+ destructiveHint: false,
1292
+ idempotentHint: false,
1293
+ openWorldHint: true
1294
+ };
1295
+ var INSTRUCTIONS_TOOL_ANNOTATIONS = {
1296
+ readOnlyHint: true,
1297
+ destructiveHint: false,
1298
+ idempotentHint: true,
1299
+ openWorldHint: false
1300
+ };
1301
+ var SERVER_ICONS = [
1302
+ {
1303
+ src: "https://raw.githubusercontent.com/Jubstaaa/standup-mr/main/assets/icon-512.png",
1304
+ mimeType: "image/png",
1305
+ sizes: ["512x512"]
1306
+ },
1307
+ {
1308
+ src: "https://raw.githubusercontent.com/Jubstaaa/standup-mr/main/assets/icon.svg",
1309
+ mimeType: "image/svg+xml",
1310
+ sizes: ["any"]
1311
+ }
1312
+ ];
1280
1313
  function createServer() {
1281
1314
  const server = new McpServer({
1282
1315
  name: "standup-mr",
1283
- version: packageVersion(import.meta.url)
1316
+ version: packageVersion(import.meta.url),
1317
+ icons: SERVER_ICONS
1284
1318
  });
1285
1319
  server.registerTool(
1286
1320
  "get_standup_data",
1287
1321
  {
1288
1322
  description: STANDUP_TOOL_DESCRIPTION,
1289
1323
  inputSchema: STANDUP_TOOL_SCHEMA,
1290
- annotations: {
1291
- readOnlyHint: true,
1292
- destructiveHint: false,
1293
- idempotentHint: true,
1294
- openWorldHint: true
1295
- }
1324
+ annotations: STANDUP_TOOL_ANNOTATIONS
1296
1325
  },
1297
1326
  async (args) => await runStandupTool(args)
1298
1327
  );
@@ -1301,12 +1330,7 @@ function createServer() {
1301
1330
  {
1302
1331
  description: POST_TOOL_DESCRIPTION,
1303
1332
  inputSchema: POST_TOOL_SCHEMA,
1304
- annotations: {
1305
- readOnlyHint: false,
1306
- destructiveHint: false,
1307
- idempotentHint: false,
1308
- openWorldHint: true
1309
- }
1333
+ annotations: POST_TOOL_ANNOTATIONS
1310
1334
  },
1311
1335
  async (args) => await runPostTool(args)
1312
1336
  );
@@ -1314,12 +1338,7 @@ function createServer() {
1314
1338
  "get_note_instructions",
1315
1339
  {
1316
1340
  description: INSTRUCTIONS_TOOL_DESCRIPTION,
1317
- annotations: {
1318
- readOnlyHint: true,
1319
- destructiveHint: false,
1320
- idempotentHint: true,
1321
- openWorldHint: false
1322
- }
1341
+ annotations: INSTRUCTIONS_TOOL_ANNOTATIONS
1323
1342
  },
1324
1343
  async () => await runInstructionsTool()
1325
1344
  );
@@ -1345,16 +1364,22 @@ if (entryUrl && import.meta.url === entryUrl) {
1345
1364
  });
1346
1365
  }
1347
1366
  export {
1367
+ INSTRUCTIONS_TOOL_ANNOTATIONS,
1348
1368
  INSTRUCTIONS_TOOL_DESCRIPTION,
1369
+ POST_TOOL_ANNOTATIONS,
1349
1370
  POST_TOOL_DESCRIPTION,
1350
1371
  POST_TOOL_SCHEMA,
1372
+ SERVER_ICONS,
1373
+ STANDUP_TOOL_ANNOTATIONS,
1351
1374
  STANDUP_TOOL_DESCRIPTION,
1352
1375
  STANDUP_TOOL_SCHEMA,
1353
1376
  WEBHOOK_URL_ENV,
1354
1377
  collect,
1355
1378
  createServer,
1379
+ failure,
1356
1380
  main,
1357
1381
  runInstructionsTool,
1358
1382
  runPostTool,
1359
- runStandupTool
1383
+ runStandupTool,
1384
+ text
1360
1385
  };
package/llms-install.md CHANGED
@@ -3,6 +3,11 @@
3
3
  Instructions for an AI assistant setting this MCP server up on a user's
4
4
  machine. Everything here is verified against the published package.
5
5
 
6
+ If the user is on claude.ai (web or mobile) rather than a client that runs
7
+ local processes, none of this applies: tell them to add
8
+ `https://standup.ilkerbalcilar.com/mcp` under Settings → Connectors → Add custom
9
+ connector and sign in on the page that opens.
10
+
6
11
  ## What it needs
7
12
 
8
13
  - Node.js 20 or newer. Nothing to clone, nothing to build — the server runs
package/mcp/README.md CHANGED
@@ -1,8 +1,13 @@
1
1
  # MCP server
2
2
 
3
- Exposes one tool, `get_standup_data`, for either GitLab or GitHub, returning
3
+ Exposes three tools — `get_standup_data`, `get_note_instructions` and
4
+ `post_standup_note` — for either GitLab or GitHub. `get_standup_data` returns
4
5
  the same JSON as `standup fetch`.
5
6
 
7
+ This is the local, stdio server: it runs on your machine and reads tokens from
8
+ its environment. On claude.ai (web or mobile), use the hosted connector instead
9
+ — see [claude.ai (web and mobile)](../README.md#claudeai-web-and-mobile).
10
+
6
11
  ## Configure
7
12
 
8
13
  GitLab:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "standup-mr",
3
- "version": "0.7.0",
3
+ "version": "1.0.0",
4
4
  "mcpName": "io.github.Jubstaaa/standup-mr",
5
5
  "description": "Standup notes from merge request state, not commit logs.",
6
6
  "keywords": [
@@ -53,6 +53,9 @@
53
53
  "CHANGELOG.md",
54
54
  "LICENSE"
55
55
  ],
56
+ "workspaces": [
57
+ "remote"
58
+ ],
56
59
  "scripts": {
57
60
  "build": "tsup",
58
61
  "lint": "eslint .",
@@ -64,8 +67,8 @@
64
67
  "prepublishOnly": "tsup"
65
68
  },
66
69
  "dependencies": {
67
- "@modelcontextprotocol/sdk": "^1.30.0",
68
- "zod": "^4.4.3"
70
+ "@modelcontextprotocol/sdk": "^1.32.1",
71
+ "zod": "^4.6.6"
69
72
  },
70
73
  "devDependencies": {
71
74
  "@eslint/js": "^9.39.1",