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.
- package/README.md +4 -1
- package/index.js +93 -0
- 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 (
|
|
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
|
|