@feedmob/github-issues 0.0.2 → 0.0.3

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 CHANGED
@@ -1,125 +1,86 @@
1
- # GitHub MCP Server
1
+ # FeedMob GitHub Issues MCP Server
2
2
 
3
- MCP Server for the GitHub API, enabling issue operations and search functionality.
4
-
5
- ## Features
6
-
7
- The GitHub MCP Server provides the following capabilities:
8
- - Create and manage GitHub issues
9
- - Search for issues across repositories
10
- - List and filter repository issues
11
- - Update existing issues
12
- - Get details of specific issues
3
+ A GitHub Issues MCP server customized for the FeedMob team
13
4
 
14
5
  ## Tools
15
6
 
7
+ ### `search_issues`
8
+ - Search GitHub Issues through FeedMob API
9
+ - Input parameters:
10
+ - `scheam` (string, required): Get from system resource `issues/search_schema`
11
+ - `start_date` (string): Issue creation start date, defaults to 6 days ago
12
+ - `end_date` (string): Issue creation end date, defaults to today
13
+ - `status` (optional string): Issue status, e.g., 'open', 'closed'
14
+ - `repo` (optional string)
15
+ - `users` (optional string[]): List of users
16
+ - `team` (optional string): Team name, e.g., 'Star', 'Mighty'
17
+ - Returns: Search results
18
+
16
19
  ### `create_issue`
17
- - Create a new issue in a GitHub repository
18
- - Inputs:
19
- - `owner` (string): Repository owner
20
- - `repo` (string): Repository name
21
- - `title` (string): Issue title
20
+ - Create a new Issue in a GitHub repository
21
+ - Input parameters:
22
+ - `owner` (optional string): Repository owner, can use environment variable default
23
+ - `repo` (string, required): Repository name
24
+ - `title` (string, required): Issue title
22
25
  - `body` (optional string): Issue description
23
- - `assignees` (optional string[]): Usernames to assign
26
+ - `assignees` (optional string[]): Usernames to assign to
24
27
  - `labels` (optional string[]): Labels to add
25
28
  - `milestone` (optional number): Milestone number
26
- - Returns: Created issue details
27
-
28
- ### `list_issues`
29
- - List and filter repository issues
30
- - Inputs:
31
- - `owner` (string): Repository owner
32
- - `repo` (string): Repository name
33
- - `state` (optional string): Filter by state ('open', 'closed', 'all')
34
- - `labels` (optional string[]): Filter by labels
35
- - `sort` (optional string): Sort by ('created', 'updated', 'comments')
36
- - `direction` (optional string): Sort direction ('asc', 'desc')
37
- - `since` (optional string): Filter by date (ISO 8601 timestamp)
38
- - `page` (optional number): Page number
39
- - `per_page` (optional number): Results per page
40
- - Returns: Array of issue details
29
+ - Returns: Created Issue details
41
30
 
42
31
  ### `update_issue`
43
- - Update an existing issue
44
- - Inputs:
45
- - `owner` (string): Repository owner
46
- - `repo` (string): Repository name
47
- - `issue_number` (number): Issue number to update
32
+ - Update an existing Issue
33
+ - Input parameters:
34
+ - `owner` (string, required): Repository owner
35
+ - `repo` (string, required): Repository name
36
+ - `issue_number` (number, required): Issue number to update
48
37
  - `title` (optional string): New title
49
38
  - `body` (optional string): New description
50
39
  - `state` (optional string): New state ('open' or 'closed')
51
40
  - `labels` (optional string[]): New labels
52
41
  - `assignees` (optional string[]): New assignees
53
42
  - `milestone` (optional number): New milestone number
54
- - Returns: Updated issue details
55
-
56
- ### `search_issues`
57
- - Search for issues and pull requests across GitHub repositories
58
- - Inputs:
59
- - `q` (string): Search query using GitHub issues search syntax
60
- - `sort` (optional string): Sort field (comments, reactions, created, etc.)
61
- - `order` (optional string): Sort order ('asc' or 'desc')
62
- - `per_page` (optional number): Results per page (max 100)
63
- - `page` (optional number): Page number
64
- - Returns: Issue and pull request search results
43
+ - Returns: Updated Issue details
65
44
 
66
45
  ### `get_issue`
67
- - Gets the contents of an issue within a repository
68
- - Inputs:
69
- - `owner` (string): Repository owner
70
- - `repo` (string): Repository name
71
- - `issue_number` (number): Issue number to retrieve
72
- - Returns: GitHub Issue object & details
73
-
74
- ## Search Query Syntax
75
-
76
- ### Issues Search
77
- - `is:issue` or `is:pr`: Filter by type
78
- - `is:open` or `is:closed`: Filter by state
79
- - `label:bug`: Search by label
80
- - `author:username`: Search by author
81
- - Example: `q: "memory leak" is:issue is:open label:bug`
82
-
83
- For detailed search syntax, see [GitHub's searching documentation](https://docs.github.com/en/search-github/searching-on-github).
84
-
85
- ## Setup
86
-
87
- ### Environment Variables
88
- This server supports the following environment variables:
89
- - `GITHUB_PERSONAL_ACCESS_TOKEN`: Your GitHub Personal Access Token (required)
90
- - `GITHUB_DEFAULT_OWNER`: Default repository owner (optional)
91
- - `GITHUB_DEFAULT_REPO`: Default repository name (optional)
92
-
93
- ### Personal Access Token
94
- [Create a GitHub Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) with appropriate permissions:
95
- - Go to [Personal access tokens](https://github.com/settings/tokens) (in GitHub Settings > Developer settings)
96
- - Select which repositories you'd like this token to have access to (Public, All, or Select)
97
- - Create a token with the `repo` scope ("Full control of private repositories")
98
- - Alternatively, if working only with public repositories, select only the `public_repo` scope
99
- - Copy the generated token
100
-
101
- ### Usage with Claude Desktop
102
- To use this with Claude Desktop, add the following to your `claude_desktop_config.json`:
103
-
104
- ```json
105
- {
106
- "mcpServers": {
107
- "github": {
108
- "command": "npx",
109
- "args": [
110
- "-y",
111
- "@feedmob/github-issues"
112
- ],
113
- "env": {
114
- "GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>",
115
- "GITHUB_DEFAULT_OWNER": "optional-default-owner",
116
- "GITHUB_DEFAULT_REPO": "optional-default-repo"
117
- }
118
- }
119
- }
120
- }
46
+ - Get details of a specific Issue in a repository
47
+ - Input parameters:
48
+ - `owner` (string, required): Repository owner
49
+ - `repo` (string, required):
50
+ - `issue_number` (number, required): Issue number to retrieve
51
+ - Returns: GitHub Issue object and details
52
+
53
+ ### `add_issue_comment`
54
+ - Add a comment to an existing Issue
55
+ - Input parameters:
56
+ - `owner` (string, required): Repository owner
57
+ - `repo` (string, required):
58
+ - `issue_number` (number, required): Issue number
59
+ - `body` (string, required): Comment content
60
+ - Returns: Created comment details
61
+
62
+ ### `sync_latest_issues`
63
+ - Sync GitHub Issues Latest Data By FeedMob API
64
+
65
+ ## Resources
66
+
67
+ ### `issues/search_schema`
68
+ - Provides schema definition for Issues search
69
+
70
+ ### Local Development
71
+ For local development, you can run the server using the following commands:
72
+
73
+ ```bash
74
+ # Install dependencies
75
+ npm install
76
+
77
+ # Build project
78
+ npm run build
79
+
80
+ # Run server
81
+ npx tsx src/github-issues/index.ts
121
82
  ```
122
83
 
123
84
  ## License
124
85
 
125
- This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
86
+ This MCP server is licensed under the MIT License. This means you can freely use, modify, and distribute this software, but must comply with the terms and conditions of the MIT License. For more details, please refer to the LICENSE file in the project repository.
@@ -1,3 +1,3 @@
1
1
  // If the format of this file changes, so it doesn't simply export a VERSION constant,
2
2
  // this will break .github/workflows/version-check.yml.
3
- export const VERSION = "0.0.2";
3
+ export const VERSION = "0.0.3";
package/dist/index.js CHANGED
@@ -1,28 +1,20 @@
1
1
  #!/usr/bin/env node
2
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
- import { z } from 'zod';
6
- import { zodToJsonSchema } from 'zod-to-json-schema';
2
+ import { FastMCP } from "fastmcp";
7
3
  import fetch from 'node-fetch';
8
4
  import * as issues from './operations/issues.js';
9
- import * as search from './operations/search.js';
10
- import { GitHubValidationError, GitHubResourceNotFoundError, GitHubAuthenticationError, GitHubPermissionError, GitHubRateLimitError, GitHubConflictError, isGitHubError, } from './common/errors.js';
5
+ import { GitHubValidationError, GitHubResourceNotFoundError, GitHubAuthenticationError, GitHubPermissionError, GitHubRateLimitError, GitHubConflictError, } from './common/errors.js';
11
6
  import { VERSION } from "./common/version.js";
12
7
  // If fetch doesn't exist in global scope, add it
13
8
  if (!globalThis.fetch) {
14
9
  globalThis.fetch = fetch;
15
10
  }
16
11
  // Default values from environment variables
17
- const DEFAULT_OWNER = process.env.GITHUB_DEFAULT_OWNER || '';
18
- const DEFAULT_REPO = process.env.GITHUB_DEFAULT_REPO || '';
19
- const server = new Server({
20
- name: "github-mcp-server",
21
- version: VERSION,
22
- }, {
23
- capabilities: {
24
- tools: {},
25
- },
12
+ const DEFAULT_OWNER = process.env.GITHUB_DEFAULT_OWNER;
13
+ const AI_API_URL = process.env.AI_API_URL;
14
+ const AI_API_TOKEN = process.env.AI_API_TOKEN;
15
+ const server = new FastMCP({
16
+ name: "feedmob-github-mcp-server",
17
+ version: VERSION
26
18
  });
27
19
  function formatGitHubError(error) {
28
20
  let message = `GitHub API Error: ${error.message}`;
@@ -49,147 +41,164 @@ function formatGitHubError(error) {
49
41
  }
50
42
  return message;
51
43
  }
52
- server.setRequestHandler(ListToolsRequestSchema, async () => {
53
- return {
54
- tools: [
55
- {
56
- name: "create_issue",
57
- description: "Create a new issue in a GitHub repository",
58
- inputSchema: zodToJsonSchema(issues.CreateIssueSchema),
59
- },
60
- {
61
- name: "list_issues",
62
- description: "List issues in a GitHub repository with filtering options",
63
- inputSchema: zodToJsonSchema(issues.ListIssuesOptionsSchema)
64
- },
65
- {
66
- name: "update_issue",
67
- description: "Update an existing issue in a GitHub repository",
68
- inputSchema: zodToJsonSchema(issues.UpdateIssueOptionsSchema)
69
- },
70
- {
71
- name: "search_issues",
72
- description: "Search for issues and pull requests across GitHub repositories",
73
- inputSchema: zodToJsonSchema(search.SearchIssuesSchema),
74
- },
75
- {
76
- name: "get_issue",
77
- description: "Get details of a specific issue in a GitHub repository.",
78
- inputSchema: zodToJsonSchema(issues.GetIssueSchema)
44
+ server.addResource({
45
+ uri: "issues/search_schema",
46
+ name: "search issues schema",
47
+ mimeType: "text/markdown",
48
+ async load() {
49
+ const response = await fetch(AI_API_URL + "/issues/scheam", {
50
+ method: 'GET',
51
+ headers: {
52
+ 'Authorization': "Bearer " + AI_API_TOKEN,
79
53
  }
80
- ],
81
- };
54
+ });
55
+ return {
56
+ text: await response.text(),
57
+ };
58
+ },
82
59
  });
83
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
84
- try {
85
- if (!request.params.arguments) {
86
- throw new Error("Arguments are required");
87
- }
88
- switch (request.params.name) {
89
- case "create_issue": {
90
- const args = issues.CreateIssueSchema.parse(request.params.arguments);
91
- // Use default values from environment variables if not provided
92
- const owner = args.owner || DEFAULT_OWNER;
93
- const repo = args.repo || DEFAULT_REPO;
94
- const { ...options } = args;
95
- if (!owner || !repo) {
96
- throw new Error("Repository owner and name are required. Either provide them directly or set GITHUB_DEFAULT_OWNER and GITHUB_DEFAULT_REPO environment variables.");
97
- }
98
- try {
99
- console.error(`[DEBUG] Attempting to create issue in ${owner}/${repo}`);
100
- console.error(`[DEBUG] Issue options:`, JSON.stringify(options, null, 2));
101
- const issue = await issues.createIssue(owner, repo, options);
102
- console.error(`[DEBUG] Issue created successfully`);
103
- return {
104
- content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
105
- };
106
- }
107
- catch (err) {
108
- // Type guard for Error objects
109
- const error = err instanceof Error ? err : new Error(String(err));
110
- console.error(`[ERROR] Failed to create issue:`, error);
111
- if (error instanceof GitHubResourceNotFoundError) {
112
- throw new Error(`Repository '${owner}/${repo}' not found. Please verify:\n` +
113
- `1. The repository exists\n` +
114
- `2. You have correct access permissions\n` +
115
- `3. The owner and repository names are spelled correctly`);
116
- }
117
- // Safely access error properties
118
- throw new Error(`Failed to create issue: ${error.message}${error.stack ? `\nStack: ${error.stack}` : ''}`);
119
- }
60
+ server.addTool({
61
+ name: "search_issues",
62
+ description: "Search GitHub Issues",
63
+ parameters: issues.FeedmobSearchOptions,
64
+ execute: async (args) => {
65
+ try {
66
+ let params = new URLSearchParams();
67
+ params.set('start_date', args.start_date);
68
+ params.set('end_date', args.end_date);
69
+ // 添加可选参数
70
+ if (args.status !== undefined) {
71
+ params.set('status', args.status);
120
72
  }
121
- case "search_issues": {
122
- const args = search.SearchIssuesSchema.parse(request.params.arguments);
123
- const results = await search.searchIssues(args);
124
- return {
125
- content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
126
- };
73
+ if (args.repo !== undefined) {
74
+ params.set('repo', args.repo);
127
75
  }
128
- case "list_issues": {
129
- const args = issues.ListIssuesOptionsSchema.parse(request.params.arguments);
130
- // Use default values from environment variables if not provided
131
- const owner = args.owner || DEFAULT_OWNER;
132
- const repo = args.repo || DEFAULT_REPO;
133
- const { ...options } = args;
134
- if (!owner || !repo) {
135
- throw new Error("Repository owner and name are required. Either provide them directly or set GITHUB_DEFAULT_OWNER and GITHUB_DEFAULT_REPO environment variables.");
136
- }
137
- const result = await issues.listIssues(owner, repo, options);
138
- return {
139
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
140
- };
76
+ if (args.users !== undefined) {
77
+ args.users.forEach(user => params.append('users[]', user));
141
78
  }
142
- case "update_issue": {
143
- const args = issues.UpdateIssueOptionsSchema.parse(request.params.arguments);
144
- // Use default values from environment variables if not provided
145
- const owner = args.owner || DEFAULT_OWNER;
146
- const repo = args.repo || DEFAULT_REPO;
147
- const { issue_number, ...options } = args;
148
- if (!owner || !repo) {
149
- throw new Error("Repository owner and name are required. Either provide them directly or set GITHUB_DEFAULT_OWNER and GITHUB_DEFAULT_REPO environment variables.");
150
- }
151
- const result = await issues.updateIssue(owner, repo, issue_number, options);
152
- return {
153
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
154
- };
79
+ if (args.team !== undefined) {
80
+ params.set('team', args.team);
155
81
  }
156
- case "get_issue": {
157
- const args = issues.GetIssueSchema.parse(request.params.arguments);
158
- // Use default values from environment variables if not provided
159
- const owner = args.owner || DEFAULT_OWNER;
160
- const repo = args.repo || DEFAULT_REPO;
161
- const { issue_number } = args;
162
- if (!owner || !repo) {
163
- throw new Error("Repository owner and name are required. Either provide them directly or set GITHUB_DEFAULT_OWNER and GITHUB_DEFAULT_REPO environment variables.");
82
+ const response = await fetch(`${AI_API_URL}/issues?${params}`, {
83
+ method: 'GET',
84
+ headers: {
85
+ 'Authorization': "Bearer " + AI_API_TOKEN
164
86
  }
165
- const issue = await issues.getIssue(owner, repo, issue_number);
166
- return {
167
- content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
168
- };
169
- }
170
- default:
171
- throw new Error(`Unknown tool: ${request.params.name}`);
87
+ });
88
+ return {
89
+ content: [{ type: "text", text: await response.text() }],
90
+ };
91
+ }
92
+ catch (error) {
93
+ return {
94
+ content: [{ type: "text", text: `API ERROR: ${error instanceof Error ? error.message : String(error)}` }],
95
+ };
172
96
  }
173
97
  }
174
- catch (error) {
175
- if (error instanceof z.ZodError) {
176
- throw new Error(`Invalid input: ${JSON.stringify(error.errors)}`);
98
+ });
99
+ server.addTool({
100
+ name: "create_issue",
101
+ description: "Create a new issue in a GitHub repository",
102
+ parameters: issues.CreateIssueSchema,
103
+ execute: async (args) => {
104
+ const owner = args.owner || DEFAULT_OWNER;
105
+ const repo = args.repo;
106
+ const { ...options } = args;
107
+ if (!owner || !repo) {
108
+ throw new Error("Repository owner and name are required. Either provide them directly or set GITHUB_DEFAULT_OWNER environment variables.");
177
109
  }
178
- if (isGitHubError(error)) {
179
- throw new Error(formatGitHubError(error));
110
+ try {
111
+ console.error(`[DEBUG] Attempting to create issue in ${owner}/${repo}`);
112
+ console.error(`[DEBUG] Issue options:`, JSON.stringify(options, null, 2));
113
+ const issue = await issues.createIssue(owner, repo, options);
114
+ console.error(`[DEBUG] Issue created successfully`);
115
+ return {
116
+ content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
117
+ };
180
118
  }
181
- throw error;
182
- }
119
+ catch (err) {
120
+ // Type guard for Error objects
121
+ const error = err instanceof Error ? err : new Error(String(err));
122
+ console.error(`[ERROR] Failed to create issue:`, error);
123
+ if (error instanceof GitHubResourceNotFoundError) {
124
+ throw new Error(`Repository '${owner}/${repo}' not found. Please verify:\n` +
125
+ `1. The repository exists\n` +
126
+ `2. You have correct access permissions\n` +
127
+ `3. The owner and repository names are spelled correctly`);
128
+ }
129
+ // Safely access error properties
130
+ throw new Error(`Failed to create issue: ${error.message}${error.stack ? `\nStack: ${error.stack}` : ''}`);
131
+ }
132
+ },
183
133
  });
184
- async function runServer() {
185
- const transport = new StdioServerTransport();
186
- await server.connect(transport);
187
- console.error("GitHub MCP Server running on stdio");
188
- if (DEFAULT_OWNER && DEFAULT_REPO) {
189
- console.error(`Using default repository: ${DEFAULT_OWNER}/${DEFAULT_REPO}`);
190
- }
191
- }
192
- runServer().catch((error) => {
193
- console.error("Fatal error in main():", error);
194
- process.exit(1);
134
+ server.addTool({
135
+ name: "update_issue",
136
+ description: "Update an existing issue in a GitHub repository",
137
+ parameters: issues.UpdateIssueOptionsSchema,
138
+ execute: async (args) => {
139
+ const owner = args.owner || DEFAULT_OWNER;
140
+ const repo = args.repo;
141
+ const { issue_number, ...options } = args;
142
+ if (!owner || !repo) {
143
+ throw new Error("Repository owner and name are required. Either provide them directly or set GITHUB_DEFAULT_OWNER environment variables.");
144
+ }
145
+ const result = await issues.updateIssue(owner, repo, issue_number, options);
146
+ return {
147
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
148
+ };
149
+ },
150
+ });
151
+ server.addTool({
152
+ name: "get_issue",
153
+ description: "Get details of a specific issue in a GitHub repository.",
154
+ parameters: issues.GetIssueSchema,
155
+ execute: async (args) => {
156
+ const owner = args.owner || DEFAULT_OWNER;
157
+ const repo = args.repo;
158
+ const { issue_number } = args;
159
+ if (!owner || !repo) {
160
+ throw new Error("Repository owner and name are required. Either provide them directly or set GITHUB_DEFAULT_OWNER environment variables.");
161
+ }
162
+ const issue = await issues.getIssue(owner, repo, issue_number);
163
+ return {
164
+ content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
165
+ };
166
+ },
167
+ });
168
+ server.addTool({
169
+ name: "add_issue_comment",
170
+ description: "Add a comment to an existing issue",
171
+ parameters: issues.IssueCommentSchema,
172
+ execute: async (args) => {
173
+ const { owner, repo, issue_number, body } = args;
174
+ const result = await issues.addIssueComment(owner, repo, issue_number, body);
175
+ return {
176
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
177
+ };
178
+ },
179
+ });
180
+ server.addTool({
181
+ name: "sync_latest_issues",
182
+ description: "sync latest issues from Api",
183
+ execute: async () => {
184
+ try {
185
+ const response = await fetch(AI_API_URL + "/issues/sync_latest", {
186
+ method: 'GET',
187
+ headers: {
188
+ 'Authorization': "Bearer " + AI_API_TOKEN,
189
+ }
190
+ });
191
+ return {
192
+ content: [{ type: "text", text: await response.text() }],
193
+ };
194
+ }
195
+ catch (error) {
196
+ return {
197
+ content: [{ type: "text", text: `API ERROR: ${error instanceof Error ? error.message : String(error)}` }],
198
+ };
199
+ }
200
+ },
201
+ });
202
+ server.start({
203
+ transportType: "stdio"
195
204
  });
@@ -1,13 +1,23 @@
1
1
  import { z } from "zod";
2
2
  import { githubRequest, buildUrl } from "../common/utils.js";
3
+ import { subDays, format } from 'date-fns';
4
+ export const FeedmobSearchOptions = z.object({
5
+ scheam: z.string().describe("get from system resources issues/search_schema"),
6
+ start_date: z.string().default(format(subDays(new Date(), 6), 'yyyy-MM-dd')).describe("The creation start date of the issue"),
7
+ end_date: z.string().default(format(new Date(), 'yyyy-MM-dd')).describe("The creation end date of the issue"),
8
+ status: z.string().optional().describe("The status of the issue, e.g., 'open', 'closed'"),
9
+ repo: z.string().optional().describe("The repository name, e.g., 'feedmob', 'tracking_admin', If the user does not specify otherwise, this parameter can be omitted and all repos will be searched by default."),
10
+ users: z.array(z.string()).optional().optional(),
11
+ team: z.string().optional().describe("The team name, e.g., 'Star', 'Mighty'"),
12
+ });
3
13
  export const GetIssueSchema = z.object({
4
14
  owner: z.string(),
5
- repo: z.string(),
15
+ repo: z.string().describe("The repository name, e.g., 'feedmob', 'tracking_admin'"),
6
16
  issue_number: z.number(),
7
17
  });
8
18
  export const IssueCommentSchema = z.object({
9
19
  owner: z.string(),
10
- repo: z.string(),
20
+ repo: z.string().describe("The repository name, e.g., 'feedmob', 'tracking_admin'"),
11
21
  issue_number: z.number(),
12
22
  body: z.string(),
13
23
  });
@@ -20,7 +30,7 @@ export const CreateIssueOptionsSchema = z.object({
20
30
  });
21
31
  export const CreateIssueSchema = z.object({
22
32
  owner: z.string().optional(),
23
- repo: z.string().optional(),
33
+ repo: z.string().describe("The repository name, e.g., 'feedmob', 'tracking_admin'"),
24
34
  ...CreateIssueOptionsSchema.shape,
25
35
  });
26
36
  export const ListIssuesOptionsSchema = z.object({
@@ -36,7 +46,7 @@ export const ListIssuesOptionsSchema = z.object({
36
46
  });
37
47
  export const UpdateIssueOptionsSchema = z.object({
38
48
  owner: z.string(),
39
- repo: z.string(),
49
+ repo: z.string().describe("The repository name, e.g., 'feedmob', 'tracking_admin'"),
40
50
  issue_number: z.number(),
41
51
  title: z.string().optional(),
42
52
  body: z.string().optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feedmob/github-issues",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "MCP server for using the GitHub API",
5
5
  "license": "MIT",
6
6
  "author": "FeedMob",
@@ -19,6 +19,8 @@
19
19
  "watch": "tsc --watch"
20
20
  },
21
21
  "dependencies": {
22
+ "date-fns": "^4.1.0",
23
+ "fastmcp": "2.1.0",
22
24
  "@modelcontextprotocol/sdk": "1.0.1",
23
25
  "@types/node": "^22",
24
26
  "@types/node-fetch": "^2.6.12",