loopctl-mcp-server 1.1.1 → 1.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.
Files changed (2) hide show
  1. package/index.js +12 -8
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -116,10 +116,12 @@ function toContent(result) {
116
116
  }
117
117
 
118
118
  /**
119
- * Compact variant for list endpoints — strips bulky fields (acceptance_criteria,
120
- * description) from each story to stay within token limits. Callers can use
121
- * get_story for full details on individual stories.
119
+ * Compact variant for list endpoints — strips acceptance_criteria and
120
+ * description (use get_story for full details). Keeps all other fields.
121
+ * Enforces a max page size to prevent MCP response token overflow.
122
122
  */
123
+ const MAX_PAGE_SIZE = 20;
124
+
123
125
  function toContentCompact(result) {
124
126
  if (result && result.error === true) return toContent(result);
125
127
 
@@ -191,7 +193,7 @@ async function listStories({ project_id, agent_status, verified_status, epic_id,
191
193
  if (agent_status) params.set("agent_status", agent_status);
192
194
  if (verified_status) params.set("verified_status", verified_status);
193
195
  if (epic_id) params.set("epic_id", epic_id);
194
- params.set("limit", String(limit ?? 20));
196
+ params.set("limit", String(Math.min(limit ?? MAX_PAGE_SIZE, MAX_PAGE_SIZE)));
195
197
  if (offset != null) params.set("offset", String(offset));
196
198
  if (include_token_totals) params.set("include_token_totals", "true");
197
199
 
@@ -201,7 +203,7 @@ async function listStories({ project_id, agent_status, verified_status, epic_id,
201
203
 
202
204
  async function listReadyStories({ project_id, limit }) {
203
205
  const params = new URLSearchParams({ project_id });
204
- params.set("limit", String(limit ?? 20));
206
+ params.set("limit", String(Math.min(limit ?? MAX_PAGE_SIZE, MAX_PAGE_SIZE)));
205
207
 
206
208
  const result = await apiCall("GET", `/api/v1/stories/ready?${params}`);
207
209
  return toContentCompact(result);
@@ -490,7 +492,8 @@ const TOOLS = [
490
492
  description:
491
493
  "List stories for a project, optionally filtered by agent_status, verified_status, or epic_id. " +
492
494
  "Returns compact results (no acceptance_criteria/description) — use get_story for full details. " +
493
- "Defaults to 20 stories per page; use limit/offset to paginate.",
495
+ "Max 20 per page. Use offset to paginate (response includes total_count). " +
496
+ "Filter by epic_id or agent_status to reduce result size.",
494
497
  inputSchema: {
495
498
  type: "object",
496
499
  properties: {
@@ -531,7 +534,8 @@ const TOOLS = [
531
534
  name: "list_ready_stories",
532
535
  description:
533
536
  "List stories that are ready to be worked on (contracted, dependencies met). " +
534
- "Returns compact results — use get_story for full details. Defaults to 20 per page.",
537
+ "Returns compact results — use get_story for full details. " +
538
+ "Max 20 per page. Response includes total_count for pagination.",
535
539
  inputSchema: {
536
540
  type: "object",
537
541
  properties: {
@@ -965,7 +969,7 @@ const TOOLS = [
965
969
  const server = new Server(
966
970
  {
967
971
  name: "loopctl",
968
- version: "1.1.1",
972
+ version: "1.1.2",
969
973
  },
970
974
  {
971
975
  capabilities: { tools: {} },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loopctl-mcp-server",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "MCP server for loopctl — structural trust for AI development loops",
5
5
  "type": "module",
6
6
  "main": "index.js",