loopctl-mcp-server 2.44.0 → 2.45.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.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/index.js +67 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -188,6 +188,7 @@ autonomous agent) can self-remediate without a human. Full agent-tenant lifecycl
188
188
  | `get_cost_summary` | orch | Get cost/token usage summary for a project, optionally broken down by `agent`, `epic`, or `model`. |
189
189
  | `get_story_token_usage` | orch | Get all token usage records for a single story. |
190
190
  | `get_cost_anomalies` | orch | Get cost anomaly alerts — stories or agents exceeding expected budgets. Optionally filter by project. |
191
+ | `get_ingestion_anomalies` | orch | Get ingestion-health anomalies — capture-silence (a source_type stopped producing articles). Check whether knowledge capture is still landing. |
191
192
  | `set_token_budget` | orch | Set a token budget (in millicents) for a project, epic, story, or agent scope. Requires orchestrator role. |
192
193
 
193
194
  ### Knowledge Wiki Tools (agent key)
package/index.js CHANGED
@@ -824,6 +824,35 @@ async function getCostAnomalies({ project_id, page, page_size }) {
824
824
  return toContent(result);
825
825
  }
826
826
 
827
+ async function getIngestionAnomalies({
828
+ source_type,
829
+ anomaly_type,
830
+ resolved,
831
+ include_archived,
832
+ page,
833
+ page_size,
834
+ }) {
835
+ const params = new URLSearchParams();
836
+ if (source_type) params.set("source_type", source_type);
837
+ if (anomaly_type) params.set("anomaly_type", anomaly_type);
838
+ if (resolved != null) params.set("resolved", String(resolved));
839
+ if (include_archived != null) params.set("include_archived", String(include_archived));
840
+ if (page != null) params.set("page", String(page));
841
+ if (page_size != null) params.set("page_size", String(page_size));
842
+
843
+ const query = params.toString() ? `?${params}` : "";
844
+ // Orchestrator-gated endpoint (RequireRole :orchestrator). Pass the ORCH key
845
+ // explicitly so a misconfigured single agent-role LOOPCTL_API_KEY fails loudly
846
+ // rather than drifting into an undiagnosable 403.
847
+ const result = await apiCall(
848
+ "GET",
849
+ `/api/v1/ingestion-anomalies${query}`,
850
+ undefined,
851
+ process.env.LOOPCTL_ORCH_KEY
852
+ );
853
+ return toContent(result);
854
+ }
855
+
827
856
  async function setTokenBudget({ scope_type, scope_id, budget_millicents, alert_threshold_pct }) {
828
857
  const body = { scope_type, scope_id, budget_millicents };
829
858
  if (alert_threshold_pct != null) body.alert_threshold_pct = alert_threshold_pct;
@@ -2751,6 +2780,41 @@ const TOOLS = [
2751
2780
  required: [],
2752
2781
  },
2753
2782
  },
2783
+ {
2784
+ name: "get_ingestion_anomalies",
2785
+ description:
2786
+ "Get ingestion-health anomalies — capture-silence (a source_type that was producing " +
2787
+ "articles has gone silent). Use to check whether knowledge capture is still landing. " +
2788
+ "Paginated (page/page_size); advance `page` to enumerate all. Filter by source_type, " +
2789
+ "anomaly_type, resolved status, or include archived.",
2790
+ inputSchema: {
2791
+ type: "object",
2792
+ properties: {
2793
+ source_type: {
2794
+ type: "string",
2795
+ description: 'Optional: filter to one article source_type (e.g. "session_log").',
2796
+ },
2797
+ anomaly_type: {
2798
+ type: "string",
2799
+ enum: ["capture_silence"],
2800
+ description: 'Optional: filter by anomaly type (only "capture_silence" is currently produced).',
2801
+ },
2802
+ resolved: {
2803
+ type: "string",
2804
+ enum: ["false", "true", "all"],
2805
+ description:
2806
+ 'Which anomalies to return: "false" = unresolved only (default), "true" = resolved only, "all" = both.',
2807
+ },
2808
+ include_archived: {
2809
+ type: "boolean",
2810
+ description: "Optional: include archived (retired-source) anomalies (default false).",
2811
+ },
2812
+ page: { type: "integer", description: "Page number (default 1)." },
2813
+ page_size: { type: "integer", description: "Anomalies per page (default 20, max 100)." },
2814
+ },
2815
+ required: [],
2816
+ },
2817
+ },
2754
2818
  {
2755
2819
  name: "set_token_budget",
2756
2820
  description:
@@ -5019,6 +5083,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
5019
5083
  case "get_cost_anomalies":
5020
5084
  return await getCostAnomalies(args);
5021
5085
 
5086
+ case "get_ingestion_anomalies":
5087
+ return await getIngestionAnomalies(args);
5088
+
5022
5089
  case "set_token_budget":
5023
5090
  return await setTokenBudget(args);
5024
5091
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loopctl-mcp-server",
3
- "version": "2.44.0",
3
+ "version": "2.45.0",
4
4
  "description": "MCP server for loopctl — structural trust for AI development loops",
5
5
  "type": "module",
6
6
  "main": "index.js",