{"_id":"@assertthat/at-tm-mcp-server","_rev":"5-134c894eab1976618be98d667a7f03d2","name":"@assertthat/at-tm-mcp-server","dist-tags":{"latest":"0.1.4"},"versions":{"0.1.0":{"name":"@assertthat/at-tm-mcp-server","version":"0.1.0","license":"MIT","_id":"@assertthat/at-tm-mcp-server@0.1.0","maintainers":[{"name":"glib-briia","email":"glib.assertthat@gmail.com"}],"bin":{"at-tm-mcp":"dist/cli.js","at-tm-mcp-server":"dist/server.js"},"dist":{"shasum":"840b00943e95fde564ee9e97854bbfa1f1e72021","tarball":"https://registry.npmjs.org/@assertthat/at-tm-mcp-server/-/at-tm-mcp-server-0.1.0.tgz","fileCount":10,"integrity":"sha512-jisr9gf9kT8otm7VdO9Ro7Klb+F/+HB3r4+86Tnjgb5B/AIdU+MGq3HjzKr2wx4lBa7akNerzoqz89dPxp8qdQ==","signatures":[{"sig":"MEUCICO7nvske24WM+eK+un/st4SjaXx6poHeBT/Nig/BzZWAiEA08F0TROA3ih5aTWWsq1UzSDuyIj27XaWaTLTbaR7dSQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49312},"type":"module","engines":{"node":">=18.17"},"gitHead":"5b77d779fe286ea00c2bba6b126b45d41a187d67","scripts":{"dev":"tsc -p tsconfig.json --watch","build":"tsc -p tsconfig.json","login":"npm run build && node dist/cli.js login","start":"node dist/server.js"},"_npmUser":{"name":"glib-briia","email":"glib.assertthat@gmail.com"},"_npmVersion":"11.6.1","description":"MCP server for the AssertThat AI Test Manager (AT AI TM) Forge app, authenticated with the caller's own Atlassian account.","directories":{},"_nodeVersion":"22.11.0","dependencies":{"zod":"^4.4.3","open":"^11.0.0","@modelcontextprotocol/sdk":"^1.30.0"},"preferGlobal":true,"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^7.0.2","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/at-tm-mcp-server_0.1.0_1785935329459_0.8750678021176341","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@assertthat/at-tm-mcp-server","version":"0.1.1","license":"MIT","_id":"@assertthat/at-tm-mcp-server@0.1.1","maintainers":[{"name":"glib-briia","email":"glib.assertthat@gmail.com"}],"bin":{"at-tm-mcp":"dist/cli.js","at-tm-mcp-server":"dist/server.js"},"dist":{"shasum":"8c1ad62a420d9aeed388bfa3843c91f0a0909f43","tarball":"https://registry.npmjs.org/@assertthat/at-tm-mcp-server/-/at-tm-mcp-server-0.1.1.tgz","fileCount":10,"integrity":"sha512-SKhFhymY1pYK6SB6OzSBQgPHaQ6WRO/3aeBQocRBQ7MayDYX7KiPFg8op2Yj89Y+ZCjBpR9Qa7yOijrQsft6ug==","signatures":[{"sig":"MEUCIEboEqYwyTBmQoHLQWU71pyxR/o8Zz9WfEnWan9VfV0vAiEAkzLOuXl9+7v84FjvPWpBKQi/4t39V/4WitQZSIXwdq8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55140},"type":"module","engines":{"node":">=18.17"},"gitHead":"2a587082598e9d42bf53943fb31bb39c7de58d26","scripts":{"dev":"tsc -p tsconfig.json --watch","build":"tsc -p tsconfig.json","login":"npm run build && node dist/cli.js login","start":"node dist/server.js"},"_npmUser":{"name":"glib-briia","email":"glib.assertthat@gmail.com"},"_npmVersion":"11.6.1","description":"MCP server for the AssertThat AI Test Manager (AT AI TM) Forge app, authenticated with the caller's own Atlassian account.","directories":{},"_nodeVersion":"22.11.0","dependencies":{"zod":"^4.4.3","open":"^11.0.0","@modelcontextprotocol/sdk":"^1.30.0"},"preferGlobal":true,"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^7.0.2","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/at-tm-mcp-server_0.1.1_1787904215176_0.5660691600081638","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@assertthat/at-tm-mcp-server","version":"0.1.2","license":"MIT","_id":"@assertthat/at-tm-mcp-server@0.1.2","maintainers":[{"name":"glib-briia","email":"glib.assertthat@gmail.com"}],"bin":{"at-tm-mcp":"dist/cli.js","at-tm-mcp-server":"dist/server.js"},"dist":{"shasum":"12786c26fe2e34337ceecdc466ec29e569e16915","tarball":"https://registry.npmjs.org/@assertthat/at-tm-mcp-server/-/at-tm-mcp-server-0.1.2.tgz","fileCount":10,"integrity":"sha512-cYfbSO4qMrHPQ4hQCuZha6qWQdKf+w/JNZlnT3QsnpCJ5J9NAbrrlrt20JfTiohtAvHmr01lPTW8dplsbLB4pQ==","signatures":[{"sig":"MEQCICf5rQm7d56/MRuUJI7CrYzj5DDeHSKfwFc3SMXoioYyAiBMQvuEoeaItl5X1E/rffOM9mjJcXXnxdHe6lUFWmtKzQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56817},"type":"module","engines":{"node":">=18.17"},"gitHead":"f9ae878f924f58bfaf15da96a388cba223cdcf52","scripts":{"dev":"tsc -p tsconfig.json --watch","build":"tsc -p tsconfig.json","login":"npm run build && node dist/cli.js login","start":"node dist/server.js"},"_npmUser":{"name":"glib-briia","email":"glib.assertthat@gmail.com"},"_npmVersion":"11.6.1","description":"MCP server for the Testament (formerly AssertThat AI Test Manager) Forge app, authenticated with the caller's own Atlassian account.","directories":{},"_nodeVersion":"22.11.0","dependencies":{"zod":"^4.4.3","open":"^11.0.0","@modelcontextprotocol/sdk":"^1.30.0"},"preferGlobal":true,"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^7.0.2","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/at-tm-mcp-server_0.1.2_1788436183728_0.9849901134680317","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@assertthat/at-tm-mcp-server","version":"0.1.3","license":"MIT","_id":"@assertthat/at-tm-mcp-server@0.1.3","maintainers":[{"name":"glib-briia","email":"glib.assertthat@gmail.com"}],"bin":{"at-tm-mcp":"dist/cli.js","at-tm-mcp-server":"dist/server.js"},"dist":{"shasum":"cc8eb9f07273bb0ebe28a157a954e877f6d27671","tarball":"https://registry.npmjs.org/@assertthat/at-tm-mcp-server/-/at-tm-mcp-server-0.1.3.tgz","fileCount":10,"integrity":"sha512-9kUEhN06j1/I2hw9Hd2RbKnmI09VwaLg/DnbUNhcsjFjpA4RoJqLQS8/Tt4n/zRaCD4NLaLy5CkgAQ4N6fxrtw==","signatures":[{"sig":"MEUCIBbwAHOSc/4SDDN/YfxCwQLH8ZCvBrgD4pDU1Bz8pqGtAiEAhC6BYFGFKIFNBZQcxmVGVEdYGWbOhhF4xFE7WLY8KOg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":60506},"type":"module","engines":{"node":">=18.17"},"gitHead":"f9ae878f924f58bfaf15da96a388cba223cdcf52","scripts":{"dev":"tsc -p tsconfig.json --watch","build":"tsc -p tsconfig.json","login":"npm run build && node dist/cli.js login","start":"node dist/server.js"},"_npmUser":{"name":"glib-briia","email":"glib.assertthat@gmail.com"},"_npmVersion":"11.6.1","description":"MCP server for the Testament (formerly AssertThat AI Test Manager) Forge app, authenticated with the caller's own Atlassian account.","directories":{},"_nodeVersion":"22.11.0","dependencies":{"zod":"^4.4.3","open":"^11.0.0","@modelcontextprotocol/sdk":"^1.30.0"},"preferGlobal":true,"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^7.0.2","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/at-tm-mcp-server_0.1.3_1788520777037_0.5849693717030746","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@assertthat/at-tm-mcp-server","version":"0.1.4","description":"MCP server for the Testament (formerly AssertThat AI Test Manager) Forge app, authenticated with the caller's own Atlassian account.","type":"module","license":"MIT","publishConfig":{"access":"public"},"preferGlobal":true,"bin":{"at-tm-mcp-server":"dist/server.js","at-tm-mcp":"dist/cli.js"},"scripts":{"build":"tsc -p tsconfig.json","dev":"tsc -p tsconfig.json --watch","login":"npm run build && node dist/cli.js login","start":"node dist/server.js"},"engines":{"node":">=18.17"},"dependencies":{"@modelcontextprotocol/sdk":"^1.30.0","open":"^11.0.0","zod":"^4.4.3"},"devDependencies":{"@types/node":"^22.10.2","typescript":"^7.0.2"},"gitHead":"f9ae878f924f58bfaf15da96a388cba223cdcf52","_id":"@assertthat/at-tm-mcp-server@0.1.4","_nodeVersion":"22.11.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-uKdKn+aNhGNlCqeGrI1hFABpoXcCD41uTULQfX2foCzYcqjwfjpJxXTvAotfYAOpyD+HO7wll7hIgt0Iy5U5sg==","shasum":"8e61649b1767c63b0a9695462399205f83258576","tarball":"https://registry.npmjs.org/@assertthat/at-tm-mcp-server/-/at-tm-mcp-server-0.1.4.tgz","fileCount":10,"unpackedSize":59806,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDbmRtJb+MZ6YVdWuINhMeoWM9Bm6SWOTZ5j3UQ3oM57gIgHj++EuOEcV5rqHEtHqPl3bXHhcq1d3nczmsjBonvV0Q="}]},"_npmUser":{"name":"glib-briia","email":"glib.assertthat@gmail.com"},"directories":{},"maintainers":[{"name":"glib-briia","email":"glib.assertthat@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/at-tm-mcp-server_0.1.4_1788530624496_0.2677315200410584"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-05T13:08:49.312Z","modified":"2026-09-04T14:03:44.873Z","0.1.0":"2026-08-05T13:08:49.620Z","0.1.1":"2026-08-28T08:03:35.311Z","0.1.2":"2026-09-03T11:49:43.872Z","0.1.3":"2026-09-04T11:19:37.158Z","0.1.4":"2026-09-04T14:03:44.641Z"},"license":"MIT","description":"MCP server for the Testament (formerly AssertThat AI Test Manager) Forge app, authenticated with the caller's own Atlassian account.","maintainers":[{"name":"glib-briia","email":"glib.assertthat@gmail.com"}],"readme":"# at-tm-mcp-server\n\nMCP server for the **Testament** (formerly AssertThat AI Test Manager) Forge app. Instead of pasting an\napp-generated token, each user signs in with their own **Atlassian account** (OAuth 2.0 / 3LO).\nFrom then on:\n\n- Every tool call carries _that user's own_ Atlassian access token, so Jira's own permission\n  model decides what they can touch — a user with access to projects A/B/C who tries to act on\n  project E is rejected by Jira itself, not by anything this server invents.\n- Access + refresh tokens are cached locally, so the user doesn't have to log in again next\n  session (refresh tokens are used to silently renew the access token).\n- This is a global CLI + a stdio MCP server: install once, run `at-tm-mcp login`, wire it into\n  your AI agent.\n\nCloud-only. Jira Data Center/Server has no equivalent OAuth 3LO / `accessible-resources` /\n`mypermissions` APIs, so this design doesn't extend to it.\n\n## How it fits together\n\n```\nClaude / MCP host  --stdio-->  at-tm-mcp-server  --HTTPS-->  Testament Forge app webtrigger\n                                      |                              |\n                                      | X-User-Access-Token           | assertProjectAccessWithToken()\n                                      | X-Cloud-Id                    | -> /rest/api/3/mypermissions\n                                      | Authorization: Bearer <shared secret>\n```\n\nThe webtrigger side of this already exists in the `at-ai-tm` repo\n(`src/resolvers/api-tools.js` → `webTriggerToolsHandler`, `src/resolvers/auth-remote.js`) — it\nwas already built to accept a caller-supplied Atlassian bearer token + cloud ID and check Jira\npermissions live. This project is the missing piece: it gets that bearer token by having the\nuser log in with Atlassian directly, and keeps it fresh.\n\n## Quick start\n\n### 1. Install\n\n```\nnpm install -g @assertthat/at-tm-mcp-server\n```\n\n> Not published to npm yet? From a clone of this repo: `npm install && npm run build && npm\nlink` — same result, `at-tm-mcp` and `at-tm-mcp-server` land on your PATH either way.\n\n### 2. Log in\n\n```\nat-tm-mcp login\n```\n\nThe first run interactively asks for **four values** before it opens your browser to sign in\nwith Atlassian. Two come from an Atlassian Developer Console OAuth app, two come from Jira's Testament\nadmin page. Both are one-time, per-organization/per-site setup — most teammates just ask\nwhoever did it first for the values instead of repeating these steps.\n\n#### 2a. Atlassian OAuth 2.0 (3LO) app → `clientId` + `clientSecret`\n\nOne person per **organization** needs to register this app once; everyone else reuses the same\nClient ID/Secret pair.\n\n| Step | Where                                             | What to do                                                                                                                                                                                 |\n| ---- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| 1    | <https://developer.atlassian.com/console/myapps/> | Click **Create** → **OAuth 2.0 integration**. Give it a name (e.g. `Testament MCP`) and accept the terms.                                                                                  |\n| 2    | Left sidebar → **Authorization** tab              | Find the **OAuth 2.0 (3LO)** row and click **Configure**. In the **Callback URL** field, enter `http://localhost:8765/callback`, then **Save changes**.                                    |\n| 3    | Left sidebar → **Permissions** tab                | Click **Add** on both **User identity API** and **Jira API** to attach them to the app.                                                                                                    |\n| 4    | Same **Permissions** tab, per API just added      | Click **Configure** on **User identity API** → check the scopes for `read:me`. Click **Configure** on **Jira API** → check the scopes for `read:jira-user` and `read:jira-work`. **Save**. |\n| 5    | Left sidebar → **Settings** tab                   | Scroll to the **Authentication details** section. Copy the **Client ID** directly. Click **Copy** (or reveal, then copy) next to **Secret**.                                               |\n\n| Value        | Maps to                                    | Notes                                                                                                                                                      |\n| ------------ | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Client ID    | `clientId` / `AT_TM_MCP_CLIENT_ID`         | Plain text, safe to share within the org.                                                                                                                  |\n| Secret       | `clientSecret` / `AT_TM_MCP_CLIENT_SECRET` | Treat like a password — only visible once unless you rotate it.                                                                                            |\n| Callback URL | _(not stored — must just match)_           | Only needs to change if you customize `redirectPort` via `at-tm-mcp config set redirectPort <port>`; keep the port in this URL and in that config in sync. |\n| Scopes       | `read:me read:jira-user read:jira-work`    | This is the CLI's built-in default — you don't need to pass it yourself unless your app grants a different scope string.                                   |\n\n#### 2b. Testament webtrigger → `webtriggerUrl` + `sharedSecret`\n\nSelf-service, no Forge CLI needed — but you do need **Jira admin** rights on the site you're\nconnecting to.\n\n| Step | Where                              | What to do                                                                                                     |\n| ---- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------- |\n| 1    | Jira → ⚙️ **Settings** (top right) | Click **Apps**.                                                                                                |\n| 2    | Apps sidebar                       | Under **Manage apps**, find and click **Testament**.                                                           |\n| 3    | Testament app page                 | Open **Testament Global Config**.                                                                              |\n| 4    | Testament Global Config page       | Find the **MCP connection details** section.                                                                   |\n| 5    | MCP connection details             | Click **Copy** next to the **webtrigger URL**. Click **Reveal**, then **Copy**, next to the **shared secret**. |\n\n| Value          | Maps to                                      | Notes                                                                                                                                                                   |\n| -------------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Webtrigger URL | `webtriggerUrl` / `AT_TM_MCP_WEBTRIGGER_URL` | Specific to this Jira **site** — a different site (or a dev/staging install of the Forge app) has a different URL. Not tied to an individual user.                      |\n| Shared secret  | `sharedSecret` / `AT_TM_MCP_SHARED_SECRET`   | Shared by every teammate connecting to this site. If it leaks, click **Regenerate secret** on the same page, then have everyone re-run `at-tm-mcp login --reconfigure`. |\n\n---\n\nOnce all four values are entered, they're saved to `~/.at-tm-mcp/config.json`, then your browser\nopens for the actual Atlassian sign-in, and refresh/access tokens land in\n`~/.at-tm-mcp/credentials.json`. Re-running `at-tm-mcp login` later skips straight to the\nAtlassian sign-in step (reusing saved config) — use `at-tm-mcp login --reconfigure` to re-enter\nthe four values instead (e.g. after rotating the shared secret, or to switch organizations/sites).\n\n> Prefer environment variables instead (e.g. for CI, or to avoid writing secrets to disk)? Set\n> `AT_TM_MCP_CLIENT_ID`, `AT_TM_MCP_CLIENT_SECRET`, `AT_TM_MCP_WEBTRIGGER_URL`,\n> `AT_TM_MCP_SHARED_SECRET` — env vars always take priority over the config file, and skip the\n> setup prompt entirely once all four are set.\n\nAccess tokens refresh automatically and transparently on every tool call once they're close to\nexpiry — you won't need to log in again unless Atlassian revokes the refresh token (long\ninactivity, or you revoking this app's access from your Atlassian account settings). Run\n`at-tm-mcp login` again any time to switch accounts or sites.\n\n### 3. Add it to your AI agent\n\n`login` prints these once it finishes, but for reference:\n\n**Claude Code**:\n\n```\nclaude mcp add at-tm -- at-tm-mcp-server\n```\n\n**Claude Desktop** — add to `claude_desktop_config.json`\n(`%APPDATA%\\Claude\\claude_desktop_config.json` on Windows):\n\n```json\n{\n    \"mcpServers\": {\n        \"at-tm\": {\n            \"command\": \"at-tm-mcp-server\"\n        }\n    }\n}\n```\n\n**Other MCP hosts**: point them at the command `at-tm-mcp-server` with no arguments — no path or\n`env` block needed, since config/credentials already live on disk from step 2.\n\nRestart Claude Desktop (or reload the MCP connection in Claude Code), then confirm the `at-tm`\nserver shows as connected and its tools (`jira_issue`, `test_cases`, etc.) are available.\n\n> The server process itself only serves tool calls — it doesn't run the interactive login flow\n> (a stdio MCP process can't prompt for browser interaction the way a CLI invocation can). Always\n> run `at-tm-mcp login` from a terminal first.\n\n## Everyday commands\n\n```\nat-tm-mcp whoami                who's currently signed in, and to which site\nat-tm-mcp status                config + credential file locations, whether everything's configured\nat-tm-mcp login --reconfigure   re-enter client ID/secret or webtrigger URL/secret\nat-tm-mcp logout                sign out AND wipe all local config (asks to confirm; -y to skip)\nat-tm-mcp config get            show current config (secrets masked)\nat-tm-mcp config set <key> <value>   set one config value manually\n```\n\n## Tools exposed\n\n`jira_issue`, `jira_subtasks`, `folders`, `test_cases`, `test_cases_bulk`, `test_plans`,\n`executions`, `analytics`, `tags`, `issue_links` — same surface as the in-Jira Rovo agent (see\n`manifest.yml`'s `rovo:agent` block in `at-ai-tm`), reachable here over the webtrigger instead.\n\n## Development\n\nRunning from a local clone instead of the global install:\n\n```\nnpm install\nnpm run build   # compiles src/ -> dist/\nnpm run dev     # tsc --watch, recompiles on save\nnode dist/cli.js login   # or: npm run login\n```\n\n`npm link` (after building) puts `at-tm-mcp`/`at-tm-mcp-server` on your PATH pointing at this\nclone's `dist/`, so the Quick start commands above work identically against your working copy.\n\nAfter changing `src/`, rebuild (`npm run build`) and restart the server in your MCP host to pick\nup the change — Claude doesn't hot-reload a running stdio server.\n","readmeFilename":"README.md"}