{
  "markdown": "# standup-mr\n\n[![standup-mr MCP server](https://glama.ai/mcp/servers/Jubstaaa/standup-mr/badges/score.svg)](https://glama.ai/mcp/servers/Jubstaaa/standup-mr)\n[![Listed on mcpservers.org](https://mcpservers.org/badge.svg)](https://mcpservers.org/servers/jubstaaa/standup-mr)\n\nStandup notes from **merge request state**, not commit logs.\n\nMost standup tools read your local `git log`. That answers \"what did I type\",\nwhich is not what anyone asks in a standup. This one reads GitLab or GitHub:\nwhat is ready to merge, what is blocked, what is waiting on you — and when a\npipeline is red, it opens the job log and tells you **why**.\n\n## What makes it different\n\n|                                               | commit-log tools | standup-mr                                            |\n| --------------------------------------------- | ---------------- | ----------------------------------------------------- |\n| Source                                        | local `git log`  | GitLab or GitHub API                                  |\n| Merge request state                           | ✗                | ready / blocked / draft / stale                       |\n| Review queue                                  | ✗                | pending only, approvals filtered out                  |\n| Failed pipeline                               | ✗                | error lines from the job trace or the Actions job log |\n| Self-hosted (GitLab CE/EE, GitHub Enterprise) | varies           | first class                                           |\n\n## Use\n\n```bash\nnpx standup-mr fetch                            # JSON, provider auto-detected\nnpx standup-mr fetch --provider github          # GitHub\nnpx standup-mr fetch --provider gitlab          # GitLab\nnpx standup-mr fetch --markdown                 # structured digest\nnpx standup-mr fetch --lang tr                  # Turkish date labels\n```\n\n```bash\nnpx standup-mr fetch --markdown | npx standup-mr post --google-chat \"$URL\"\n```\n\n### Identity\n\n|             | GitHub                                      | GitLab                                                  |\n| ----------- | ------------------------------------------- | ------------------------------------------------------- |\n| Flags       | `--host` / `--token`                        | `--host` / `--token`                                    |\n| Env         | `GITHUB_HOST` / `GITHUB_TOKEN`              | `GITLAB_HOST` / `GITLAB_TOKEN`                          |\n| CLI session | [`gh`](https://cli.github.com/) auth config | [`glab`](https://gitlab.com/gitlab-org/cli) auth config |\n\nGitHub defaults to `github.com` when no host is given. GitLab has no default —\nself-hosted is the norm there, so a host must come from a flag, env var, or\n`glab`'s own config.\n\nThe provider itself is picked in this order:\n\n1. `--provider github` / `--provider gitlab`, if passed\n2. a recognizable `--host` (`github.com`, `gitlab.com`, or a hostname\n   containing `github`/`gitlab`)\n3. `STANDUP_PROVIDER`, or whichever of the `GITHUB_*` / `GITLAB_*` env pairs\n   is set\n4. whichever of `gh` / `glab` is logged in\n\nIf none of these resolve — or both do, ambiguously — the command fails with a\nclear error instead of guessing.\n\nSo if you already use `gh` or `glab`, there is nothing to configure.\n\n### Post it to chat\n\n```bash\nnpx standup-mr fetch --markdown | npx standup-mr post --slack \"$SLACK_WEBHOOK_URL\"\n```\n\n## The three surfaces\n\n**CLI** — the core. Emits JSON; zero runtime dependencies.\n\n**MCP server** (`mcp/`) — one tool, `get_standup_data`, for Claude Desktop,\nCursor, or any MCP client. See [`mcp/README.md`](mcp/README.md).\n\n**Claude Code plugin** — the note-writing playbook, shipped as the `standup`\nskill. From inside Claude Code:\n\n```\n/plugin marketplace add Jubstaaa/standup-mr\n/plugin install standup@standup-mr\n```\n\nThen type `/standup`. Updates come with `/plugin marketplace update standup-mr`.\n\n### Using it from Cursor, Codex, or another assistant\n\nIf you're not using Claude Code, wire up the MCP server for live data and\npaste in the note-writing rules separately.\n\n**Cursor** — add to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json`\n(project-local):\n\n```json\n{\n    \"mcpServers\": {\n        \"standup\": {\n            \"command\": \"npx\",\n            \"args\": [\"-y\", \"standup-mr\", \"mcp\"],\n            \"env\": {\n                \"GITHUB_TOKEN\": \"ghp_...\"\n            }\n        }\n    }\n}\n```\n\n**Codex** — add to `~/.codex/config.toml`:\n\n```toml\n[mcp_servers.standup]\ncommand = \"npx\"\nargs = [\"-y\", \"standup-mr\", \"mcp\"]\n\n[mcp_servers.standup.env]\nGITHUB_TOKEN = \"ghp_...\"\n```\n\nThe exact config key and file path are version-dependent for both clients —\nif a snippet above doesn't work, check [Cursor's MCP\ndocs](https://docs.cursor.com/context/mcp) or Codex's own config\ndocumentation for the current format rather than trusting this file blindly.\n\nThe server exposes three tools:\n\n| Tool                    | What it does                                                                                 |\n| ----------------------- | -------------------------------------------------------------------------------------------- |\n| `get_standup_data`      | Reads the provider and returns the report as JSON. Optional `provider`, `host`, `lang`.      |\n| `get_note_instructions` | Returns the note-writing rules, so the assistant can write the note the way the skill would. |\n| `post_standup_note`     | Posts a finished note to a Slack, Discord or Google Chat webhook.                            |\n\n`post_standup_note` reads the webhook URL from `STANDUP_WEBHOOK_URL` and never\ntakes it as an argument — anyone holding that URL can post to the channel, so\nit belongs with the tokens, not in a transcript. The payload shape is inferred\nfrom the URL host; `kind` is only needed when a proxy hides it.\n\nThree shapes are implemented: `slack` and `google-chat` both post `{\"text\"}`,\n`discord` posts `{\"content\"}`.\n\nSlack and Google Chat do not render standard Markdown, so the note is rewritten\non the way out: `**bold**` becomes `*bold*` and a `##` heading becomes a bold\nline. Inline code, fenced blocks and their contents are left alone. Discord\nspeaks Markdown natively and is sent untouched. Anything else that accepts a Slack-shaped body —\nMattermost, Rocket.Chat, an n8n or Zapier endpoint — works today by passing\n`kind: \"slack\"`, or `--slack URL` on the CLI.\n\nOutside MCP, the same rules are available on stdout:\n\n```bash\nnpx standup-mr instructions >> AGENTS.md\n```\n\n## `--markdown` is a digest, not a written note\n\n`--markdown` organizes the raw material into readable sections. It does **not**\ngroup events into themes or diagnose blockers — that is the model's work, and it\nlives in the MCP client's prompt or in the Claude Code skill.\n\n- Without AI: a structured digest.\n- With AI: a note you can read out.\n\n## What the digest looks like\n\nAnonymised output from a real Monday run — note that Friday and Saturday each\nget their own section, and that a merge request GitLab has not evaluated is not\ncalled ready:\n\n```markdown\n# Monday, 31 August — dev\n\n_Structured digest — not a written note._\n\n## Previous working day: Friday, 28 August\n\n- `acme/ui` pushed to — fix(keyboard): scale keys to viewport (4 commits)\n- `acme/ui` accepted — chore(deps): bump @acme/ui to 0.5.18\n- `acme/api` opened — feat: package subscription sales\n\n## Previous working day: Saturday, 29 August\n\n- `acme/ui` pushed to — fix(keyboard): close the autofill bar (1 commit)\n\n## Ready to merge (2)\n\n- `acme/api` !196 fix: normalise the +90 trunk prefix\n- `acme/web` !194 refactor: loading state — **no pipeline ran**\n\n## Blocked (1)\n\n- `acme/terminal` !49 fix: relative date chips — **1 unresolved comment(s)**\n\n## Reviews (2 pending)\n\n- `acme/mobile` !501 chore: upgrade to RN 0.87 — Teammate\n\n## Blockers\n\n- `acme/mobile` !6 — job `quality`\n    - `npm ERR! code E404`\n    - `npm ERR! 404 Not Found - GET https://registry.example.com/@acme%2fui`\n```\n\nThe last section is the point of the tool. Every other standup tool can tell you\nthat pipeline is red; this one opens the failed job's log and shows you the\n404 — and a 404 rather than a 403 usually means the token's scope is wrong, not\nthat the package is missing.\n\n## Known limits\n\n- **GitHub's events feed is shallow.** It is capped at roughly 300 events over\n  the last 90 days, so a very active account or an old gap can silently lose\n  the earliest events. GitLab has no comparable documented cap.\n- **GitHub activity is only visible to a token belonging to that same\n  account**, and private-repository events do not show up for anyone else's\n  token, even with otherwise sufficient scopes.\n- **On GitHub, CI that reports only through the legacy commit-statuses API**\n  — still how some vendors integrate — shows up as `pipelineMissing`. Check\n  state is read from check-runs only.\n- **A blocker whose diagnosis could not be fetched is still reported**, as\n  `job: \"unknown\"` with a `diagnosis unavailable: …` error line. The merge\n  request is blocked either way; only the explanation is missing. Server\n  errors are retried twice first, and a rejected token still fails the run.\n\n## Upgrading from 0.1.x\n\n0.2.0 changes the JSON output, the library API, and the MCP options. If you\npipe `standup fetch` into anything, or import the package, read\n[`CHANGELOG.md`](CHANGELOG.md) before upgrading. The short version:\n\n- `previous` and `previousEvents` are replaced by `previousDays[]`, one entry\n  per active day, so a weekend no longer swallows Friday. `jq .previous` now\n  returns `null` with no error.\n- `MergeRequest`, `Review` and `Blocker` carry a required `provider` field, and\n  `Provider.getReviews` takes an `Identity` rather than a numeric id.\n- The MCP `CollectOptions.provider` is now a provider _name_; inject a\n  `Provider` instance through `providerImpl`.\n\nClaude Code plugin users should run `/plugin marketplace update standup-mr` —\nthe `standup` skill changed along with the report shape.\n\n## Requirements\n\nNode 20 or newer. The CLI core (`fetch`, `post`, `instructions`) pulls no\nruntime dependencies. The MCP server (`mcp` command) brings one:\n`@modelcontextprotocol/sdk`.\n\n## License\n\nMIT\n",
  "bytes": 10154,
  "sha": "5e78b4567cc56b805a7893d2ec599171fa4dbbff2c5c5e0ad4a806159e4dd47c",
  "repo_slug": "jubstaaa/standup-mr",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_jubstaaa_standup_mr_4db5a9ad/readme"
}