@agllama/mcp 0.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -0
  3. package/dist/api-client.d.ts +71 -0
  4. package/dist/api-client.d.ts.map +1 -0
  5. package/dist/api-client.js +315 -0
  6. package/dist/api-client.js.map +1 -0
  7. package/dist/index.d.ts +3 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +18 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/server.d.ts +4 -0
  12. package/dist/server.d.ts.map +1 -0
  13. package/dist/server.js +495 -0
  14. package/dist/server.js.map +1 -0
  15. package/dist/tools/backlog.d.ts +16 -0
  16. package/dist/tools/backlog.d.ts.map +1 -0
  17. package/dist/tools/backlog.js +59 -0
  18. package/dist/tools/backlog.js.map +1 -0
  19. package/dist/tools/boards.d.ts +62 -0
  20. package/dist/tools/boards.d.ts.map +1 -0
  21. package/dist/tools/boards.js +158 -0
  22. package/dist/tools/boards.js.map +1 -0
  23. package/dist/tools/comments.d.ts +82 -0
  24. package/dist/tools/comments.d.ts.map +1 -0
  25. package/dist/tools/comments.js +162 -0
  26. package/dist/tools/comments.js.map +1 -0
  27. package/dist/tools/connect.d.ts +7 -0
  28. package/dist/tools/connect.d.ts.map +1 -0
  29. package/dist/tools/connect.js +61 -0
  30. package/dist/tools/connect.js.map +1 -0
  31. package/dist/tools/context.d.ts +16 -0
  32. package/dist/tools/context.d.ts.map +1 -0
  33. package/dist/tools/context.js +79 -0
  34. package/dist/tools/context.js.map +1 -0
  35. package/dist/tools/help.d.ts +13 -0
  36. package/dist/tools/help.d.ts.map +1 -0
  37. package/dist/tools/help.js +421 -0
  38. package/dist/tools/help.js.map +1 -0
  39. package/dist/tools/index.d.ts +17 -0
  40. package/dist/tools/index.d.ts.map +1 -0
  41. package/dist/tools/index.js +17 -0
  42. package/dist/tools/index.js.map +1 -0
  43. package/dist/tools/issueLinks.d.ts +45 -0
  44. package/dist/tools/issueLinks.d.ts.map +1 -0
  45. package/dist/tools/issueLinks.js +90 -0
  46. package/dist/tools/issueLinks.js.map +1 -0
  47. package/dist/tools/issues.d.ts +127 -0
  48. package/dist/tools/issues.d.ts.map +1 -0
  49. package/dist/tools/issues.js +262 -0
  50. package/dist/tools/issues.js.map +1 -0
  51. package/dist/tools/labels.d.ts +56 -0
  52. package/dist/tools/labels.d.ts.map +1 -0
  53. package/dist/tools/labels.js +123 -0
  54. package/dist/tools/labels.js.map +1 -0
  55. package/dist/tools/members.d.ts +13 -0
  56. package/dist/tools/members.d.ts.map +1 -0
  57. package/dist/tools/members.js +43 -0
  58. package/dist/tools/members.js.map +1 -0
  59. package/dist/tools/organizations.d.ts +35 -0
  60. package/dist/tools/organizations.d.ts.map +1 -0
  61. package/dist/tools/organizations.js +116 -0
  62. package/dist/tools/organizations.js.map +1 -0
  63. package/dist/tools/projects.d.ts +67 -0
  64. package/dist/tools/projects.d.ts.map +1 -0
  65. package/dist/tools/projects.js +165 -0
  66. package/dist/tools/projects.js.map +1 -0
  67. package/dist/tools/search.d.ts +34 -0
  68. package/dist/tools/search.d.ts.map +1 -0
  69. package/dist/tools/search.js +62 -0
  70. package/dist/tools/search.js.map +1 -0
  71. package/dist/tools/sprints.d.ts +141 -0
  72. package/dist/tools/sprints.d.ts.map +1 -0
  73. package/dist/tools/sprints.js +380 -0
  74. package/dist/tools/sprints.js.map +1 -0
  75. package/dist/tools/status.d.ts +22 -0
  76. package/dist/tools/status.d.ts.map +1 -0
  77. package/dist/tools/status.js +44 -0
  78. package/dist/tools/status.js.map +1 -0
  79. package/dist/tools/workflows.d.ts +137 -0
  80. package/dist/tools/workflows.d.ts.map +1 -0
  81. package/dist/tools/workflows.js +355 -0
  82. package/dist/tools/workflows.js.map +1 -0
  83. package/dist/types.d.ts +312 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +5 -0
  86. package/dist/types.js.map +1 -0
  87. package/package.json +63 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AG-Llama Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,249 @@
1
+ # @agllama/mcp
2
+
3
+ MCP (Model Context Protocol) server for AG-Llama project management. Connect Claude Code and other MCP-compatible AI tools to your agile workflow.
4
+
5
+ ## Quick Start
6
+
7
+ ### 1. Get Your API Key
8
+
9
+ 1. Sign up at [agllama-web.onrender.com](https://agllama-web.onrender.com)
10
+ 2. Go to Settings > API Keys
11
+ 3. Click "Generate API Key"
12
+ 4. Copy the key (it's only shown once!)
13
+
14
+ ### 2. Configure Claude Code
15
+
16
+ Add to your project's `.mcp.json` or `~/.claude.json`:
17
+
18
+ ```json
19
+ {
20
+ "mcpServers": {
21
+ "llama": {
22
+ "command": "npx",
23
+ "args": ["-y", "@agllama/mcp"],
24
+ "env": {
25
+ "LLAMA_API_URL": "https://agllama-api.onrender.com",
26
+ "LLAMA_API_KEY": "your-api-key-here"
27
+ }
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ Or use the Claude CLI:
34
+
35
+ ```bash
36
+ claude mcp add llama -- npx -y @agllama/mcp
37
+ ```
38
+
39
+ Then set the environment variables:
40
+
41
+ ```bash
42
+ export LLAMA_API_URL=https://agllama-api.onrender.com
43
+ export LLAMA_API_KEY=llm_xxxxxxxx
44
+ ```
45
+
46
+ ### 3. Test the Connection
47
+
48
+ In Claude Code, try:
49
+
50
+ ```
51
+ Use llama to test the connection
52
+ ```
53
+
54
+ ## Self-Hosted Setup
55
+
56
+ If you're running your own AG-Llama instance:
57
+
58
+ ```json
59
+ {
60
+ "mcpServers": {
61
+ "llama": {
62
+ "command": "npx",
63
+ "args": ["-y", "@agllama/mcp"],
64
+ "env": {
65
+ "LLAMA_API_URL": "http://localhost:3001",
66
+ "LLAMA_API_KEY": "your-api-key-here"
67
+ }
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ ## Available Tools
74
+
75
+ ### Connection & Context
76
+
77
+ | Tool | Description |
78
+ |------|-------------|
79
+ | `llama_connect` | Test connection and get user info |
80
+ | `llama_context` | Get project snapshot (sprint, backlog, statuses, members) |
81
+ | `llama_help` | Get help on available tools |
82
+
83
+ ### Organizations
84
+
85
+ | Tool | Description |
86
+ |------|-------------|
87
+ | `llama_list_organizations` | List all organizations you have access to |
88
+ | `llama_get_organization` | Get organization details by slug |
89
+ | `llama_create_organization` | Create a new organization |
90
+
91
+ ### Projects
92
+
93
+ | Tool | Description |
94
+ |------|-------------|
95
+ | `llama_list_projects` | List all projects in an organization |
96
+ | `llama_get_project` | Get project details by key |
97
+ | `llama_create_project` | Create a new project |
98
+ | `llama_update_project` | Update project name/description |
99
+
100
+ ### Issues
101
+
102
+ | Tool | Description |
103
+ |------|-------------|
104
+ | `llama_get_issue` | Get full issue details by key |
105
+ | `llama_create_issue` | Create a new issue (EPIC, STORY, TASK, BUG, SUBTASK) |
106
+ | `llama_update_issue` | Update issue fields |
107
+ | `llama_delete_issue` | Soft-delete an issue |
108
+ | `llama_update_status` | Move issue to different status |
109
+
110
+ ### Issue Links
111
+
112
+ | Tool | Description |
113
+ |------|-------------|
114
+ | `llama_create_issue_link` | Link issues (BLOCKS, RELATES_TO, DUPLICATES, etc.) |
115
+ | `llama_delete_issue_link` | Remove an issue link |
116
+
117
+ ### Boards
118
+
119
+ | Tool | Description |
120
+ |------|-------------|
121
+ | `llama_list_boards` | List all boards in a project |
122
+ | `llama_get_board` | Get board with columns and issues |
123
+ | `llama_move_issue_on_board` | Move issue between columns |
124
+
125
+ ### Backlog & Sprints
126
+
127
+ | Tool | Description |
128
+ |------|-------------|
129
+ | `llama_get_backlog` | Get all issues not in a sprint |
130
+ | `llama_list_sprints` | List all sprints |
131
+ | `llama_get_sprint` | Get sprint details |
132
+ | `llama_create_sprint` | Create a new sprint |
133
+ | `llama_start_sprint` | Start a planned sprint |
134
+ | `llama_complete_sprint` | Complete an active sprint |
135
+ | `llama_update_sprint` | Update sprint name/goal/dates |
136
+ | `llama_delete_sprint` | Delete a sprint |
137
+ | `llama_add_to_sprint` | Move issues to/from sprint |
138
+
139
+ ### Comments
140
+
141
+ | Tool | Description |
142
+ |------|-------------|
143
+ | `llama_list_comments` | List comments on an issue |
144
+ | `llama_add_comment` | Add a comment to an issue |
145
+ | `llama_update_comment` | Update a comment |
146
+ | `llama_delete_comment` | Delete a comment |
147
+
148
+ ### Labels
149
+
150
+ | Tool | Description |
151
+ |------|-------------|
152
+ | `llama_list_labels` | List all labels in a project |
153
+ | `llama_create_label` | Create a new label |
154
+ | `llama_delete_label` | Delete a label |
155
+
156
+ ### Members
157
+
158
+ | Tool | Description |
159
+ |------|-------------|
160
+ | `llama_list_members` | List organization members |
161
+
162
+ ### Workflows
163
+
164
+ | Tool | Description |
165
+ |------|-------------|
166
+ | `llama_list_workflows` | List available Claude workflows |
167
+ | `llama_get_workflow` | Get workflow details |
168
+ | `llama_create_workflow` | Create a reusable workflow |
169
+ | `llama_update_workflow` | Update a workflow |
170
+ | `llama_run_workflow` | Execute a workflow |
171
+ | `llama_suggest_workflow` | Find workflows matching an intent |
172
+
173
+ ### Search
174
+
175
+ | Tool | Description |
176
+ |------|-------------|
177
+ | `llama_search` | Search issues with filters |
178
+
179
+ ## Usage Examples
180
+
181
+ ### Get Project Overview
182
+
183
+ ```
184
+ Use llama to get the context for demo-org/PROJ
185
+ ```
186
+
187
+ ### Create an Issue
188
+
189
+ ```
190
+ Use llama to create a task in demo-org/PROJ:
191
+ - Summary: "Add user authentication"
192
+ - Priority: HIGH
193
+ - Description: "Implement JWT-based auth with refresh tokens"
194
+ ```
195
+
196
+ ### Manage Sprints
197
+
198
+ ```
199
+ Use llama to show me the backlog for demo-org/PROJ, then create a sprint and add the top 3 issues to it
200
+ ```
201
+
202
+ ### Search Issues
203
+
204
+ ```
205
+ Use llama to find all high-priority bugs in demo-org
206
+ ```
207
+
208
+ ### Use Workflows
209
+
210
+ ```
211
+ Use llama to suggest a workflow for "sprint planning"
212
+ ```
213
+
214
+ ## Environment Variables
215
+
216
+ | Variable | Required | Description |
217
+ |----------|----------|-------------|
218
+ | `LLAMA_API_URL` | Yes | URL of your AG-Llama API |
219
+ | `LLAMA_API_KEY` | Yes | Your API key from Settings |
220
+
221
+ ## Development
222
+
223
+ ```bash
224
+ # Clone the repo
225
+ git clone https://github.com/willsower/JiraKiller.git
226
+ cd JiraKiller/packages/mcp-server
227
+
228
+ # Install dependencies
229
+ pnpm install
230
+
231
+ # Run in development mode
232
+ pnpm dev
233
+
234
+ # Build
235
+ pnpm build
236
+
237
+ # Test with MCP Inspector
238
+ npx @modelcontextprotocol/inspector npx tsx src/index.ts
239
+ ```
240
+
241
+ ## Links
242
+
243
+ - [AG-Llama Web App](https://agllama-web.onrender.com)
244
+ - [GitHub Repository](https://github.com/willsower/JiraKiller)
245
+ - [Report Issues](https://github.com/willsower/JiraKiller/issues)
246
+
247
+ ## License
248
+
249
+ MIT
@@ -0,0 +1,71 @@
1
+ import { MCPContextResponse, MCPUserInfo, MCPIssueDetail, MCPIssueSummary, MCPSprintDetail, CreateIssueInput, UpdateIssueInput, CreateSprintInput, SearchFilters, SearchResult, MCPOrganization, CreateOrganizationInput, MCPProject, CreateProjectInput, UpdateProjectInput, MCPBoard, MoveIssueInput, MCPComment, CreateCommentInput, MCPLabel, CreateLabelInput, MCPMember, MCPIssueLink, CreateIssueLinkInput, StartSprintInput, CompleteSprintInput, MCPWorkflowSummary, MCPWorkflowDetail, MCPSuggestedWorkflow, MCPWorkflowExecution, CreateClaudeWorkflowInput, UpdateClaudeWorkflowInput } from './types.js';
2
+ export declare class LlamaApiError extends Error {
3
+ statusCode: number;
4
+ constructor(statusCode: number, message: string);
5
+ }
6
+ export declare class LlamaApiClient {
7
+ private baseUrl;
8
+ private apiKey;
9
+ constructor(baseUrl: string, apiKey: string);
10
+ private request;
11
+ testConnection(): Promise<MCPUserInfo>;
12
+ getProjectContext(orgSlug: string, projectKey: string): Promise<MCPContextResponse>;
13
+ getProjectContextDoc(orgSlug: string, projectKey: string): Promise<{
14
+ content: string;
15
+ updatedAt: string | null;
16
+ updatedBy: string | null;
17
+ }>;
18
+ updateProjectContextDoc(orgSlug: string, projectKey: string, content: string): Promise<{
19
+ content: string;
20
+ updatedAt: string;
21
+ updatedBy: string;
22
+ }>;
23
+ getIssue(orgSlug: string, projectKey: string, issueKey: string): Promise<MCPIssueDetail>;
24
+ createIssue(orgSlug: string, projectKey: string, input: CreateIssueInput): Promise<MCPIssueDetail>;
25
+ updateIssue(orgSlug: string, projectKey: string, issueKey: string, input: UpdateIssueInput): Promise<MCPIssueDetail>;
26
+ deleteIssue(orgSlug: string, projectKey: string, issueKey: string): Promise<void>;
27
+ listSprints(orgSlug: string, projectKey: string): Promise<MCPSprintDetail[]>;
28
+ createSprint(orgSlug: string, projectKey: string, input: CreateSprintInput): Promise<MCPSprintDetail>;
29
+ addIssuesToSprint(orgSlug: string, projectKey: string, issueKeys: string[], sprintId: string | null): Promise<MCPIssueSummary[]>;
30
+ searchIssues(orgSlug: string, query: string, filters?: SearchFilters): Promise<SearchResult>;
31
+ listOrganizations(): Promise<MCPOrganization[]>;
32
+ getOrganization(slug: string): Promise<MCPOrganization>;
33
+ createOrganization(input: CreateOrganizationInput): Promise<MCPOrganization>;
34
+ listProjects(orgSlug: string): Promise<MCPProject[]>;
35
+ getProject(orgSlug: string, projectKey: string): Promise<MCPProject>;
36
+ createProject(orgSlug: string, input: CreateProjectInput): Promise<MCPProject>;
37
+ updateProject(orgSlug: string, projectKey: string, input: UpdateProjectInput): Promise<MCPProject>;
38
+ listBoards(orgSlug: string, projectKey: string): Promise<MCPBoard[]>;
39
+ getBoard(orgSlug: string, projectKey: string, boardId: string): Promise<MCPBoard>;
40
+ moveIssueOnBoard(orgSlug: string, projectKey: string, boardId: string, input: MoveIssueInput): Promise<void>;
41
+ getBacklog(orgSlug: string, projectKey: string): Promise<{
42
+ issues: MCPIssueSummary[];
43
+ total: number;
44
+ }>;
45
+ listComments(orgSlug: string, projectKey: string, issueKey: string): Promise<MCPComment[]>;
46
+ createComment(orgSlug: string, projectKey: string, issueKey: string, input: CreateCommentInput): Promise<MCPComment>;
47
+ updateComment(orgSlug: string, projectKey: string, issueKey: string, commentId: string, content: string): Promise<MCPComment>;
48
+ deleteComment(orgSlug: string, projectKey: string, issueKey: string, commentId: string): Promise<void>;
49
+ listLabels(orgSlug: string, projectKey: string): Promise<MCPLabel[]>;
50
+ createLabel(orgSlug: string, projectKey: string, input: CreateLabelInput): Promise<MCPLabel>;
51
+ deleteLabel(orgSlug: string, projectKey: string, labelName: string): Promise<void>;
52
+ listMembers(orgSlug: string): Promise<MCPMember[]>;
53
+ listIssueLinks(orgSlug: string, projectKey: string, issueKey: string): Promise<MCPIssueLink[]>;
54
+ createIssueLink(orgSlug: string, projectKey: string, issueKey: string, input: CreateIssueLinkInput): Promise<MCPIssueLink>;
55
+ deleteIssueLink(orgSlug: string, projectKey: string, issueKey: string, linkId: string): Promise<void>;
56
+ startSprint(sprintId: string, input?: StartSprintInput): Promise<MCPSprintDetail>;
57
+ completeSprint(sprintId: string, input?: CompleteSprintInput): Promise<MCPSprintDetail>;
58
+ getSprint(sprintId: string): Promise<MCPSprintDetail>;
59
+ updateSprint(sprintId: string, input: Partial<CreateSprintInput>): Promise<MCPSprintDetail>;
60
+ deleteSprint(sprintId: string): Promise<void>;
61
+ listClaudeWorkflows(orgSlug: string, projectKey: string): Promise<MCPWorkflowSummary[]>;
62
+ getClaudeWorkflow(orgSlug: string, projectKey: string, workflowId: string): Promise<MCPWorkflowDetail>;
63
+ createClaudeWorkflow(orgSlug: string, projectKey: string, input: CreateClaudeWorkflowInput): Promise<MCPWorkflowDetail>;
64
+ updateClaudeWorkflow(orgSlug: string, projectKey: string, workflowId: string, input: UpdateClaudeWorkflowInput): Promise<MCPWorkflowDetail>;
65
+ deleteClaudeWorkflow(orgSlug: string, projectKey: string, workflowId: string): Promise<void>;
66
+ suggestClaudeWorkflows(orgSlug: string, projectKey: string, intent: string): Promise<MCPSuggestedWorkflow[]>;
67
+ runClaudeWorkflow(orgSlug: string, projectKey: string, workflowId: string, parameters: Record<string, string>): Promise<MCPWorkflowExecution>;
68
+ }
69
+ export declare function getApiClient(): LlamaApiClient;
70
+ export declare function resetApiClient(): void;
71
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,315 @@
1
+ export class LlamaApiError extends Error {
2
+ statusCode;
3
+ constructor(statusCode, message) {
4
+ super(message);
5
+ this.statusCode = statusCode;
6
+ this.name = 'LlamaApiError';
7
+ }
8
+ }
9
+ export class LlamaApiClient {
10
+ baseUrl;
11
+ apiKey;
12
+ constructor(baseUrl, apiKey) {
13
+ this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
14
+ this.apiKey = apiKey;
15
+ }
16
+ async request(method, path, body) {
17
+ const url = `${this.baseUrl}${path}`;
18
+ const headers = {
19
+ 'X-API-Key': this.apiKey,
20
+ 'Content-Type': 'application/json',
21
+ };
22
+ const response = await fetch(url, {
23
+ method,
24
+ headers,
25
+ body: body ? JSON.stringify(body) : undefined,
26
+ });
27
+ // Handle 204 No Content responses (e.g., DELETE operations)
28
+ if (response.status === 204) {
29
+ return undefined;
30
+ }
31
+ const json = (await response.json());
32
+ if (!response.ok || !json.success) {
33
+ throw new LlamaApiError(response.status, json.error || `Request failed with status ${response.status}`);
34
+ }
35
+ return json.data;
36
+ }
37
+ // ============================================
38
+ // Connection
39
+ // ============================================
40
+ async testConnection() {
41
+ return this.request('GET', '/api/auth/me');
42
+ }
43
+ // ============================================
44
+ // Project Context
45
+ // ============================================
46
+ async getProjectContext(orgSlug, projectKey) {
47
+ return this.request('GET', `/api/organizations/${orgSlug}/projects/${projectKey}/mcp/context`);
48
+ }
49
+ async getProjectContextDoc(orgSlug, projectKey) {
50
+ return this.request('GET', `/api/organizations/${orgSlug}/projects/${projectKey}/mcp/project-context`);
51
+ }
52
+ async updateProjectContextDoc(orgSlug, projectKey, content) {
53
+ return this.request('PUT', `/api/organizations/${orgSlug}/projects/${projectKey}/mcp/project-context`, { content });
54
+ }
55
+ // ============================================
56
+ // Issues
57
+ // ============================================
58
+ async getIssue(orgSlug, projectKey, issueKey) {
59
+ return this.request('GET', `/api/organizations/${orgSlug}/projects/${projectKey}/issues/${issueKey}`);
60
+ }
61
+ async createIssue(orgSlug, projectKey, input) {
62
+ return this.request('POST', `/api/organizations/${orgSlug}/projects/${projectKey}/issues`, input);
63
+ }
64
+ async updateIssue(orgSlug, projectKey, issueKey, input) {
65
+ return this.request('PATCH', `/api/organizations/${orgSlug}/projects/${projectKey}/issues/${issueKey}`, input);
66
+ }
67
+ async deleteIssue(orgSlug, projectKey, issueKey) {
68
+ await this.request('DELETE', `/api/organizations/${orgSlug}/projects/${projectKey}/issues/${issueKey}`);
69
+ }
70
+ // ============================================
71
+ // Sprints
72
+ // ============================================
73
+ async listSprints(orgSlug, projectKey) {
74
+ // Get sprints through the sprint-actions endpoint
75
+ const result = await this.request('GET', `/api/organizations/${orgSlug}/projects/${projectKey}/mcp/context`);
76
+ // The context already includes sprint info, but we may need dedicated sprint list
77
+ // For now, extract from context
78
+ const context = result;
79
+ const sprints = [];
80
+ if (context.activeSprint) {
81
+ sprints.push({
82
+ ...context.activeSprint,
83
+ status: 'ACTIVE',
84
+ issueCount: context.activeSprint.issues.length,
85
+ completedCount: context.activeSprint.issues.filter((i) => i.statusCategory === 'DONE').length,
86
+ });
87
+ }
88
+ for (const pending of context.pendingSprints) {
89
+ sprints.push({
90
+ id: pending.id,
91
+ name: pending.name,
92
+ goal: null,
93
+ startDate: null,
94
+ endDate: null,
95
+ status: 'PLANNED',
96
+ issues: [],
97
+ issueCount: 0,
98
+ completedCount: 0,
99
+ });
100
+ }
101
+ return sprints;
102
+ }
103
+ async createSprint(orgSlug, projectKey, input) {
104
+ return this.request('POST', `/api/organizations/${orgSlug}/projects/${projectKey}/sprints`, input);
105
+ }
106
+ async addIssuesToSprint(orgSlug, projectKey, issueKeys, sprintId) {
107
+ // Update each issue's sprint
108
+ const results = [];
109
+ for (const issueKey of issueKeys) {
110
+ const issue = await this.updateIssue(orgSlug, projectKey, issueKey, {
111
+ sprintId,
112
+ });
113
+ results.push({
114
+ id: issue.id,
115
+ key: issue.key,
116
+ summary: issue.summary,
117
+ type: issue.type,
118
+ status: issue.status,
119
+ statusCategory: issue.statusCategory,
120
+ priority: issue.priority,
121
+ assignee: issue.assignee,
122
+ estimate: issue.estimate,
123
+ });
124
+ }
125
+ return results;
126
+ }
127
+ // ============================================
128
+ // Search
129
+ // ============================================
130
+ async searchIssues(orgSlug, query, filters) {
131
+ const params = new URLSearchParams();
132
+ params.set('q', query);
133
+ if (filters?.type)
134
+ params.set('type', filters.type);
135
+ if (filters?.priority)
136
+ params.set('priority', filters.priority);
137
+ if (filters?.status)
138
+ params.set('status', filters.status);
139
+ if (filters?.assigneeId)
140
+ params.set('assigneeId', filters.assigneeId);
141
+ if (filters?.sprintId)
142
+ params.set('sprintId', filters.sprintId);
143
+ if (filters?.labels?.length)
144
+ params.set('labels', filters.labels.join(','));
145
+ return this.request('GET', `/api/organizations/${orgSlug}/search?${params.toString()}`);
146
+ }
147
+ // ============================================
148
+ // Organizations
149
+ // ============================================
150
+ async listOrganizations() {
151
+ return this.request('GET', '/api/organizations');
152
+ }
153
+ async getOrganization(slug) {
154
+ return this.request('GET', `/api/organizations/${slug}`);
155
+ }
156
+ async createOrganization(input) {
157
+ return this.request('POST', '/api/organizations', input);
158
+ }
159
+ // ============================================
160
+ // Projects
161
+ // ============================================
162
+ async listProjects(orgSlug) {
163
+ return this.request('GET', `/api/organizations/${orgSlug}/projects`);
164
+ }
165
+ async getProject(orgSlug, projectKey) {
166
+ return this.request('GET', `/api/organizations/${orgSlug}/projects/${projectKey}`);
167
+ }
168
+ async createProject(orgSlug, input) {
169
+ return this.request('POST', `/api/organizations/${orgSlug}/projects`, input);
170
+ }
171
+ async updateProject(orgSlug, projectKey, input) {
172
+ return this.request('PATCH', `/api/organizations/${orgSlug}/projects/${projectKey}`, input);
173
+ }
174
+ // ============================================
175
+ // Boards
176
+ // ============================================
177
+ async listBoards(orgSlug, projectKey) {
178
+ return this.request('GET', `/api/organizations/${orgSlug}/projects/${projectKey}/boards`);
179
+ }
180
+ async getBoard(orgSlug, projectKey, boardId) {
181
+ return this.request('GET', `/api/organizations/${orgSlug}/projects/${projectKey}/boards/${boardId}`);
182
+ }
183
+ async moveIssueOnBoard(orgSlug, projectKey, boardId, input) {
184
+ await this.request('POST', `/api/organizations/${orgSlug}/projects/${projectKey}/boards/${boardId}/move-issue`, input);
185
+ }
186
+ // ============================================
187
+ // Backlog
188
+ // ============================================
189
+ async getBacklog(orgSlug, projectKey) {
190
+ // Make raw request to handle paginated response format
191
+ const url = `${this.baseUrl}/api/organizations/${orgSlug}/projects/${projectKey}/backlog`;
192
+ const headers = {
193
+ 'X-API-Key': this.apiKey,
194
+ 'Content-Type': 'application/json',
195
+ };
196
+ const response = await fetch(url, { method: 'GET', headers });
197
+ const json = (await response.json());
198
+ if (!response.ok || !json.success) {
199
+ throw new LlamaApiError(response.status, json.error || `Request failed with status ${response.status}`);
200
+ }
201
+ // Backend uses sendPaginated which returns { success, data, pagination }
202
+ return {
203
+ issues: json.data ?? [],
204
+ total: json.pagination?.total ?? json.data?.length ?? 0,
205
+ };
206
+ }
207
+ // ============================================
208
+ // Comments
209
+ // ============================================
210
+ async listComments(orgSlug, projectKey, issueKey) {
211
+ return this.request('GET', `/api/organizations/${orgSlug}/projects/${projectKey}/issues/${issueKey}/comments`);
212
+ }
213
+ async createComment(orgSlug, projectKey, issueKey, input) {
214
+ return this.request('POST', `/api/organizations/${orgSlug}/projects/${projectKey}/issues/${issueKey}/comments`, input);
215
+ }
216
+ async updateComment(orgSlug, projectKey, issueKey, commentId, content) {
217
+ return this.request('PATCH', `/api/organizations/${orgSlug}/projects/${projectKey}/issues/${issueKey}/comments/${commentId}`, { content });
218
+ }
219
+ async deleteComment(orgSlug, projectKey, issueKey, commentId) {
220
+ await this.request('DELETE', `/api/organizations/${orgSlug}/projects/${projectKey}/issues/${issueKey}/comments/${commentId}`);
221
+ }
222
+ // ============================================
223
+ // Labels
224
+ // ============================================
225
+ async listLabels(orgSlug, projectKey) {
226
+ return this.request('GET', `/api/organizations/${orgSlug}/projects/${projectKey}/labels`);
227
+ }
228
+ async createLabel(orgSlug, projectKey, input) {
229
+ return this.request('POST', `/api/organizations/${orgSlug}/projects/${projectKey}/labels`, input);
230
+ }
231
+ async deleteLabel(orgSlug, projectKey, labelName) {
232
+ await this.request('DELETE', `/api/organizations/${orgSlug}/projects/${projectKey}/labels/${encodeURIComponent(labelName)}`);
233
+ }
234
+ // ============================================
235
+ // Members
236
+ // ============================================
237
+ async listMembers(orgSlug) {
238
+ return this.request('GET', `/api/organizations/${orgSlug}/members`);
239
+ }
240
+ // ============================================
241
+ // Issue Links
242
+ // ============================================
243
+ async listIssueLinks(orgSlug, projectKey, issueKey) {
244
+ // Links are returned as part of issue details
245
+ const issue = await this.getIssue(orgSlug, projectKey, issueKey);
246
+ return issue.links ?? [];
247
+ }
248
+ async createIssueLink(orgSlug, projectKey, issueKey, input) {
249
+ return this.request('POST', `/api/organizations/${orgSlug}/projects/${projectKey}/issues/${issueKey}/links`, {
250
+ targetIssueKey: input.targetIssueKey,
251
+ linkType: input.type, // Backend expects linkType, not type
252
+ });
253
+ }
254
+ async deleteIssueLink(orgSlug, projectKey, issueKey, linkId) {
255
+ await this.request('DELETE', `/api/organizations/${orgSlug}/projects/${projectKey}/issues/${issueKey}/links/${linkId}`);
256
+ }
257
+ // ============================================
258
+ // Sprint Actions
259
+ // ============================================
260
+ async startSprint(sprintId, input) {
261
+ return this.request('POST', `/api/sprints/${sprintId}/start`, input || {});
262
+ }
263
+ async completeSprint(sprintId, input) {
264
+ return this.request('POST', `/api/sprints/${sprintId}/complete`, input || {});
265
+ }
266
+ async getSprint(sprintId) {
267
+ return this.request('GET', `/api/sprints/${sprintId}`);
268
+ }
269
+ async updateSprint(sprintId, input) {
270
+ return this.request('PATCH', `/api/sprints/${sprintId}`, input);
271
+ }
272
+ async deleteSprint(sprintId) {
273
+ await this.request('DELETE', `/api/sprints/${sprintId}`);
274
+ }
275
+ // ============================================
276
+ // Claude Workflows
277
+ // ============================================
278
+ async listClaudeWorkflows(orgSlug, projectKey) {
279
+ return this.request('GET', `/api/organizations/${orgSlug}/projects/${projectKey}/claude-workflows`);
280
+ }
281
+ async getClaudeWorkflow(orgSlug, projectKey, workflowId) {
282
+ return this.request('GET', `/api/organizations/${orgSlug}/projects/${projectKey}/claude-workflows/${workflowId}`);
283
+ }
284
+ async createClaudeWorkflow(orgSlug, projectKey, input) {
285
+ return this.request('POST', `/api/organizations/${orgSlug}/projects/${projectKey}/claude-workflows`, input);
286
+ }
287
+ async updateClaudeWorkflow(orgSlug, projectKey, workflowId, input) {
288
+ return this.request('PATCH', `/api/organizations/${orgSlug}/projects/${projectKey}/claude-workflows/${workflowId}`, input);
289
+ }
290
+ async deleteClaudeWorkflow(orgSlug, projectKey, workflowId) {
291
+ await this.request('DELETE', `/api/organizations/${orgSlug}/projects/${projectKey}/claude-workflows/${workflowId}`);
292
+ }
293
+ async suggestClaudeWorkflows(orgSlug, projectKey, intent) {
294
+ return this.request('POST', `/api/organizations/${orgSlug}/projects/${projectKey}/claude-workflows/suggest`, { intent });
295
+ }
296
+ async runClaudeWorkflow(orgSlug, projectKey, workflowId, parameters) {
297
+ return this.request('POST', `/api/organizations/${orgSlug}/projects/${projectKey}/claude-workflows/${workflowId}/run`, { parameters });
298
+ }
299
+ }
300
+ let clientInstance = null;
301
+ export function getApiClient() {
302
+ if (!clientInstance) {
303
+ const apiUrl = process.env.LLAMA_API_URL;
304
+ const apiKey = process.env.LLAMA_API_KEY;
305
+ if (!apiUrl || !apiKey) {
306
+ throw new Error('LLAMA_API_URL and LLAMA_API_KEY environment variables are required');
307
+ }
308
+ clientInstance = new LlamaApiClient(apiUrl, apiKey);
309
+ }
310
+ return clientInstance;
311
+ }
312
+ export function resetApiClient() {
313
+ clientInstance = null;
314
+ }
315
+ //# sourceMappingURL=api-client.js.map