@remogram/mcp 0.1.0-beta.3 → 0.1.0-beta.5

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 (2) hide show
  1. package/package.json +2 -2
  2. package/register-tools.mjs +103 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remogram/mcp",
3
- "version": "0.1.0-beta.3",
3
+ "version": "0.1.0-beta.5",
4
4
  "description": "Remogram MCP server delegating to CLI",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@modelcontextprotocol/sdk": "^1.17.0",
33
- "@remogram/cli": "0.1.0-beta.3",
33
+ "@remogram/cli": "0.1.0-beta.5",
34
34
  "zod": "^3.25.76"
35
35
  }
36
36
  }
@@ -41,15 +41,65 @@ export function registerTools(server) {
41
41
  description: 'Aggregate open change requests with checks and merge-plan facts into a semantic-diff slice.',
42
42
  inputSchema: z.object({
43
43
  slice_ref: z.string().optional().describe('Optional slice ref label for consumers'),
44
- limit: z.number().int().positive().optional().describe('Max open CR entries (default 50)'),
44
+ limit: z.number().int().positive().optional().describe('Max open CR entries (default 3)'),
45
+ sort: z
46
+ .enum(['number_asc', 'number_desc', 'recent_update', 'recent_created'])
47
+ .optional()
48
+ .describe('Open-list slice sort preset (default number_asc)'),
45
49
  }),
46
50
  args: (input) => {
47
51
  const a = ['cr', 'inventory'];
48
52
  if (input.slice_ref) a.push('--slice-ref', input.slice_ref);
49
53
  if (input.limit != null) a.push('--limit', String(input.limit));
54
+ if (input.sort) a.push('--sort', input.sort);
50
55
  return a;
51
56
  },
52
57
  },
58
+ {
59
+ name: 'cr_open',
60
+ description: 'Open a change request (pull request) on the configured forge.',
61
+ inputSchema: z.object({
62
+ head: z.string().describe('Head branch ref'),
63
+ base: z.string().describe('Base branch ref'),
64
+ title: z.string().describe('Change request title'),
65
+ body: z.string().optional().describe('Optional change request body'),
66
+ }),
67
+ args: (input) => {
68
+ const a = ['cr', 'open', '--head', input.head, '--base', input.base, '--title', input.title];
69
+ if (input.body) a.push('--body', input.body);
70
+ return a;
71
+ },
72
+ readOnlyHint: false,
73
+ destructiveHint: true,
74
+ },
75
+ {
76
+ name: 'status_set',
77
+ description: 'Set a commit status (check context) on the configured forge.',
78
+ inputSchema: z.object({
79
+ sha: z.string().describe('40-character commit SHA'),
80
+ context: z.string().describe('Status context name'),
81
+ state: z.enum(['pending', 'success', 'failure', 'error']).describe('Status state'),
82
+ target_url: z.string().optional().describe('Optional target URL for the status'),
83
+ description: z.string().optional().describe('Optional status description'),
84
+ }),
85
+ args: (input) => {
86
+ const a = [
87
+ 'status',
88
+ 'set',
89
+ '--sha',
90
+ input.sha,
91
+ '--context',
92
+ input.context,
93
+ '--state',
94
+ input.state,
95
+ ];
96
+ if (input.target_url) a.push('--target-url', input.target_url);
97
+ if (input.description) a.push('--description', input.description);
98
+ return a;
99
+ },
100
+ readOnlyHint: false,
101
+ destructiveHint: true,
102
+ },
53
103
  {
54
104
  name: 'pr_status',
55
105
  description: 'PR metadata and mergeability facts.',
@@ -82,8 +132,55 @@ export function registerTools(server) {
82
132
  description: 'Merge readiness facts: mergeability, checks, blockers.',
83
133
  inputSchema: z.object({
84
134
  number: z.number().int().positive(),
135
+ allowed_paths: z.array(z.string()).optional(),
136
+ }),
137
+ args: (input) => {
138
+ const a = ['merge', 'plan', '--number', String(input.number)];
139
+ for (const glob of input.allowed_paths ?? []) {
140
+ a.push('--allowed-path', glob);
141
+ }
142
+ return a;
143
+ },
144
+ },
145
+ {
146
+ name: 'whoami',
147
+ description: 'Authenticated forge identity facts (login, can_write, token scope/expiry signals).',
148
+ inputSchema: z.object({}),
149
+ args: ['whoami'],
150
+ },
151
+ {
152
+ name: 'branch_protection',
153
+ description:
154
+ 'Branch protection policy facts: required status contexts, protected rules, approvals signal.',
155
+ inputSchema: z.object({
156
+ branch_ref: z.string(),
157
+ }),
158
+ args: (input) => ['branch', 'protection', '--branch-ref', input.branch_ref],
159
+ },
160
+ {
161
+ name: 'cr_files',
162
+ description: 'Changed file paths for a change request (bounded, truncation-aware).',
163
+ inputSchema: z.object({
164
+ number: z.number().int().positive(),
165
+ }),
166
+ args: (input) => ['cr', 'files', '--number', String(input.number)],
167
+ },
168
+ {
169
+ name: 'cr_comments',
170
+ description: 'Review comments for a change request (sanitized bodies, truncation-aware).',
171
+ inputSchema: z.object({
172
+ number: z.number().int().positive(),
173
+ }),
174
+ args: (input) => ['cr', 'comments', '--number', String(input.number)],
175
+ },
176
+ {
177
+ name: 'forge_changes',
178
+ description:
179
+ 'Forge activity events since an observed_at boundary (PR lifecycle, head SHA moves, check conclusions).',
180
+ inputSchema: z.object({
181
+ since: z.string().describe('ISO-8601 observed_at boundary'),
85
182
  }),
86
- args: (input) => ['merge', 'plan', '--number', String(input.number)],
183
+ args: (input) => ['forge', 'changes', '--since', input.since],
87
184
  },
88
185
  {
89
186
  name: 'sync_plan',
@@ -105,7 +202,10 @@ export function registerTools(server) {
105
202
  {
106
203
  description: tool.description,
107
204
  inputSchema: tool.inputSchema,
108
- annotations: { readOnlyHint: true, destructiveHint: false },
205
+ annotations: {
206
+ readOnlyHint: tool.readOnlyHint !== false,
207
+ destructiveHint: tool.destructiveHint === true,
208
+ },
109
209
  },
110
210
  async (input) => {
111
211
  const args = typeof tool.args === 'function' ? tool.args(input) : tool.args;