lean-jira-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@lean-jira-mcpsearch for issues assigned to me"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
lean-jira-mcp
A lean, agent-first MCP server for JIRA Cloud. See DESIGN.md
for the rationale and design decisions.
Instead of mapping the REST API 1:1, it exposes 10 intent-shaped tools that read
and write markdown (not raw ADF), resolve human references (emails, "me", status
names) server-side, hide internal IDs and pagination mechanics, and stamp every
response — success or error — with recovery hints.
Tools & resources
Tools: jira_search, jira_get_issue, jira_create_issue,
jira_update_issue, jira_transition, jira_comment, jira_get_comments,
jira_describe_project, jira_read_attachment, jira_add_attachment.
Resources: jira://projects (project catalog), jira://jql-fields (JQL
field catalog incl. custom fields), jira://link-types.
Related MCP server: Jira Cloud MCP Server
Requirements
A JIRA Cloud site + a classic, unscoped API token (see below)
One of: a host that can run the published bin via
npx(Node ≥ 18), the one-click.mcpbbundle, or Bun ≥ 1.3 for local development
Configuration
All configuration is read from the environment at startup — credentials are never passed as tool arguments. Missing or blank required values fail fast with a clear startup error naming the variable.
Variable | Required | Default | Description |
| yes | — | Your JIRA Cloud site, e.g. |
| yes | — | Atlassian account email (HTTP basic auth) |
| yes | — | Classic, unscoped API token (see below) |
| no | — | Project key used by |
| no |
| Visible marker prefixed to comments the agent posts |
| no | auto-detected | Custom-field id backing Story Points (explicit override) |
| no | auto-detected | Custom-field id backing Sprint (explicit override) |
| no | auto-detected | Custom-field id backing Epic Link (explicit override) |
| no |
| Hard byte ceiling for |
| no | cwd + temp dirs | Path-delimiter ( |
| no |
| Size cap for |
The three JIRA_FIELD_* ids back the curated agile fields surfaced by
jira_get_issue. The server detects each id automatically per instance at
startup (Sprint and Epic Link by their stable JIRA Software schema key, Story
Points by field name), so these are only needed as an explicit override when
detection misses on your instance — find the id at /rest/api/3/field and set
the matching variable. If a field isn't detected and no override is set, the
server logs a warning naming it and omits it from jira_get_issue rather than
guessing.
The API token must be unscoped
Create the token at id.atlassian.com → API tokens with "Create API token" — not "Create API token with scopes".
A scoped token (one with granular scopes such as read:jira-work,
write:jira-work, read:jira-user, read:me) does not work with HTTP basic
auth. JIRA Cloud doesn't reject it outright — it silently treats the request as
anonymous, so data endpoints return 200 with empty results while
/myself returns 401. The symptom is "every search returns 0 issues."
The server guards against this: on the first tool call it preflights /rest/api/3/myself
once (memoized). If the credentials are rejected, the tool returns an
authentication_failed error with a hint instead of a misleading empty result.
Quick check that a token works:
curl -s -u "$JIRA_EMAIL:$JIRA_API_TOKEN" \
https://your-domain.atlassian.net/rest/api/3/myself
# → your user JSON (good) | 401 "Client must be authenticated" (bad token)Install
Claude Code
claude mcp add jira \
-e JIRA_BASE_URL=https://your-domain.atlassian.net \
-e JIRA_EMAIL=you@example.com \
-e JIRA_API_TOKEN=your-api-token \
-- npx -y lean-jira-mcpDefault scope is local (this project only); add -s user before -- to make
it available in all your projects.
Codex CLI
codex mcp add jira \
--env JIRA_BASE_URL=https://your-domain.atlassian.net \
--env JIRA_EMAIL=you@example.com \
--env JIRA_API_TOKEN=your-api-token \
-- npx -y lean-jira-mcpOr edit ~/.codex/config.toml directly:
[mcp_servers.jira]
command = "npx"
args = ["-y", "lean-jira-mcp"]
[mcp_servers.jira.env]
JIRA_BASE_URL = "https://your-domain.atlassian.net"
JIRA_EMAIL = "you@example.com"
JIRA_API_TOKEN = "your-api-token"Any other MCP client — npx
No manual build: the published package ships a self-contained, Node-runnable bin.
Point your client's MCP config at it and supply credentials via env:
{
"mcpServers": {
"jira": {
"command": "npx",
"args": ["-y", "lean-jira-mcp"],
"env": {
"JIRA_BASE_URL": "https://your-domain.atlassian.net",
"JIRA_EMAIL": "you@example.com",
"JIRA_API_TOKEN": "your-unscoped-api-token",
"JIRA_PROJECT_DEFAULT": "PROJ",
"JIRA_MCP_COMMENT_MARKER": ":claude:"
}
}
}
}(In Claude Desktop this lives in claude_desktop_config.json. Only the first
three env vars are required; the rest are optional.)
Claude Desktop — .mcpb bundle (one-click)
Build the bundle, then open it in Claude Desktop (Settings → Extensions, or
double-click the .mcpb file). Claude Desktop prompts for the configuration
values listed above and stores the API token securely.
bun install
bun run build:mcpb # → dist/lean-jira-mcp.mcpbThe bundle is a self-contained Node payload (no node_modules to ship) plus a
manifest.json whose config prompts map 1:1 onto the env
variables in the table above. To validate the manifest against the official spec:
npx -y @anthropic-ai/mcpb validate manifest.jsonKnown limitations
Comment reactions are not readable. Emoji reactions (👍 etc.) are not exposed by the Jira Cloud REST/token API — there is no
reactionsfield, expand, or Jira Expressions route, and the internal reaction endpoints are absent on Cloud (or cookie/session-auth only). The only honest out-of-band route is browser automation against the rendered UI (session auth) — a different mechanism and a different tool, explicitly out of scope for this REST/token-auth server. Treat reactions as a blind spot: never infer a decision, approval, or consensus from them — this server keys hand-offs off API-visible artifacts (text comments, labels, status) only.
Local development
bun install
cp .env.example .env # fill in JIRA_BASE_URL, JIRA_EMAIL, JIRA_API_TOKEN
bun run start # serve over stdio
bun test # full offline test suite (no network)
bun run typecheck # tsc --noEmit
bun run build # bundle the Node bin → dist/index.jsThe Bun .env autoload footgun (config can look ignored)
Bun auto-loads a .env from the working directory. When an MCP client
launches the server with bun run src/index.ts and cwd = this repo, a stray
repo .env backfills any env var the client didn't set in its own config —
silently. That can:
mask the fail-fast contract — a missing required var looks "set" because
.envfilled it in, so the server starts instead of failing loudly; andmake
JIRA_PROJECT_DEFAULTlook ignored — the repo.env's value wins over what you thought the client was (or wasn't) passing.
The published Node bin does not autoload .env — this only bites local
development/testing via Bun. To test config and fail-fast behaviour faithfully,
run from a clean cwd (or temporarily move the repo .env aside) so only the
vars you actually pass are in scope:
cd "$(mktemp -d)" && JIRA_BASE_URL=… JIRA_EMAIL=… JIRA_API_TOKEN=… bun run /path/to/repo/src/index.tsArchitecture
src/config/env.ts— the single config read path: loads + validates env, fails fast.src/lib/jira-client.ts— the single HTTP boundary to JIRA (auth, retry/backoff). The one external test seam; tool handlers depend on theIJiraClientinterface.src/lib/response-shaper.ts— uniform success/error envelope that stampshints.src/tools/— one file per tool + a central registry (tools/index.ts).src/resources/— the static reference resources + registry.src/core/server.ts— dependency-injectedMcpServerconstruction.test/helpers/fake-jira-client.ts— the faked-JiraClientfixture every tool reuses.
Manual / live smoke test
The test suite runs fully offline against the fake client. To exercise the real
JIRA path, set credentials in .env and point MCP Inspector at the server:
bunx @modelcontextprotocol/inspector bun run src/index.tsThen call jira_search with a real jql (e.g. project = ABC ORDER BY updated DESC).
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/wjarka/lean-jira-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server