Jira Agent Gateway
by yauchinlam
README.md
# Jira Agent Gateway
A public, cloud-agnostic, TypeScript-based MCP-compatible gateway that lets AI agents administer a Jira project through controlled backend tool calls. The default target user is someone who is not a Scrum Master and wants an AI Scrum Master agent to create and manage one Jira project for them. Agents call this gateway; they never receive Jira credentials or call Jira directly.
## Architecture
```text
AI agent
-> MCP tool call or HTTP API request
-> TypeScript Jira Agent Gateway
-> Tool registry
-> Validation layer
-> Policy and risk engine
-> Approval hooks, if needed
-> Jira connector
-> Jira REST API
-> Audit logger
-> Structured response
```
Gateway capability areas:
- Project administration: create and administer the Jira project owned by the AI Scrum Master workflow through high-risk, approval-gated tools such as `create_jira_project`.
- Issue operations: search, read, create, update, assign, link, and transition Jira work items.
- Story operations: create Jira stories through `create_jira_story`.
- Epic operations: create Jira epics through `create_jira_epic`.
- Bug operations: create Jira bugs through `create_jira_bug`.
- Assignment defaults: whenever a tool has an assignee option and the caller omits it, the gateway assigns work to the Jira account configured by `JIRA_EMAIL`.
- Comment operations: add Jira comments through `add_jira_comment`.
- Sprint operations: create sprints through `create_jira_sprint` and add work to sprints through `add_jira_issues_to_sprint`.
- Policy and approval: classify risky writes, require approval where needed, and reject malformed or overly broad requests.
- Audit: log every write action with agent/user identity, payload, approval status, result, and error details.
The same `executeTool` pipeline is used by MCP and HTTP mode:
1. Validate tool schema with Zod.
2. Validate Jira-specific constraints.
3. Resolve authentication from server-side config.
4. Resolve default assignee from `JIRA_EMAIL` when an assignee-capable tool does not specify one.
5. Classify risk.
6. Check policy.
7. Request approval for high-risk actions.
8. Execute the Jira API call through the connector.
9. Write an audit event.
10. Return a structured result.
## Install
```bash
npm install jira-agent-gateway
```
or run it directly:
```bash
npx jira-agent-gateway mcp
npx jira-agent-gateway serve --port 8787
```
For local development:
```bash
npm install
npm run build
node dist/cli/index.js mcp
node dist/cli/index.js serve --port 8787
```
## Configuration
Configuration can come from environment variables or a JSON config file. Environment variables override file values.
```bash
JIRA_BASE_URL=https://example.atlassian.net
JIRA_EMAIL=you@example.com
JIRA_API_TOKEN=replace-me
JIRA_AUTH_MODE=scoped
JIRA_DEFAULT_PROJECT=PROJ
JIRA_APPROVAL_MODE=console
JIRA_AUDIT_LOG_MODE=console
```
How to get these values:
| Variable | How to set it |
| --- | --- |
| `JIRA_BASE_URL` | Use your Jira site URL, usually `https://your-company.atlassian.net`. Open Jira in your browser and copy the origin before `/jira` or `/browse`. |
| `JIRA_EMAIL` | Use the email address for the Atlassian account that owns the API token. |
| `JIRA_API_TOKEN` | For Jira Cloud, create one at <https://id.atlassian.com/manage-profile/security/api-tokens>. Copy it once and store it as a secret. |
| `JIRA_AUTH_MODE` | Use `scoped` by default. Use `classic` only for quick local development, prototyping, or compatibility fallback. |
| `JIRA_DEFAULT_PROJECT` | Use the Jira project key shown in issue keys, such as `PROJ` from `PROJ-123`. |
| `JIRA_APPROVAL_MODE` | Use `console` for local development, `webhook` for production approval workflows, or `none` to deny approval-gated actions. |
| `JIRA_AUDIT_LOG_MODE` | Use `console` for local development, `file` for local append-only logs, `webhook` for centralized audit ingestion, or `none` to disable audit logging. |
## Jira API Token Recommendation
This framework supports both classic Jira API tokens and scoped Jira API tokens.
TLDR:
- Use a scoped API token for real usage, shared usage, public usage, or production-like usage.
- Use a classic API token only for quick local development, prototyping, or compatibility fallback.
Scoped tokens are recommended because they follow least privilege, limit what the token can access, reduce risk if the token is exposed, and are safer for an AI-agent gateway that may perform real Jira actions. AI agents should never receive the token directly.
Recommended read-only scoped token permissions:
```text
read:jira-work
read:jira-user
```
Read-only mode supports:
- `search_jira_issues`
- `get_jira_issue`
- `get_jira_transitions`
- reporting
- summarization
Recommended standard write scoped token permissions:
```text
read:jira-work
read:jira-user
write:jira-work
write:comment
write:epic
write:sprint
```
Standard write mode supports:
- `create_jira_issue` for Jira stories, epics, tasks, bugs, and other configured issue types
- `create_jira_story`
- `create_jira_epic`
- `create_jira_bug`
- `create_jira_sprint`
- `add_jira_issues_to_sprint`
- `update_jira_issue`
- `add_jira_comment`
- `assign_jira_issue`
- `transition_jira_issue`
- `link_jira_issues`
Token scopes are only one layer of authorization. The Jira user that owns the token must also have project-level permissions for the target project, especially **Browse Projects** for read tools and **Create Issues** for `create_jira_issue`, `create_jira_story`, and `create_jira_epic`.
The default workflow assumes the AI Scrum Master can create and administer the Jira project it owns. That project administration capability is high risk, so it should use admin-scoped permissions plus approval:
```text
read:jira-work
read:jira-user
write:jira-work
write:comment
write:epic
write:sprint
manage:jira-project
manage:jira-configuration
```
`create_jira_project` is high-risk and approval-gated by default because it changes Jira administration structure. After the project is created, the agent should administer that one project through gateway policy rather than being given unconstrained Jira access.
Avoid unrelated admin scopes unless the framework intentionally adds that administrative feature. In particular, avoid:
- `manage:jira-webhook`
This framework is designed for AI-assisted Jira project administration within the project the agent creates or is assigned to manage. It should not administer unrelated Jira projects, global Jira configuration, permissions, workflows, or webhooks unless those capabilities are explicitly added and policy-gated.
Authentication mode examples:
```bash
JIRA_AUTH_MODE=scoped
```
```bash
JIRA_AUTH_MODE=classic
```
The recommended default is:
```bash
JIRA_AUTH_MODE=scoped
```
Security note: Jira credentials must never be exposed to AI agents, prompts, frontend clients, browser code, or public logs. Jira credentials should stay inside the gateway runtime through environment variables, local secrets, or a user-managed secret provider.
AI agents should call structured gateway tools. They should never call Jira directly.
## Jira API Token Setup
For Jira Cloud, create the token from your Atlassian account:
1. Go to <https://id.atlassian.com/manage-profile/security/api-tokens>.
2. Select **Create API token** for a standard token, or **Create API token with scopes** if your organization requires scoped tokens.
3. Give the token a purpose-specific name, such as `jira-agent-gateway-dev`.
4. Choose an expiration date. Atlassian API tokens can expire, so set a reminder to rotate it.
5. Copy the token immediately and store it in a password manager or secret manager. Atlassian does not show the token again.
6. Set `JIRA_EMAIL` to the Atlassian account email that created the token.
7. Set `JIRA_API_TOKEN` to the copied token value.
Recommended Jira scopes:
| Gateway capability | Scope | Why it is needed |
| --- | --- | --- |
| Search issues, read issue details, get transitions | `read:jira-work` | Allows the gateway to read Jira project and issue data and search issues. |
| Create and update Jira work items | `write:jira-work` | Allows the gateway to create, edit, assign, transition, and link Jira issues through controlled tools. |
| Add comments | `write:comment` | Allows `add_jira_comment` to post comments without granting broader admin permissions. |
| Create and manage epics | `write:epic` | Allows epic-specific creation and updates when using `create_jira_epic` or future epic tools. |
| Sprint work | `write:sprint` | Allows `create_jira_sprint` and `add_jira_issues_to_sprint` to plan work in biweekly or custom sprints. |
| Create Jira projects | `manage:jira-project` plus Jira Administrator global permission | Allows `create_jira_project` to create new Jira projects when project creation mode is enabled. |
| Configure Jira project defaults | `manage:jira-configuration` | May be required by Jira Cloud for project creation templates and project configuration defaults. |
| Resolve or inspect Jira users | `read:jira-user` | Optional. Useful if you add user lookup, account-id resolution, or richer assignee validation. |
Use the smallest scope set that matches the tools you enable. A read-only deployment needs `read:jira-work` and `read:jira-user`; the standard AI Scrum Master deployment should include `read:jira-work`, `read:jira-user`, `write:jira-work`, `write:comment`, `write:epic`, `write:sprint`, `manage:jira-project`, and `manage:jira-configuration`. Avoid `manage:jira-webhook` unless you add webhook administration tools.
Important: scoped Atlassian API tokens are designed for the Atlassian API endpoint form `https://api.atlassian.com/ex/jira/{cloudId}`. The default examples in this README use `JIRA_BASE_URL=https://example.atlassian.net`, which is the normal Jira site URL for standard API-token basic auth. If you require scoped tokens, configure the connector/base URL strategy accordingly before production use.
Project creation auth note: Jira Cloud project creation is stricter than normal issue work. The Atlassian account that owns the token must have **Jira Administrator global permission** in the Jira site. A token with only `manage:jira-project` and `manage:jira-configuration` may still fail project creation because the workflow also needs to read Jira data and then create epics, stories, comments, sprints, and issues. For the default AI Scrum Master workflow, create the token with the full standard set above from a Jira Administrator account. If Jira still rejects `create_jira_project` with an authentication error, use `JIRA_AUTH_MODE=classic` with a classic API token from a Jira site admin account, or move project creation to an OAuth app flow with the same administrative permissions.
Official references:
- Atlassian account API token docs: <https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/>
- Jira Cloud scope docs: <https://developer.atlassian.com/cloud/jira/platform/scopes-for-oauth-2-3LO-and-forge-apps/>
For local development, create a `.env` file from `.env.example` and replace the placeholder values:
```bash
cp .env.example .env
```
Run with a config file:
```bash
jira-agent-gateway mcp --config ./config.example.json
jira-agent-gateway serve --config ./config.example.json --port 8787
```
## Tools
| Tool | Risk | Purpose |
| --- | --- | --- |
| `search_jira_issues` | read | Search Jira issues with scoped JQL. |
| `get_jira_issue` | read | Read issue details. |
| `create_jira_project` | high | Create a Jira project for a Scrum team. Approval-gated by default and requires admin-scoped permissions. |
| `create_jira_issue` | low or high | Create Jira work items such as stories, epics, tasks, bugs, and other project-configured issue types. Critical or Blocker priority is high risk. |
| `create_jira_story` | low or high | Create a Jira Story in a project. Critical or Blocker priority is high risk. |
| `create_jira_epic` | low or high | Create a Jira Epic in a project. Critical or Blocker priority is high risk. |
| `create_jira_bug` | low or high | Create a Jira Bug in a project. Critical or Blocker priority is high risk. |
| `update_jira_issue` | low or high | Update issue fields. Workflow, security, resolution, fix version, and Critical or Blocker priority changes are high risk. |
| `add_jira_comment` | low | Add an issue comment. |
| `assign_jira_issue` | low | Assign an issue to a Jira account id. If omitted, the assignee defaults to the account configured by `JIRA_EMAIL`. |
| `get_jira_transitions` | read | List available transitions. |
| `transition_jira_issue` | high | Transition an issue. Approval-gated by default. |
| `link_jira_issues` | low | Link two issues. |
| `create_jira_sprint` | low | Create a Jira sprint on a Scrum board. |
| `add_jira_issues_to_sprint` | low | Add stories, tasks, bugs, or other issues to a sprint. |
## AI Scrum Master Workflow
This gateway is intended to support an AI agent acting as a Scrum Master for users who do not want to administer Jira themselves. The default flow is:
1. Create or select a Jira project with `create_jira_project`.
2. Create a biweekly sprint with `create_jira_sprint`.
3. Create epics with `create_jira_epic`.
4. Create stories with `create_jira_story`.
5. Create implementation tasks or other work items with `create_jira_issue`.
6. Create bugs with `create_jira_bug`.
7. Add the sprint's work items to the sprint with `add_jira_issues_to_sprint`.
8. Track updates, comments, assignments, links, and transitions through the gateway.
Project creation and project administration are intentionally high-risk and should require human approval. Once approved, the agent should administer the project it created: create biweekly sprints, create epics, add stories, add implementation issues, track bugs, and manage the sprint plan. Sprint and work-item creation are lower risk by default, but still audited.
## Creating Projects, Sprints, Stories, Epics, Issues, and Bugs
The gateway is designed to let AI agents create Jira work items through controlled tools.
Use these first-class tools when the intent is specific:
- `create_jira_project` creates a Jira project.
- `create_jira_sprint` creates a sprint on a Scrum board.
- `create_jira_story` creates a Jira Story.
- `create_jira_epic` creates a Jira Epic.
- `create_jira_bug` creates a Jira Bug.
- `add_jira_issues_to_sprint` adds planned work to a sprint.
- `create_jira_issue` creates any configured Jira issue type by accepting `issueType`.
Example project:
```json
{
"key": "SCRUM",
"name": "My Scrum Space",
"projectTypeKey": "software",
"description": "Scrum project managed through the Jira Agent Gateway."
}
```
Call it through:
```text
create_jira_project(key, name, projectTypeKey, projectTemplateKey, leadAccountId, description)
```
Example biweekly sprint:
```json
{
"boardId": 1,
"name": "Sprint 2026-07-01 to 2026-07-14",
"startDate": "2026-07-01T09:00:00.000Z",
"endDate": "2026-07-14T17:00:00.000Z",
"goal": "Deliver the first validated gateway workflow."
}
```
Call it through:
```text
create_jira_sprint(boardId, name, startDate, endDate, goal)
```
The generic `create_jira_issue` tool passes `issueType` to Jira, so it can create any issue type configured for the target project, including:
- `Story`
- `Epic`
- `Task`
- `Bug`
- Custom issue types configured in Jira
Example Story:
```json
{
"projectKey": "SCRUM",
"summary": "As a user, I want safer Jira automation",
"description": "Created through the Jira Agent Gateway with validated inputs and audit logging.",
"priority": "Medium"
}
```
Call it through:
```text
create_jira_story(projectKey, summary, description, priority)
```
If `assignee` is omitted, the gateway assigns the story to the account configured by `JIRA_EMAIL`.
Example Epic:
```json
{
"projectKey": "SCRUM",
"summary": "AI-assisted Jira operations",
"description": "Parent initiative for gateway-driven Jira workflows.",
"priority": "Medium"
}
```
Call it through:
```text
create_jira_epic(projectKey, summary, description, priority)
```
Generic issue example:
```json
{
"projectKey": "SCRUM",
"issueType": "Bug",
"summary": "Investigate gateway validation edge case",
"description": "Created through the generic create_jira_issue tool.",
"priority": "Medium"
}
```
Call it through:
```text
create_jira_issue(projectKey, issueType, summary, description, priority)
```
If `assignee` is omitted, the gateway assigns the issue to the account configured by `JIRA_EMAIL`.
Example Bug:
```json
{
"projectKey": "SCRUM",
"summary": "Bug: gateway should validate missing sprint id",
"description": "A bug found during AI Scrum Master workflow testing.",
"priority": "Medium"
}
```
Call it through:
```text
create_jira_bug(projectKey, summary, description, priority)
```
If `assignee` is omitted, the gateway assigns the bug to the account configured by `JIRA_EMAIL`.
Add work to sprint:
```json
{
"sprintId": 42,
"issueKeys": ["SCRUM-1", "SCRUM-2", "SCRUM-3"]
}
```
Call it through:
```text
add_jira_issues_to_sprint(sprintId, issueKeys)
```
Requirements for creation:
- The token must include `write:jira-work`.
- The default AI Scrum Master workflow token should include `read:jira-work`, `read:jira-user`, `write:jira-work`, `write:comment`, `write:epic`, `write:sprint`, `manage:jira-project`, and `manage:jira-configuration`.
- The Atlassian account that owns the token must have **Jira Administrator global permission** to create projects through the REST API.
- Jira Cloud project creation may require `leadAccountId`, which is the Atlassian account ID of the project lead. Server/Data Center can use a username string instead.
- Story creation should use `create_jira_story`; epic creation should use `create_jira_epic`.
- Epic creation should include `write:epic` when using scoped tokens.
- Comment creation should include `write:comment` when using scoped tokens.
- Sprint creation and sprint planning should include `write:sprint` when using scoped tokens.
- Project creation should include `manage:jira-project` and may require `manage:jira-configuration`; some Jira Cloud tenants may require a classic API token from a Jira site admin or an OAuth app flow for this specific operation.
- The Jira user that owns the token must be able to create the same work item manually in Jira.
- The requested `issueType` must exist in that project and be available on the project's create screen.
- Required Jira fields for that issue type must either be provided by the gateway input or have defaults in Jira.
If Jira returns an error such as "project does not exist or you do not have permission to create issues", the token may be valid but the Jira user likely lacks project-level **Create Issues** permission or the issue type is not enabled for that project.
## HTTP API
```bash
curl http://localhost:8787/health
curl http://localhost:8787/tools
```
Invoke a tool:
```bash
curl -X POST http://localhost:8787/tools/search_jira_issues \
-H 'Content-Type: application/json' \
-H 'x-agent-id: example-agent' \
-d '{"jql":"project = PROJ ORDER BY created DESC","maxResults":10}'
```
Create a Story:
```bash
curl -X POST http://localhost:8787/tools/create_jira_story \
-H 'Content-Type: application/json' \
-d '{
"projectKey": "SCRUM",
"summary": "As a team, we want controlled Jira automation",
"description": "Created through Jira Agent Gateway",
"priority": "Medium"
}'
```
Create an Epic:
```bash
curl -X POST http://localhost:8787/tools/create_jira_epic \
-H 'Content-Type: application/json' \
-d '{
"projectKey": "SCRUM",
"summary": "AI-assisted Jira operations",
"description": "Created through Jira Agent Gateway",
"priority": "Medium"
}'
```
## MCP Usage
Configure your MCP-compatible AI agent to launch:
```json
{
"mcpServers": {
"jira-agent-gateway": {
"command": "npx",
"args": ["jira-agent-gateway", "mcp"],
"env": {
"JIRA_BASE_URL": "https://example.atlassian.net",
"JIRA_EMAIL": "you@example.com",
"JIRA_API_TOKEN": "replace-me",
"JIRA_AUTH_MODE": "scoped"
}
}
}
}
```
Example agent instruction:
```text
Use the jira-agent-gateway MCP tools to search project PROJ for open bugs.
Do not ask for Jira credentials. If a high-risk write action is required,
request approval through the gateway.
```
## Structured Responses
Success:
```json
{
"success": true,
"action": "create_jira_issue",
"riskLevel": "low",
"issueKey": "PROJ-123",
"issueUrl": "https://example.atlassian.net/browse/PROJ-123",
"summary": "Created Jira issue PROJ-123.",
"warnings": [],
"requiresApproval": false,
"approvalStatus": "not_required"
}
```
Rejected or approval-gated:
```json
{
"success": false,
"action": "transition_jira_issue",
"riskLevel": "high",
"errorCode": "APPROVAL_REQUIRED",
"message": "This action requires human approval before execution.",
"warnings": [],
"requiresApproval": true,
"approvalStatus": "denied",
"proposedAction": {
"issueKey": "PROJ-123",
"transitionId": "31"
}
}
```
## Approval Providers
The approval layer is pluggable through `ApprovalProvider`.
Included providers:
- `console`: prompts a local operator.
- `webhook`: POSTs approval requests to a URL and expects `{ "approved": true }`.
- `none`: denies approval-gated actions.
High-risk actions require approval by default.
## Audit Loggers
The audit layer is pluggable through `AuditLogger`.
Included loggers:
- `console`
- `file`
- `webhook`
- `none`
Every action logs timestamp, agent/user ids when supplied, issue key when available, action, risk level, request payload, approval status, result, and error details.
## Security Recommendations
- Never pass Jira credentials in tool inputs.
- Keep Jira credentials in environment variables, local secrets, or your secret manager.
- Do not expose this gateway directly to untrusted clients without authentication and network controls.
- Scope Jira API tokens to the minimum permissions required.
- Keep high-risk actions approval-gated in production.
- Set webhook approval endpoints behind authenticated internal services.
- Store audit logs in append-only or tamper-resistant storage for regulated workflows.
- Prefer narrowly scoped JQL and project-level policies for multi-agent deployments.
## Error Handling Strategy
The gateway returns structured errors with stable `errorCode` values:
- `VALIDATION_ERROR`: Zod rejected malformed input.
- `POLICY_REJECTED`: policy denied an action.
- `OVERLY_BROAD_QUERY`: JQL looked too broad for an agent search.
- `APPROVAL_REQUIRED`: approval was required and not granted.
- `EXECUTION_ERROR`: Jira API or connector execution failed.
- `UNKNOWN_TOOL`: HTTP caller requested an unknown tool.
## Testing Strategy
Recommended coverage:
- Unit test every Zod schema with valid and invalid tool payloads.
- Unit test `classifyRisk` for read, low, and high-risk cases.
- Unit test `validateAction` for overly broad JQL and high-risk approval gating.
- Mock `JiraClient` in tool pipeline tests to verify audit and approval behavior.
- Integration test HTTP routes with a fake runtime.
- Smoke test MCP startup with test credentials disabled and mocked connectors.
- Contract test Jira Cloud requests against a mocked Jira REST server.
## Connector Model
`JiraClient` is the adapter boundary. `JiraCloudClient` implements Jira Cloud REST API v3. `JiraDataCenterClient` currently inherits the same surface so Data Center-specific REST differences can be added without changing tools or servers.
## Project Structure
```text
/src
/tools
/connectors
/policy
/approval
/auth
/audit
/schemas
/server
/cli
/config
```
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues