loopctl-mcp-server 1.2.0 → 1.3.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 +4 -2
  2. package/index.js +63 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  MCP (Model Context Protocol) server for [loopctl](https://loopctl.com) -- structural trust for AI development loops.
4
4
 
5
- Wraps the loopctl REST API into 33 typed MCP tools so AI coding agents (Claude Code, etc.) can interact with loopctl without writing curl commands.
5
+ Wraps the loopctl REST API into 35 typed MCP tools so AI coding agents (Claude Code, etc.) can interact with loopctl without writing curl commands.
6
6
 
7
7
  ## Installation
8
8
 
@@ -65,7 +65,7 @@ Or if installed locally:
65
65
 
66
66
  Key resolution priority: `LOOPCTL_API_KEY` > tool-specific key > `LOOPCTL_ORCH_KEY`.
67
67
 
68
- ## Tools (33)
68
+ ## Tools (35)
69
69
 
70
70
  ### Project Tools
71
71
 
@@ -143,6 +143,8 @@ Key resolution priority: `LOOPCTL_API_KEY` > tool-specific key > `LOOPCTL_ORCH_K
143
143
  | `knowledge_drafts` | List all draft (unpublished) knowledge articles. Optional: `limit`, `offset`. |
144
144
  | `knowledge_lint` | Run a lint check on the knowledge wiki to identify stale or low-coverage articles. Optional: `project_id`, `stale_days`, `min_coverage`. |
145
145
  | `knowledge_export` | Export all knowledge articles as a ZIP archive. Returns a curl command for direct download (ZIP binary cannot be returned as MCP content). Optional: `project_id`. |
146
+ | `knowledge_ingest` | Submit a URL or raw content for knowledge extraction. Enqueues an Oban job. Required: `source_type`. One of: `url` or `content`. Optional: `project_id`. |
147
+ | `knowledge_ingestion_jobs` | List recent content ingestion jobs (last 7 days, max 50). |
146
148
 
147
149
  ### Discovery Tools
148
150
 
package/index.js CHANGED
@@ -480,6 +480,20 @@ async function knowledgeLint({ project_id, stale_days, min_coverage }) {
480
480
  return toContent(result);
481
481
  }
482
482
 
483
+ async function knowledgeIngest({ url, content, source_type, project_id }) {
484
+ const body = { source_type };
485
+ if (url) body.url = url;
486
+ if (content) body.content = content;
487
+ if (project_id) body.project_id = project_id;
488
+ const result = await apiCall("POST", "/api/v1/knowledge/ingest", body, process.env.LOOPCTL_ORCH_KEY);
489
+ return toContent(result);
490
+ }
491
+
492
+ async function knowledgeIngestionJobs() {
493
+ const result = await apiCall("GET", "/api/v1/knowledge/ingestion-jobs", null, process.env.LOOPCTL_ORCH_KEY);
494
+ return toContent(result);
495
+ }
496
+
483
497
  async function knowledgeExport({ project_id }) {
484
498
  const basePath = project_id
485
499
  ? `/api/v1/projects/${project_id}/knowledge/export`
@@ -1256,6 +1270,48 @@ const TOOLS = [
1256
1270
  },
1257
1271
  },
1258
1272
 
1273
+ // Knowledge Ingestion Tools
1274
+ {
1275
+ name: "knowledge_ingest",
1276
+ description:
1277
+ "Submit a URL or raw content for knowledge extraction. " +
1278
+ "Enqueues an Oban job that fetches the content (if URL), extracts knowledge articles via LLM, " +
1279
+ "and inserts them as draft articles. Requires orchestrator role.",
1280
+ inputSchema: {
1281
+ type: "object",
1282
+ properties: {
1283
+ url: {
1284
+ type: "string",
1285
+ description: "URL to fetch content from (exactly one of url or content required).",
1286
+ },
1287
+ content: {
1288
+ type: "string",
1289
+ description: "Raw content to extract knowledge from (exactly one of url or content required).",
1290
+ },
1291
+ source_type: {
1292
+ type: "string",
1293
+ description: "Source type (e.g., newsletter, skill, web_article, ingestion). Required.",
1294
+ },
1295
+ project_id: {
1296
+ type: "string",
1297
+ description: "Optional: scope extracted articles to a specific project UUID.",
1298
+ },
1299
+ },
1300
+ required: ["source_type"],
1301
+ },
1302
+ },
1303
+ {
1304
+ name: "knowledge_ingestion_jobs",
1305
+ description:
1306
+ "List recent content ingestion jobs for the current tenant. " +
1307
+ "Returns jobs from the last 7 days, max 50 results. Requires orchestrator role.",
1308
+ inputSchema: {
1309
+ type: "object",
1310
+ properties: {},
1311
+ required: [],
1312
+ },
1313
+ },
1314
+
1259
1315
  // Discovery Tools
1260
1316
  {
1261
1317
  name: "list_routes",
@@ -1395,6 +1451,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1395
1451
  case "knowledge_export":
1396
1452
  return await knowledgeExport(args);
1397
1453
 
1454
+ // Knowledge Ingestion Tools
1455
+ case "knowledge_ingest":
1456
+ return await knowledgeIngest(args);
1457
+
1458
+ case "knowledge_ingestion_jobs":
1459
+ return await knowledgeIngestionJobs();
1460
+
1398
1461
  // Discovery Tools
1399
1462
  case "list_routes":
1400
1463
  return await listRoutes();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loopctl-mcp-server",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "MCP server for loopctl — structural trust for AI development loops",
5
5
  "type": "module",
6
6
  "main": "index.js",