@shortcut/mcp 0.1.0 → 0.1.2
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.
- package/README.md +19 -24
- package/dist/index.js +39 -24
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -1,26 +1,7 @@
|
|
|
1
|
-
# @
|
|
2
|
-
|
|
3
|
-
> [!IMPORTANT]
|
|
4
|
-
> To use the MCP server, you need to first install the dependencies and run the build step.
|
|
5
|
-
|
|
6
|
-
## Installation
|
|
7
|
-
|
|
8
|
-
> First - install **bun** if needed: [Bun](https://bun.sh).
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
bun install
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## Build
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
bun run build
|
|
18
|
-
```
|
|
1
|
+
# @shortcut/mcp
|
|
19
2
|
|
|
20
3
|
## Usage
|
|
21
4
|
|
|
22
|
-
> Note: `mcp-server-shortcut` in the paths below refer to the folder name where you cloned this repo. If you used a different folder name, you'll need to use that instead.
|
|
23
|
-
|
|
24
5
|
### Windsurf
|
|
25
6
|
|
|
26
7
|
See the [official Windsurf docs](https://codeium.com/docs/windsurf/mcp) for more information.
|
|
@@ -33,9 +14,9 @@ See the [official Windsurf docs](https://codeium.com/docs/windsurf/mcp) for more
|
|
|
33
14
|
{
|
|
34
15
|
"mcpServers": {
|
|
35
16
|
"shortcut": {
|
|
36
|
-
"command": "
|
|
17
|
+
"command": "npx",
|
|
37
18
|
"args": [
|
|
38
|
-
"/
|
|
19
|
+
"@shortcut/mcp"
|
|
39
20
|
],
|
|
40
21
|
"env": {
|
|
41
22
|
"SHORTCUT_API_TOKEN": "<YOUR_SHORTCUT_API_TOKEN>"
|
|
@@ -56,9 +37,9 @@ See the [official Cursor docs](https://docs.cursor.com/context/model-context-pro
|
|
|
56
37
|
{
|
|
57
38
|
"mcpServers": {
|
|
58
39
|
"shortcut": {
|
|
59
|
-
"command": "
|
|
40
|
+
"command": "npx",
|
|
60
41
|
"args": [
|
|
61
|
-
"/
|
|
42
|
+
"@shortcut/mcp"
|
|
62
43
|
],
|
|
63
44
|
"env": {
|
|
64
45
|
"SHORTCUT_API_TOKEN": "<YOUR_SHORTCUT_API_TOKEN>"
|
|
@@ -66,4 +47,18 @@ See the [official Cursor docs](https://docs.cursor.com/context/model-context-pro
|
|
|
66
47
|
}
|
|
67
48
|
}
|
|
68
49
|
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Development
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm install
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Build
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm run build
|
|
69
64
|
```
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
2
|
-
// @bun
|
|
1
|
+
#!/usr/bin/env node
|
|
3
2
|
import { createRequire } from "node:module";
|
|
4
3
|
var __create = Object.create;
|
|
5
4
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -16457,8 +16456,8 @@ var require_lib = __commonJS((exports) => {
|
|
|
16457
16456
|
});
|
|
16458
16457
|
|
|
16459
16458
|
// package.json
|
|
16460
|
-
var name = "@
|
|
16461
|
-
var version = "0.
|
|
16459
|
+
var name = "@shortcut/mcp";
|
|
16460
|
+
var version = "0.1.0";
|
|
16462
16461
|
|
|
16463
16462
|
// node_modules/zod/lib/index.mjs
|
|
16464
16463
|
var util;
|
|
@@ -23692,11 +23691,13 @@ var formatStoryList = (stories, users) => {
|
|
|
23692
23691
|
return stories
|
|
23693
23692
|
.map(
|
|
23694
23693
|
(story) =>
|
|
23695
|
-
`- sc-${story.id}: ${story.name} (Type: ${story.story_type}, State: ${story.completed ? "Completed" : story.started ? "In Progress" : "Not Started"},
|
|
23696
|
-
.
|
|
23697
|
-
|
|
23698
|
-
|
|
23699
|
-
|
|
23694
|
+
`- sc-${story.id}: ${story.name} (Type: ${story.story_type}, State: ${story.completed ? "Completed" : story.started ? "In Progress" : "Not Started"}, Team: ${story.group_id ? `${story.group_id}` : "[None]"}, Epic: ${story.epic_id ? `${story.epic_id}` : "[None]"}, Iteration: ${story.iteration_id ? `${story.iteration_id}` : "[None]"}, Owners: ${
|
|
23695
|
+
story.owner_ids
|
|
23696
|
+
.map((ownerId) => users.get(ownerId))
|
|
23697
|
+
.filter((owner) => owner !== null)
|
|
23698
|
+
.map((owner) => `@${owner.profile.mention_name}`)
|
|
23699
|
+
.join(", ") || "[None]"
|
|
23700
|
+
})`,
|
|
23700
23701
|
)
|
|
23701
23702
|
.join(`
|
|
23702
23703
|
`);
|
|
@@ -23881,7 +23882,7 @@ class StoryTools extends BaseTools {
|
|
|
23881
23882
|
isUnstarted: is("unstarted"),
|
|
23882
23883
|
isUnestimated: is("unestimated"),
|
|
23883
23884
|
isOverdue: is("overdue"),
|
|
23884
|
-
isArchived: is("archived"),
|
|
23885
|
+
isArchived: is("archived").default(false),
|
|
23885
23886
|
isBlocker: is("blocking"),
|
|
23886
23887
|
isBlocked: is("blocked"),
|
|
23887
23888
|
hasComment: has("a comment"),
|
|
@@ -23970,19 +23971,20 @@ The story will be added to the default state for the workflow.
|
|
|
23970
23971
|
});
|
|
23971
23972
|
return this.toResult(`Unassigned current user as owner of story sc-${storyPublicId}`);
|
|
23972
23973
|
}
|
|
23974
|
+
createBranchName(currentUser, story) {
|
|
23975
|
+
return `${currentUser.mention_name}/sc-${story.id}/${story.name
|
|
23976
|
+
.toLowerCase()
|
|
23977
|
+
.replace(/\s+/g, "-")
|
|
23978
|
+
.replace(/[^\w\-]/g, "")}`.substring(0, 50);
|
|
23979
|
+
}
|
|
23973
23980
|
async getStoryBranchName(storyPublicId) {
|
|
23974
23981
|
const currentUser = await this.client.getCurrentUser();
|
|
23975
23982
|
if (!currentUser) throw new Error("Unable to find current user");
|
|
23976
23983
|
const story = await this.client.getStory(storyPublicId);
|
|
23977
23984
|
if (!story)
|
|
23978
23985
|
throw new Error(`Failed to retrieve Shortcut story with public ID: ${storyPublicId}`);
|
|
23979
|
-
const branchName =
|
|
23980
|
-
|
|
23981
|
-
.replace(/\s+/g, "-")
|
|
23982
|
-
.replace(/[^\w\-]/g, "")}`;
|
|
23983
|
-
return this.toResult(
|
|
23984
|
-
`Branch name for story sc-${storyPublicId}: ${branchName.substring(0, 50)}`,
|
|
23985
|
-
);
|
|
23986
|
+
const branchName = story.formatted_vcs_branch_name || this.createBranchName(currentUser, story);
|
|
23987
|
+
return this.toResult(`Branch name for story sc-${storyPublicId}: ${branchName}`);
|
|
23986
23988
|
}
|
|
23987
23989
|
async createStory({ name: name2, description, type, owner, epic, team, workflow }) {
|
|
23988
23990
|
if (!workflow && !team) throw new Error("Team or Workflow has to be specified");
|
|
@@ -24018,7 +24020,11 @@ ${formatStoryList(stories, users)}`);
|
|
|
24018
24020
|
const story = await this.client.getStory(storyPublicId);
|
|
24019
24021
|
if (!story)
|
|
24020
24022
|
throw new Error(`Failed to retrieve Shortcut story with public ID: ${storyPublicId}.`);
|
|
24021
|
-
const
|
|
24023
|
+
const relatedUsers = new Set([
|
|
24024
|
+
...story.owner_ids,
|
|
24025
|
+
...story.comments.flatMap((c) => c.author_id),
|
|
24026
|
+
]);
|
|
24027
|
+
const users = await this.client.getUserMap([...relatedUsers].filter((id) => !!id));
|
|
24022
24028
|
return this.toResult(`Story: sc-${storyPublicId}
|
|
24023
24029
|
URL: ${story.app_url}
|
|
24024
24030
|
Name: ${story.name}
|
|
@@ -24029,22 +24035,28 @@ Started: ${story.started ? "Yes" : "No"}
|
|
|
24029
24035
|
Blocked: ${story.blocked ? "Yes" : "No"}
|
|
24030
24036
|
Blocking: ${story.blocker ? "Yes" : "No"}
|
|
24031
24037
|
Due date: ${story.deadline ? story.deadline : "[None]"}
|
|
24038
|
+
Team: ${story.group_id ? `${story.group_id}` : "[None]"}
|
|
24032
24039
|
Owners:${
|
|
24033
24040
|
story.owner_ids.length
|
|
24034
24041
|
? `
|
|
24035
|
-
${formatMemberList(story.owner_ids,
|
|
24042
|
+
${formatMemberList(story.owner_ids, users)}`
|
|
24036
24043
|
: " [None]"
|
|
24037
24044
|
}
|
|
24045
|
+
Epic: ${story.epic_id ? `${story.epic_id}` : "[None]"}
|
|
24046
|
+
Iteration: ${story.iteration_id ? `${story.iteration_id}` : "[None]"}
|
|
24038
24047
|
|
|
24039
24048
|
Description:
|
|
24040
24049
|
${story.description}
|
|
24041
24050
|
|
|
24042
24051
|
Comments:
|
|
24043
24052
|
${(story.comments || [])
|
|
24044
|
-
.map(
|
|
24045
|
-
|
|
24046
|
-
|
|
24047
|
-
|
|
24053
|
+
.map((comment) => {
|
|
24054
|
+
const mentionName = comment.author_id
|
|
24055
|
+
? users.get(comment.author_id)?.profile?.mention_name
|
|
24056
|
+
: null;
|
|
24057
|
+
return `- From: ${mentionName ? `@${mentionName}` : `id=${comment.author_id}` || "[Unknown]"} on ${comment.created_at}.
|
|
24058
|
+
${comment.text || ""}`;
|
|
24059
|
+
})
|
|
24048
24060
|
.join(`
|
|
24049
24061
|
|
|
24050
24062
|
`)}`);
|
|
@@ -24112,7 +24124,7 @@ class EpicTools extends BaseTools {
|
|
|
24112
24124
|
isUnstarted: is("unstarted"),
|
|
24113
24125
|
isStarted: is("started"),
|
|
24114
24126
|
isDone: is("completed"),
|
|
24115
|
-
isArchived: is("archived"),
|
|
24127
|
+
isArchived: is("archived").default(false),
|
|
24116
24128
|
isOverdue: is("overdue"),
|
|
24117
24129
|
hasOwner: has("an owner"),
|
|
24118
24130
|
hasComment: has("a comment"),
|
|
@@ -24149,6 +24161,8 @@ Archived: ${epic.archived ? "Yes" : "No"}
|
|
|
24149
24161
|
Completed: ${epic.completed ? "Yes" : "No"}
|
|
24150
24162
|
Started: ${epic.started ? "Yes" : "No"}
|
|
24151
24163
|
Due date: ${epic.deadline ? epic.deadline : "[Not set]"}
|
|
24164
|
+
Team: ${epic.group_id ? `${epic.group_id}` : "[None]"}
|
|
24165
|
+
Objective: ${epic.milestone_id ? `${epic.milestone_id}` : "[None]"}
|
|
24152
24166
|
|
|
24153
24167
|
Description:
|
|
24154
24168
|
${epic.description}`);
|
|
@@ -24315,6 +24329,7 @@ Start date: ${iteration.start_date}
|
|
|
24315
24329
|
End date: ${iteration.end_date}
|
|
24316
24330
|
Completed: ${iteration.status === "completed" ? "Yes" : "No"}
|
|
24317
24331
|
Started: ${iteration.status === "started" ? "Yes" : "No"}
|
|
24332
|
+
Team: ${iteration.group_ids?.length ? `${iteration.group_ids.join(", ")}` : "[None]"}
|
|
24318
24333
|
|
|
24319
24334
|
Description:
|
|
24320
24335
|
${iteration.description}`);
|
package/package.json
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shortcut/mcp",
|
|
3
|
+
"author": "Shortcut (https://www.shortcut.com)",
|
|
3
4
|
"repository": {
|
|
4
5
|
"type": "git",
|
|
5
6
|
"url": "https://github.com/useshortcut/mcp-server-shortcut.git"
|
|
6
7
|
},
|
|
7
8
|
"keywords": ["shortcut", "mcp", "modelcontextprotocol"],
|
|
8
9
|
"license": "MIT",
|
|
9
|
-
"version": "0.1.
|
|
10
|
+
"version": "0.1.2",
|
|
10
11
|
"type": "module",
|
|
11
|
-
"private": false,
|
|
12
12
|
"main": "dist/index.js",
|
|
13
|
-
"bin":
|
|
14
|
-
|
|
13
|
+
"bin": {
|
|
14
|
+
"mcp-server-shortcut": "dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"files": ["dist"],
|
|
15
17
|
"devDependencies": {
|
|
16
18
|
"@biomejs/biome": "^1.9.4",
|
|
17
19
|
"@types/bun": "latest",
|
|
20
|
+
"bun": "^1.2.5",
|
|
18
21
|
"husky": "^9.1.7",
|
|
19
22
|
"shx": "^0.3.4"
|
|
20
23
|
},
|