@scottsus/mdreview-mcp 0.4.0 → 0.6.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.
@@ -1,5 +1,4 @@
1
1
  interface CreateReviewResponse {
2
- id: string;
3
2
  slug: string;
4
3
  url: string;
5
4
  status: string;
@@ -20,8 +19,8 @@ interface ReviewResponse {
20
19
  }
21
20
  interface ThreadResponse {
22
21
  id: string;
23
- startOffset: number;
24
- endOffset: number;
22
+ startLine: number;
23
+ endLine: number;
25
24
  selectedText: string;
26
25
  resolved: boolean;
27
26
  comments: CommentResponse[];
@@ -33,12 +32,6 @@ interface CommentResponse {
33
32
  authorName: string | null;
34
33
  createdAt: string;
35
34
  }
36
- interface SubmitDecisionResponse {
37
- id: string;
38
- status: string;
39
- decisionMessage: string | null;
40
- decidedAt: string | null;
41
- }
42
35
  interface ResolveThreadResponse {
43
36
  id: string;
44
37
  resolved: boolean;
@@ -48,9 +41,8 @@ export declare class ApiClient {
48
41
  private baseUrl;
49
42
  constructor(baseUrl?: string);
50
43
  createReview(content: string): Promise<CreateReviewResponse>;
51
- getReview(reviewId: string, includeContent?: boolean): Promise<ReviewResponse>;
44
+ getReview(reviewId: string): Promise<ReviewResponse>;
52
45
  addComment(threadId: string, body: string): Promise<CommentResponse>;
53
- submitDecision(reviewId: string, decision: "approved" | "rejected" | "changes_requested", message?: string): Promise<SubmitDecisionResponse>;
54
46
  resolveThread(threadId: string): Promise<ResolveThreadResponse>;
55
47
  }
56
48
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAEA,UAAU,oBAAoB;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,sBAAsB;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,UAAU,qBAAqB;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;IAItB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAkB5D,SAAS,CACb,QAAQ,EAAE,MAAM,EAChB,cAAc,UAAQ,GACrB,OAAO,CAAC,cAAc,CAAC;IAcpB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAsBpE,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,UAAU,GAAG,UAAU,GAAG,mBAAmB,EACvD,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,sBAAsB,CAAC;IAkB5B,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;CActE"}
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAEA,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,qBAAqB;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;IAItB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAkB5D,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAWpD,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAsBpE,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;CActE"}
@@ -19,11 +19,8 @@ export class ApiClient {
19
19
  }
20
20
  return response.json();
21
21
  }
22
- async getReview(reviewId, includeContent = false) {
23
- const url = includeContent
24
- ? `${this.baseUrl}/api/reviews/${reviewId}?includeContent=true`
25
- : `${this.baseUrl}/api/reviews/${reviewId}`;
26
- const response = await fetch(url);
22
+ async getReview(reviewId) {
23
+ const response = await fetch(`${this.baseUrl}/api/reviews/${reviewId}`);
27
24
  if (!response.ok) {
28
25
  const error = await response.json();
29
26
  throw new Error(error.message || "Failed to get review");
@@ -46,18 +43,6 @@ export class ApiClient {
46
43
  }
47
44
  return response.json();
48
45
  }
49
- async submitDecision(reviewId, decision, message) {
50
- const response = await fetch(`${this.baseUrl}/api/reviews/${reviewId}/submit`, {
51
- method: "POST",
52
- headers: { "Content-Type": "application/json" },
53
- body: JSON.stringify({ decision, message }),
54
- });
55
- if (!response.ok) {
56
- const error = await response.json();
57
- throw new Error(error.message || "Failed to submit decision");
58
- }
59
- return response.json();
60
- }
61
46
  async resolveThread(threadId) {
62
47
  const response = await fetch(`${this.baseUrl}/api/threads/${threadId}`, {
63
48
  method: "PATCH",
package/dist/index.js CHANGED
@@ -6,13 +6,13 @@ import { z } from "zod";
6
6
  import { ApiClient } from "./api-client.js";
7
7
  const server = new McpServer({
8
8
  name: "mdreview",
9
- version: "0.4.0",
9
+ version: "0.6.0",
10
10
  });
11
11
  const apiClient = new ApiClient(process.env.MDREVIEW_BASE_URL);
12
12
  // Tool: request_review
13
13
  server.registerTool("request_review", {
14
14
  title: "Request Review",
15
- description: "Create a markdown document review and get a shareable URL. Share this URL with the reviewer and they can add inline comments and approve/reject the document.",
15
+ description: "Create a markdown document review and get a shareable URL. Share this URL with the reviewer and they can add inline comments.",
16
16
  inputSchema: {
17
17
  filePath: z.string().describe("The path to the markdown file to review"),
18
18
  },
@@ -38,11 +38,11 @@ server.registerTool("request_review", {
38
38
  content: [
39
39
  {
40
40
  type: "text",
41
- text: `Review created successfully!\n\nReview URL: ${result.url}\n\nShare this URL with your reviewer. They can:\n- Add inline comments by selecting text\n- Approve, reject, or request changes\n\nUse 'get_review_status' with reviewId "${result.id}" to check the review status.`,
41
+ text: `Review created successfully!\n\nReview URL: ${result.url}\n\nShare this URL with your reviewer. They can add inline comments by selecting text.\n\nUse 'get_review_status' with reviewId "${result.slug}" to check comments.`,
42
42
  },
43
43
  ],
44
44
  structuredContent: {
45
- reviewId: result.id,
45
+ reviewId: result.slug,
46
46
  url: result.url,
47
47
  status: result.status,
48
48
  },
@@ -54,13 +54,9 @@ server.registerTool("get_review_status", {
54
54
  description: "Get the current status of a review without waiting. Use this to check if a review has been completed.",
55
55
  inputSchema: {
56
56
  reviewId: z.string().describe("The review ID to check"),
57
- includeContent: z
58
- .boolean()
59
- .default(false)
60
- .describe("Include the full markdown content in the response"),
61
57
  },
62
- }, async ({ reviewId, includeContent }) => {
63
- const result = await apiClient.getReview(reviewId, includeContent);
58
+ }, async ({ reviewId }) => {
59
+ const result = await apiClient.getReview(reviewId);
64
60
  const commentsText = result.threads
65
61
  .map((thread) => {
66
62
  const comments = thread.comments
@@ -75,24 +71,21 @@ server.registerTool("get_review_status", {
75
71
  unresolvedThreads: result.threads.filter((t) => !t.resolved).length,
76
72
  totalComments: result.threads.reduce((sum, t) => sum + t.comments.length, 0),
77
73
  };
78
- const structuredContent = {
79
- status: result.status,
80
- decisionMessage: result.decisionMessage,
81
- decidedAt: result.decidedAt,
82
- threads: result.threads,
83
- summary,
84
- };
85
- if (includeContent) {
86
- structuredContent.content = result.content;
87
- }
88
74
  return {
89
75
  content: [
90
76
  {
91
77
  type: "text",
92
- text: `Review Status: ${result.status.toUpperCase()}\nTitle: ${result.title || "(untitled)"}\nMessage: ${result.decisionMessage || "(none)"}\nURL: ${result.url}\n\nSummary:\n- Total threads: ${summary.totalThreads}\n- Resolved: ${summary.resolvedThreads}\n- Unresolved: ${summary.unresolvedThreads}\n- Total comments: ${summary.totalComments}\n\n${commentsText ? `Comments:\n${commentsText}` : "No comments."}`,
78
+ text: `Review: ${result.title || "(untitled)"}\nURL: ${result.url}\n\nSummary:\n- Total threads: ${summary.totalThreads}\n- Resolved: ${summary.resolvedThreads}\n- Unresolved: ${summary.unresolvedThreads}\n- Total comments: ${summary.totalComments}\n\n${commentsText ? `Comments:\n${commentsText}` : "No comments."}`,
93
79
  },
94
80
  ],
95
- structuredContent,
81
+ structuredContent: {
82
+ status: result.status,
83
+ content: result.content,
84
+ decisionMessage: result.decisionMessage,
85
+ decidedAt: result.decidedAt,
86
+ threads: result.threads,
87
+ summary,
88
+ },
96
89
  };
97
90
  });
98
91
  // Tool: add_comment
@@ -141,37 +134,6 @@ server.registerTool("resolve_thread", {
141
134
  },
142
135
  };
143
136
  });
144
- // Tool: submit_decision
145
- server.registerTool("submit_decision", {
146
- title: "Submit Decision",
147
- description: "Submit a review decision (approve, reject, or request changes). Use this to finalize a review.",
148
- inputSchema: {
149
- reviewId: z.string().describe("The review ID"),
150
- decision: z
151
- .enum(["approved", "rejected", "changes_requested"])
152
- .describe("The decision"),
153
- message: z
154
- .string()
155
- .optional()
156
- .describe("Optional message explaining the decision"),
157
- },
158
- }, async ({ reviewId, decision, message }) => {
159
- const result = await apiClient.submitDecision(reviewId, decision, message);
160
- return {
161
- content: [
162
- {
163
- type: "text",
164
- text: `Decision submitted successfully!\n\nReview ID: ${result.id}\nDecision: ${result.status.toUpperCase()}\nMessage: ${result.decisionMessage || "(none)"}`,
165
- },
166
- ],
167
- structuredContent: {
168
- reviewId: result.id,
169
- status: result.status,
170
- decisionMessage: result.decisionMessage,
171
- decidedAt: result.decidedAt,
172
- },
173
- };
174
- });
175
137
  async function main() {
176
138
  const transport = new StdioServerTransport();
177
139
  await server.connect(transport);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scottsus/mdreview-mcp",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "MCP server for MDReview - markdown document review tool",
5
5
  "type": "module",
6
6
  "bin": {