Jira Connector¶
Connect to Jira to query issues, projects, sprints, and more.
Setup¶
Create Connector¶
CREATE CONNECTOR jira_ops
TYPE 'jira'
CONFIG {
"url": "https://mycompany.atlassian.net",
"email": "{{secrets.jira_email}}",
"token": "{{secrets.jira_token}}"
};
Configure Secrets¶
Get API Token¶
- Go to Atlassian API Tokens
- Click "Create API token"
- Copy the token
Available Entities¶
Issues (issues)¶
SELECT key, summary, status, priority, assignee, created
FROM jira_ops.issues
WHERE project = 'OPS'
AND type = 'Bug'
AND status NOT IN ('Done', 'Closed')
ORDER BY priority DESC, created DESC;
Fields:
| Field | Type | Description |
|---|---|---|
id | STRING | Issue ID |
key | STRING | Issue key (e.g., OPS-123) |
summary | STRING | Issue summary |
description | STRING | Full description |
type | STRING | Issue type (Bug, Task, etc.) |
status | STRING | Current status |
priority | STRING | Priority level |
assignee | STRING | Assignee username |
reporter | STRING | Reporter username |
labels | ARRAY | Issue labels |
components | ARRAY | Components |
created | TIMESTAMP | Creation time |
updated | TIMESTAMP | Last update |
resolved | TIMESTAMP | Resolution time |
project | STRING | Project key |
sprint | STRING | Current sprint |
Projects (projects)¶
Fields:
| Field | Type | Description |
|---|---|---|
id | STRING | Project ID |
key | STRING | Project key |
name | STRING | Project name |
lead | STRING | Project lead |
projectTypeKey | STRING | Type (software, business) |
style | STRING | Style (classic, next-gen) |
Sprints (sprints)¶
SELECT id, name, state, startDate, endDate
FROM jira_ops.sprints
WHERE board = 123
AND state = 'active';
Fields:
| Field | Type | Description |
|---|---|---|
id | NUMBER | Sprint ID |
name | STRING | Sprint name |
state | STRING | future, active, closed |
startDate | TIMESTAMP | Sprint start |
endDate | TIMESTAMP | Sprint end |
goal | STRING | Sprint goal |
board | NUMBER | Board ID |
Comments (comments)¶
Worklogs (worklogs)¶
JQL Queries¶
Use native JQL for complex queries:
SELECT key, summary, status
FROM jira_ops.issues
WHERE JQL = 'project = OPS AND status = "In Progress" AND assignee = currentUser()';
JQL Examples¶
-- Issues updated today
WHERE JQL = 'updated >= startOfDay()'
-- High priority bugs
WHERE JQL = 'type = Bug AND priority in (High, Highest)'
-- Issues in current sprint
WHERE JQL = 'sprint in openSprints()'
-- Overdue issues
WHERE JQL = 'duedate < now() AND status != Done'
-- Issues with specific label
WHERE JQL = 'labels = incident'
Actions¶
Create Issue¶
CONNECTOR_EXEC jira_ops.issues.create({
"project": "OPS",
"type": "Task",
"summary": "Automated task from Moltler",
"description": "This task was created automatically.",
"priority": "Medium",
"labels": ["automated"]
});
Update Issue¶
CONNECTOR_EXEC jira_ops.issues.update(
issue_key => 'OPS-123',
data => {
"summary": "Updated summary",
"priority": "High"
}
);
Transition Issue¶
-- Move to "In Progress"
CONNECTOR_EXEC jira_ops.issues.transition(
issue_key => 'OPS-123',
transition => 'Start Progress'
);
-- Move to "Done"
CONNECTOR_EXEC jira_ops.issues.transition(
issue_key => 'OPS-123',
transition => 'Done',
resolution => 'Fixed'
);
Add Comment¶
CONNECTOR_EXEC jira_ops.issues.comment(
issue_key => 'OPS-123',
body => 'Automated comment from Moltler'
);
Assign Issue¶
Add Watcher¶
Log Work¶
CONNECTOR_EXEC jira_ops.issues.worklog(
issue_key => 'OPS-123',
time_spent => '2h',
comment => 'Investigating issue'
);
Syncing¶
Sync All Issues¶
Sync Specific Project¶
Incremental Sync¶
Example Skills¶
Skill: Create Incident Ticket¶
CREATE SKILL create_incident_ticket
VERSION '1.0.0'
DESCRIPTION 'Creates a Jira incident ticket'
PARAMETERS (
connector STRING,
title STRING,
description STRING,
severity STRING DEFAULT 'Medium'
)
RETURNS DOCUMENT
BEGIN
DECLARE priority = CASE severity
WHEN 'Critical' THEN 'Highest'
WHEN 'High' THEN 'High'
WHEN 'Medium' THEN 'Medium'
ELSE 'Low'
END;
DECLARE result = CONNECTOR_EXEC connector.issues.create({
"project": "OPS",
"type": "Incident",
"summary": "[INCIDENT] " || title,
"description": description,
"priority": priority,
"labels": ["incident", "automated"]
});
RETURN {
"ticket_key": result.key,
"url": result.self
};
END SKILL;
Skill: Get Sprint Status¶
CREATE SKILL get_sprint_status
VERSION '1.0.0'
DESCRIPTION 'Gets current sprint status with metrics'
PARAMETERS (
connector STRING,
project STRING
)
RETURNS DOCUMENT
BEGIN
-- Get active sprint
DECLARE sprint_cursor CURSOR FOR
SELECT id, name, startDate, endDate
FROM connector.sprints
WHERE state = 'active'
LIMIT 1;
OPEN sprint_cursor;
DECLARE sprint = NULL;
FETCH sprint_cursor INTO sprint;
CLOSE sprint_cursor;
IF sprint IS NULL THEN
RETURN {"error": "No active sprint found"};
END IF;
-- Get issue counts
DECLARE issues_cursor CURSOR FOR
SELECT status, COUNT(*) as count
FROM connector.issues
WHERE JQL = 'project = ' || project || ' AND sprint = ' || sprint.id
GROUP BY status;
DECLARE status_counts = {};
OPEN issues_cursor;
FOR issue IN issues_cursor LOOP
SET status_counts[issue.status] = issue.count;
END LOOP;
CLOSE issues_cursor;
-- Calculate progress
DECLARE total = SUM(DOCUMENT_VALUES(status_counts));
DECLARE done = status_counts.Done ?? 0;
DECLARE progress = CASE WHEN total > 0 THEN ROUND(done * 100 / total) ELSE 0 END;
RETURN {
"sprint": sprint.name,
"start_date": sprint.startDate,
"end_date": sprint.endDate,
"status_counts": status_counts,
"total_issues": total,
"done_issues": done,
"progress_percent": progress
};
END SKILL;
Skill: Auto-Assign Incidents¶
CREATE SKILL auto_assign_incidents
VERSION '1.0.0'
DESCRIPTION 'Automatically assigns unassigned incidents'
PARAMETERS (
connector STRING,
project STRING,
oncall_user STRING
)
RETURNS NUMBER
BEGIN
DECLARE unassigned CURSOR FOR
SELECT key
FROM connector.issues
WHERE JQL = 'project = ' || project ||
' AND type = Incident AND assignee IS EMPTY';
DECLARE count = 0;
OPEN unassigned;
FOR issue IN unassigned LOOP
CONNECTOR_EXEC connector.issues.assign(
issue_key => issue.key,
assignee => oncall_user
);
SET count = count + 1;
END LOOP;
CLOSE unassigned;
RETURN count;
END SKILL;
Configuration Options¶
CREATE CONNECTOR jira_ops
TYPE 'jira'
CONFIG {
"url": "https://mycompany.atlassian.net",
"email": "{{secrets.jira_email}}",
"token": "{{secrets.jira_token}}"
}
OPTIONS {
"rate_limit": 100, -- Requests per minute
"timeout_seconds": 30, -- Request timeout
"max_results": 1000, -- Max results per query
"expand": ["changelog"] -- Expand fields
};
Troubleshooting¶
Authentication Errors¶
Solution: Use API token, not password:
- Generate token at Atlassian API Tokens
- Update secret:
moltler secrets set jira_token NEW_TOKEN
Rate Limiting¶
Solution: Reduce rate limit in connector options.
Permission Errors¶
Solution: Ensure the API token owner has appropriate Jira permissions.