linear-toon-mcp 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/linear_toon_mcp/tools/list_issues.rb +24 -12
- data/lib/linear_toon_mcp/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aab17aaea0e785a45bb6dfdc1b138c5eb501d869510d168ca7002c82c5edcc89
|
|
4
|
+
data.tar.gz: 28260e8446076959ab838c8e81baacd4ef19a360d69c589ce97fb8da6fd02f73
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2b657327e07365e2ae65360aa6c3e51df250742779d736a3f1de6ebe2d90f231155a80eb7baddde7db0bc7f11872b86fb1049acdf9292880295a43be4f17f83a
|
|
7
|
+
data.tar.gz: baeb3c97ff7324c76f3fe1fa4a87ea78dd66792f17efb3258da10aab04bea9cf660d88a124bde63974ffb7ad8cf4556c56cc9163986dc4b619bc4a2366cfa3ed
|
data/README.md
CHANGED
|
@@ -49,7 +49,7 @@ Most parameters accept either a UUID or a human identifier (issue identifier lik
|
|
|
49
49
|
| Tool | Description |
|
|
50
50
|
|------|-------------|
|
|
51
51
|
| `get_issue` | Retrieve an issue by ID or identifier (e.g., `LIN-123`). Returns the issue plus its parent and direct children. |
|
|
52
|
-
| `list_issues` | List issues with filters (team, assignee, state, label, priority, project, cycle) and cursor pagination. |
|
|
52
|
+
| `list_issues` | List issues with filters (team, assignee, creator, state, open, label, priority, project, cycle), sort by priority, and cursor pagination. |
|
|
53
53
|
| `save_issue` | Create or update an issue. Accepts names for team, assignee, state, labels, project, cycle, and milestone. Relation params (`blocks`, `relatedTo`, `duplicateOf`) and `parentId` accept UUIDs or identifiers. On create, relations are appended; on update, they replace existing. Null clears nullable fields on update. |
|
|
54
54
|
|
|
55
55
|
### Comments
|
|
@@ -17,17 +17,20 @@ module LinearToonMcp
|
|
|
17
17
|
properties: {
|
|
18
18
|
assignee: {type: "string", description: 'User ID, name, email, or "me"'},
|
|
19
19
|
createdAt: {type: "string", description: "Created after: ISO-8601 date/duration (e.g., -P1D)"},
|
|
20
|
+
creator: {type: "string", description: 'User ID, name, email, or "me"'},
|
|
20
21
|
cursor: {type: "string", description: "Next page cursor"},
|
|
21
22
|
cycle: {type: "string", description: "Cycle name, number, or ID"},
|
|
22
23
|
delegate: {type: "string", description: "Agent name or ID"},
|
|
23
|
-
includeArchived: {type: "boolean", description: "Include archived items (default
|
|
24
|
+
includeArchived: {type: "boolean", description: "Include archived items (default false)"},
|
|
24
25
|
label: {type: "string", description: "Label name or ID"},
|
|
25
26
|
limit: {type: "integer", description: "Max results (default 50, max 250)"},
|
|
27
|
+
open: {type: "boolean", description: "true: only issues not completed, canceled, or duplicate"},
|
|
26
28
|
orderBy: {type: "string", description: "createdAt or updatedAt (default updatedAt)", enum: ["createdAt", "updatedAt"]},
|
|
27
29
|
parentId: {type: "string", description: "Parent issue ID"},
|
|
28
30
|
priority: {type: "integer", description: "0=None, 1=Urgent, 2=High, 3=Normal, 4=Low"},
|
|
29
31
|
project: {type: "string", description: "Project name or ID"},
|
|
30
32
|
query: {type: "string", description: "Search issue title or description"},
|
|
33
|
+
sort: {type: "string", description: "priority: Urgent first, no priority last. Not combinable with orderBy", enum: ["priority"]},
|
|
31
34
|
state: {type: "string", description: "State name or ID"},
|
|
32
35
|
team: {type: "string", description: "Team name or ID"},
|
|
33
36
|
updatedAt: {type: "string", description: "Updated after: ISO-8601 date/duration (e.g., -P1D)"}
|
|
@@ -36,8 +39,8 @@ module LinearToonMcp
|
|
|
36
39
|
)
|
|
37
40
|
|
|
38
41
|
QUERY = <<~GRAPHQL
|
|
39
|
-
query($filter: IssueFilter, $first: Int, $after: String, $orderBy: PaginationOrderBy, $includeArchived: Boolean) {
|
|
40
|
-
issues(filter: $filter, first: $first, after: $after, orderBy: $orderBy, includeArchived: $includeArchived) {
|
|
42
|
+
query($filter: IssueFilter, $first: Int, $after: String, $orderBy: PaginationOrderBy, $sort: [IssueSortInput!], $includeArchived: Boolean) {
|
|
43
|
+
issues(filter: $filter, first: $first, after: $after, orderBy: $orderBy, sort: $sort, includeArchived: $includeArchived) {
|
|
41
44
|
nodes {
|
|
42
45
|
id
|
|
43
46
|
identifier
|
|
@@ -63,23 +66,30 @@ module LinearToonMcp
|
|
|
63
66
|
|
|
64
67
|
UUID_RE = Resolvers::UUID_RE
|
|
65
68
|
NUMERIC_RE = Resolvers::NUMERIC_RE
|
|
69
|
+
CLOSED_STATE_TYPES = %w[completed canceled duplicate].freeze
|
|
66
70
|
|
|
67
71
|
# standard:disable Naming/VariableName
|
|
68
|
-
def perform(assignee: nil, createdAt: nil, cursor: nil, cycle: nil,
|
|
69
|
-
delegate: nil, includeArchived: nil, label: nil, limit: nil, orderBy: nil,
|
|
70
|
-
parentId: nil, priority: nil, project: nil, query: nil, state: nil,
|
|
72
|
+
def perform(assignee: nil, createdAt: nil, creator: nil, cursor: nil, cycle: nil,
|
|
73
|
+
delegate: nil, includeArchived: nil, label: nil, limit: nil, open: nil, orderBy: nil,
|
|
74
|
+
parentId: nil, priority: nil, project: nil, query: nil, sort: nil, state: nil,
|
|
71
75
|
team: nil, updatedAt: nil)
|
|
76
|
+
raise Error, "Use either orderBy or sort, not both" if orderBy && sort
|
|
77
|
+
|
|
72
78
|
filter = build_filter(
|
|
73
|
-
assignee:, team:, project:, state:, label:,
|
|
79
|
+
assignee:, creator:, team:, project:, state:, open:, label:,
|
|
74
80
|
priority:, parentId:, cycle:, delegate:,
|
|
75
81
|
query:, createdAt:, updatedAt:
|
|
76
82
|
)
|
|
77
83
|
|
|
78
84
|
variables = {
|
|
79
85
|
first: (limit || 50).clamp(1, 250),
|
|
80
|
-
|
|
81
|
-
includeArchived: includeArchived != false
|
|
86
|
+
includeArchived: includeArchived == true
|
|
82
87
|
}
|
|
88
|
+
if sort
|
|
89
|
+
variables[:sort] = [{priority: {order: "Descending"}}]
|
|
90
|
+
else
|
|
91
|
+
variables[:orderBy] = orderBy || "updatedAt"
|
|
92
|
+
end
|
|
83
93
|
variables[:filter] = filter unless filter.empty?
|
|
84
94
|
variables[:after] = cursor if cursor
|
|
85
95
|
|
|
@@ -89,14 +99,16 @@ module LinearToonMcp
|
|
|
89
99
|
|
|
90
100
|
private
|
|
91
101
|
|
|
92
|
-
def build_filter(assignee:, team:, project:, state:, label:,
|
|
102
|
+
def build_filter(assignee:, creator:, team:, project:, state:, open:, label:,
|
|
93
103
|
priority:, parentId:, cycle:, delegate:,
|
|
94
104
|
query:, createdAt:, updatedAt:)
|
|
95
105
|
filter = {}
|
|
96
|
-
filter[:assignee] =
|
|
106
|
+
filter[:assignee] = user_filter(assignee) if assignee
|
|
107
|
+
filter[:creator] = user_filter(creator) if creator
|
|
97
108
|
filter[:team] = name_or_id(team) if team
|
|
98
109
|
filter[:project] = name_or_id(project) if project
|
|
99
110
|
filter[:state] = name_or_id(state) if state
|
|
111
|
+
filter[:state] = filter.fetch(:state, {}).merge(type: {nin: CLOSED_STATE_TYPES}) if open
|
|
100
112
|
filter[:labels] = {some: name_or_id(label)} if label
|
|
101
113
|
filter[:priority] = {eq: priority} if priority
|
|
102
114
|
filter[:parent] = {id: {eq: parentId}} if parentId
|
|
@@ -114,7 +126,7 @@ module LinearToonMcp
|
|
|
114
126
|
end
|
|
115
127
|
# standard:enable Naming/VariableName
|
|
116
128
|
|
|
117
|
-
def
|
|
129
|
+
def user_filter(value)
|
|
118
130
|
return {isMe: {eq: true}} if value == "me"
|
|
119
131
|
return {id: {eq: value}} if value.match?(UUID_RE)
|
|
120
132
|
return {email: {eq: value}} if value.include?("@")
|