loopctl-mcp-server 2.74.0 → 2.75.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 (2) hide show
  1. package/index.js +62 -9
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -4665,7 +4665,12 @@ const TOOLS = [
4665
4665
  "trustworthy answer plus its provenance rather than a ranked list to triage yourself; " +
4666
4666
  "use knowledge_search when you want to browse/enumerate matches. Additive — existing " +
4667
4667
  "knowledge tools are unchanged. If semantic ranking is unavailable it degrades to " +
4668
- "keyword-only (meta.fallback/fallback_reason), same as knowledge_search.",
4668
+ "keyword-only (meta.fallback/fallback_reason), same as knowledge_search.\n\n" +
4669
+ "TODAY THE CURATED BRANCH IS UNREACHABLE ON THIS DEPLOYMENT: a source counts as " +
4670
+ "curated only if its article has curated_at set, and no article does — so every " +
4671
+ "call returns provenance 'retrieved' and a null curated_article_id. Read a " +
4672
+ "'retrieved' verdict as the normal case, not as evidence that a curated answer " +
4673
+ "was considered and rejected. This line comes out when something actually curates.",
4669
4674
  inputSchema: {
4670
4675
  type: "object",
4671
4676
  properties: {
@@ -6493,7 +6498,40 @@ const TOOLS = [
6493
6498
  "search_follow_through carries two further biases pointing OPPOSITE ways: the 20-row " +
6494
6499
  "recording cap hides opens of results ranked beyond it (DOWN on large pages), while " +
6495
6500
  "one open credits EVERY search in the window that surfaced that article, not just the " +
6496
- "preceding one (UP when an agent refines and re-searches).",
6501
+ "preceding one (UP when an agent refines and re-searches).\n\n" +
6502
+ "Exact attribution (unit: READS — not surfaced results, not calls): attributed_opens " +
6503
+ "/ cross_key_opens / direct_opens count READ rows by how their originating search was " +
6504
+ "established, resolved server-side at write time and never accepted from a caller. " +
6505
+ "Not comparable with followed_through, which counts SURFACED RESULTS later opened. " +
6506
+ "cross_key_opens is the population followed_through cannot see: it correlates on " +
6507
+ "api_key_id, and the injected recall hook searches under a different key from the " +
6508
+ "session that reads, so that channel scores a structural ZERO there — meaning " +
6509
+ "UNMEASURABLE, not unread. Cross-key attribution is circumstantial (two agents in one " +
6510
+ "tenant can reach one article independently), hence labelled rather than folded in. " +
6511
+ "direct_opens is the agent going straight to an article by link or cited id, which " +
6512
+ "used to look identical to 'surfaced and ignored' — close to its opposite.\n\n" +
6513
+ "Disposition (unit: SEARCH CALLS): searches_scored_with_follow_through, " +
6514
+ "searches_reformulated and searches_quiet PARTITION searches_scored — NOT searches. " +
6515
+ "Treating every not-opened search as a failure is wrong — an agent answered by the " +
6516
+ "result snippet correctly opens nothing, and that is a success. A reformulation (the " +
6517
+ "SAME SESSION issuing a later search call with a DIFFERENT QUERY in-window, nothing " +
6518
+ "opened) is the closest thing to an unambiguous failure, so it is split out; what " +
6519
+ "remains is `quiet` and is STILL a mixture of 'snippet sufficed' and 'rows ignored'. " +
6520
+ "This surface does not separate them — do not read quiet as either.\n\n" +
6521
+ "searches_scored is SMALLER than searches and the gap is NOT quiet traffic. A search " +
6522
+ "is scoreable only if it carries a session identity (stamped forward-looking, so a " +
6523
+ "pre-migration row reports searches_scored: 0) and comes from a channel that can " +
6524
+ "react to a result at all — the recall hook and the session-start auto-query emit one " +
6525
+ "distilled query per prompt and never see what came back, so they cannot reformulate " +
6526
+ "by construction. They stay in every other denominator here, precision included. " +
6527
+ "Read searches - searches_scored as n/a, never as zero.\n\n" +
6528
+ "COMPARE ROWS ONLY WITHIN A metric_version. Every row carries the version of the " +
6529
+ "definition set that produced it. Three changes have already altered what a figure here " +
6530
+ "MEANS — searched went from search calls to surfaced results, infrastructure traffic " +
6531
+ "began being excluded, and the disposition trio was rescoped — each forward-looking and " +
6532
+ "each previously leaving no mark on the row, so a series read across one of those " +
6533
+ "boundaries compares definitions rather than days. 0 means the row predates the stamp " +
6534
+ "and its definitions are unknown.",
6497
6535
  inputSchema: {
6498
6536
  type: "object",
6499
6537
  properties: {
@@ -6515,8 +6553,15 @@ const TOOLS = [
6515
6553
  {
6516
6554
  name: "knowledge_analytics_top",
6517
6555
  description:
6518
- "Return the top accessed knowledge articles for the tenant. " +
6519
- "Use to identify which articles agents actually read. Requires orchestrator role.",
6556
+ "Return the top READ knowledge articles for the tenant — articles whose body was " +
6557
+ "actually delivered (get/context/drill). Requires orchestrator role.\n\n" +
6558
+ "access_type DEFAULTS TO READS, not to every event. `search` and `index` rows are " +
6559
+ "IMPRESSIONS the ranker produced — one per surfaced result — and they outnumber reads " +
6560
+ "roughly 50:1, so the old unfiltered default ranked ranker output while claiming to " +
6561
+ "show what agents read. Pass access_type:'all' if you genuinely want impressions " +
6562
+ "counted, or a single type to select one. unique_keys counts distinct API KEYS, not " +
6563
+ "agents: v2 mints one ephemeral key per dispatch, so one agent dispatched N times is " +
6564
+ "N keys.",
6520
6565
  inputSchema: {
6521
6566
  type: "object",
6522
6567
  properties: {
@@ -6549,8 +6594,12 @@ const TOOLS = [
6549
6594
  {
6550
6595
  name: "knowledge_article_stats",
6551
6596
  description:
6552
- "Return per-article usage statistics: total accesses, unique agents, " +
6553
- "by-type breakdown, and the 10 most recent events. Requires orchestrator role.",
6597
+ "Return per-article usage statistics: total_events (impressions included), " +
6598
+ "total_reads (bodies actually delivered get/context/drill), unique_keys, a by-type " +
6599
+ "breakdown, and the 10 most recent events. Requires orchestrator role.\n\n" +
6600
+ "Read total_reads, not total_events, when you want usage: impressions outnumber reads " +
6601
+ "roughly 50:1. unique_keys counts distinct API KEYS rather than agents — v2 mints one " +
6602
+ "ephemeral key per dispatch.",
6554
6603
  inputSchema: {
6555
6604
  type: "object",
6556
6605
  properties: {
@@ -6565,7 +6614,8 @@ const TOOLS = [
6565
6614
  {
6566
6615
  name: "knowledge_agent_usage",
6567
6616
  description:
6568
- "Return knowledge usage for an agent: total reads, unique articles, top read articles. " +
6617
+ "Return knowledge usage for an agent: total_reads (bodies actually delivered), " +
6618
+ "total_events (impressions included), unique articles, top read articles. " +
6569
6619
  "Pass api_key_id (api_keys.id credential) OR agent_id (agents.id logical identity) — not both. " +
6570
6620
  "Requires orchestrator role.",
6571
6621
  inputSchema: {
@@ -6600,8 +6650,11 @@ const TOOLS = [
6600
6650
  {
6601
6651
  name: "knowledge_unused_articles",
6602
6652
  description:
6603
- "Return published articles that have not been accessed in the configured " +
6604
- "time window. Use to identify dead-weight knowledge. Requires orchestrator role.",
6653
+ "Return published articles that have not been READ in the configured time window. " +
6654
+ "Use to identify dead-weight knowledge. Requires orchestrator role.\n\n" +
6655
+ "\"Not read\" means no get/context/drill. It deliberately does NOT mean \"no event\": " +
6656
+ "on that definition an article the ranker surfaces constantly and nobody ever opens " +
6657
+ "counted as USED, which made this blind to the largest class of dead weight there is.",
6605
6658
  inputSchema: {
6606
6659
  type: "object",
6607
6660
  properties: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loopctl-mcp-server",
3
- "version": "2.74.0",
3
+ "version": "2.75.0",
4
4
  "description": "MCP server for loopctl \u2014 structural trust for AI development loops",
5
5
  "type": "module",
6
6
  "main": "index.js",