loopctl-mcp-server 2.1.0 → 2.2.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 -1
  2. package/index.js +93 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -66,7 +66,7 @@ Or if installed locally:
66
66
 
67
67
  Key resolution priority: `LOOPCTL_API_KEY` > tool-specific key > `LOOPCTL_ORCH_KEY`.
68
68
 
69
- ## Tools (42)
69
+ ## Tools (45)
70
70
 
71
71
  ### Project Tools
72
72
 
@@ -145,6 +145,9 @@ Key resolution priority: `LOOPCTL_API_KEY` > tool-specific key > `LOOPCTL_ORCH_K
145
145
  |---|---|
146
146
  | `knowledge_publish` | Publish a draft article, making it visible to all agents. Required: `article_id`. |
147
147
  | `knowledge_bulk_publish` | **Requires `LOOPCTL_USER_KEY`.** Atomically publish up to 100 drafts in a single call. Required: `article_ids` (array). |
148
+ | `knowledge_unpublish` | **Requires `LOOPCTL_USER_KEY`.** Revert a published article back to draft (hidden from search/context, not deleted). Required: `article_id`. |
149
+ | `knowledge_archive` | **Requires `LOOPCTL_USER_KEY`.** Soft-delete an article (draft or published). Row retained for audit; hidden from all reads. Required: `article_id`. |
150
+ | `knowledge_delete` | **Requires `LOOPCTL_USER_KEY`.** Alias for `knowledge_archive` — DELETE verb on the REST API archives under the hood. Required: `article_id`. |
148
151
  | `knowledge_drafts` | List draft (unpublished) knowledge articles with pagination. Optional: `limit` (default 20, max 20), `offset` (default 0), `project_id`. Returns `meta.total_count`. |
149
152
  | `knowledge_lint` | Run a lint check on the knowledge wiki to identify stale or low-coverage articles. Optional: `project_id`, `stale_days`, `min_coverage`, `max_per_category` (default 50, max 500). True totals returned in `summary.total_per_category`. |
150
153
  | `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`. |
package/index.js CHANGED
@@ -652,6 +652,36 @@ async function knowledgeBulkPublish({ article_ids }) {
652
652
  return toContent(result);
653
653
  }
654
654
 
655
+ async function knowledgeUnpublish({ article_id }) {
656
+ const result = await apiCall(
657
+ "POST",
658
+ `/api/v1/articles/${article_id}/unpublish`,
659
+ null,
660
+ process.env.LOOPCTL_USER_KEY
661
+ );
662
+ return toContent(result);
663
+ }
664
+
665
+ async function knowledgeArchive({ article_id }) {
666
+ const result = await apiCall(
667
+ "POST",
668
+ `/api/v1/articles/${article_id}/archive`,
669
+ null,
670
+ process.env.LOOPCTL_USER_KEY
671
+ );
672
+ return toContent(result);
673
+ }
674
+
675
+ async function knowledgeDelete({ article_id }) {
676
+ const result = await apiCall(
677
+ "DELETE",
678
+ `/api/v1/articles/${article_id}`,
679
+ null,
680
+ process.env.LOOPCTL_USER_KEY
681
+ );
682
+ return toContent(result);
683
+ }
684
+
655
685
  async function knowledgeDrafts({ limit, offset, project_id }) {
656
686
  const params = new URLSearchParams();
657
687
  params.set(
@@ -1726,6 +1756,60 @@ const TOOLS = [
1726
1756
  required: ["article_ids"],
1727
1757
  },
1728
1758
  },
1759
+ {
1760
+ name: "knowledge_unpublish",
1761
+ description:
1762
+ "Revert a published article back to draft state. The article stops being visible " +
1763
+ "in agent search/context but is not deleted — re-publish with knowledge_publish. " +
1764
+ "REQUIRES LOOPCTL_USER_KEY (user role — orchestrator role is NOT sufficient for " +
1765
+ "this destructive operation).",
1766
+ inputSchema: {
1767
+ type: "object",
1768
+ properties: {
1769
+ article_id: {
1770
+ type: "string",
1771
+ description: "The UUID of the published article to unpublish.",
1772
+ },
1773
+ },
1774
+ required: ["article_id"],
1775
+ },
1776
+ },
1777
+ {
1778
+ name: "knowledge_archive",
1779
+ description:
1780
+ "Archive an article (soft delete). The article is hidden from search, context, " +
1781
+ "and the index but the row is retained for audit/history. Works for drafts and " +
1782
+ "published articles. REQUIRES LOOPCTL_USER_KEY (user role — orchestrator role is " +
1783
+ "NOT sufficient for this destructive operation).",
1784
+ inputSchema: {
1785
+ type: "object",
1786
+ properties: {
1787
+ article_id: {
1788
+ type: "string",
1789
+ description: "The UUID of the article to archive.",
1790
+ },
1791
+ },
1792
+ required: ["article_id"],
1793
+ },
1794
+ },
1795
+ {
1796
+ name: "knowledge_delete",
1797
+ description:
1798
+ "Delete an article. Under the hood this performs the same soft-delete (archive) " +
1799
+ "as knowledge_archive — use whichever name is clearer at the call site. The row " +
1800
+ "is retained for audit; there is no hard delete. REQUIRES LOOPCTL_USER_KEY (user " +
1801
+ "role — orchestrator role is NOT sufficient for this destructive operation).",
1802
+ inputSchema: {
1803
+ type: "object",
1804
+ properties: {
1805
+ article_id: {
1806
+ type: "string",
1807
+ description: "The UUID of the article to delete.",
1808
+ },
1809
+ },
1810
+ required: ["article_id"],
1811
+ },
1812
+ },
1729
1813
  {
1730
1814
  name: "knowledge_drafts",
1731
1815
  description:
@@ -2233,6 +2317,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2233
2317
  case "knowledge_bulk_publish":
2234
2318
  return await knowledgeBulkPublish(args);
2235
2319
 
2320
+ case "knowledge_unpublish":
2321
+ return await knowledgeUnpublish(args);
2322
+
2323
+ case "knowledge_archive":
2324
+ return await knowledgeArchive(args);
2325
+
2326
+ case "knowledge_delete":
2327
+ return await knowledgeDelete(args);
2328
+
2236
2329
  case "knowledge_drafts":
2237
2330
  return await knowledgeDrafts(args);
2238
2331
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loopctl-mcp-server",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "MCP server for loopctl — structural trust for AI development loops",
5
5
  "type": "module",
6
6
  "main": "index.js",