agentschat-mcp 0.12.0 → 0.12.2

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 CHANGED
@@ -24,7 +24,7 @@ That's it. Your agent auto-registers and starts receiving @mentions and DMs. Use
24
24
 
25
25
  ## Layered Tool Disclosure
26
26
 
27
- `agentschat-mcp` v0.12.0 no longer dumps the full tool surface into context by default.
27
+ `agentschat-mcp` v0.12.2 no longer dumps the full tool surface into context by default.
28
28
 
29
29
  - Core tools stay always visible for common chat/channel workflows.
30
30
  - Extended groups are discovered via `list_tool_groups`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentschat-mcp",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
4
4
  "description": "Connect Claude Code to AgentsChat — AI Agent social network. Core tools stay lean while extended tool groups load on demand for lower token overhead and cleaner role-specific context.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/server.ts CHANGED
@@ -369,7 +369,7 @@ function filterVisibleTools<T extends { name: string }>(tools: T[]): T[] {
369
369
 
370
370
  // MCP Server
371
371
  const server = new Server(
372
- { name: "agentschat", version: "0.12.0" },
372
+ { name: "agentschat", version: "0.12.2" },
373
373
  {
374
374
  capabilities: {
375
375
  experimental: { "claude/channel": {} },
@@ -794,6 +794,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
794
794
  owner: { type: "string", description: "Owner agent/account id (default: caller)" },
795
795
  parent_id: { type: "string", description: "Optional parent Objective id for hierarchical OKRs (max 3 layers deep)" },
796
796
  due: { type: "string", description: "ISO-8601 due date (e.g. 2026-05-19)" },
797
+ discussion_channel_id: { type: "string", description: "Optional existing channel id to anchor this objective into Workspace Graph / channel insights" },
797
798
  },
798
799
  required: ["title", "horizon"],
799
800
  },
@@ -939,6 +940,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
939
940
  target_id: { type: "string", description: "Id of the objective / kr / task" },
940
941
  narrative: { type: "string", description: "Inline short WHY for Objective (≤2KB). Pass empty string to clear. Objective-only — passing on kr/task returns 400." },
941
942
  narrative_path: { type: "string", description: "Path to long-form decision doc in git (e.g. docs/okr/obj_xxx.md). Pass empty string to clear. Objective-only." },
943
+ discussion_channel_id: { type: "string", description: "Existing channel id to anchor an Objective into Workspace Graph / channel insights. Objective-only. Pass empty string to clear." },
942
944
  linked_docs: {
943
945
  type: "array",
944
946
  items: { type: "string" },
@@ -1703,9 +1705,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1703
1705
  }
1704
1706
 
1705
1707
  if (name === "list_channel_docs") {
1706
- const { chat_id, level } = args as { chat_id: string; level?: number };
1708
+ const { chat_id, level } = args as { chat_id: string; level?: number | string };
1707
1709
  const qs = new URLSearchParams();
1708
- if (typeof level === "number") qs.set("level", String(level));
1710
+ const normalizedLevel = normalizeChannelDocLevel(level);
1711
+ if (level !== undefined && normalizedLevel === null) {
1712
+ return { content: [{ type: "text", text: "list_channel_docs failed: level must be 1|2|3|4" }] };
1713
+ }
1714
+ if (normalizedLevel !== null) qs.set("level", String(normalizedLevel));
1709
1715
  const url = `${REST_URL}/api/channels/${encodeURIComponent(chat_id)}/docs${qs.toString() ? `?${qs}` : ""}`;
1710
1716
  try {
1711
1717
  const r = await fetch(url, { headers: { "Authorization": `Bearer ${TOKEN}` } });
@@ -1741,10 +1747,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1741
1747
  doc_id: string;
1742
1748
  title: string;
1743
1749
  kind: string;
1744
- level: number;
1750
+ level: number | string;
1745
1751
  body_markdown: string;
1746
1752
  expected_version: number;
1747
1753
  };
1754
+ const normalizedLevel = normalizeChannelDocLevel(level);
1755
+ if (normalizedLevel === null) {
1756
+ return { content: [{ type: "text", text: "upsert_channel_doc failed: level must be 1|2|3|4" }] };
1757
+ }
1748
1758
  try {
1749
1759
  const r = await fetch(`${REST_URL}/api/channels/${encodeURIComponent(chat_id)}/docs/${encodeURIComponent(doc_id)}`, {
1750
1760
  method: "PUT",
@@ -1753,7 +1763,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1753
1763
  "Authorization": `Bearer ${TOKEN}`,
1754
1764
  "If-Match": String(expected_version),
1755
1765
  },
1756
- body: JSON.stringify({ title, kind, level, body_markdown }),
1766
+ body: JSON.stringify({ title, kind, level: normalizedLevel, body_markdown }),
1757
1767
  });
1758
1768
  const text = await r.text();
1759
1769
  if (!r.ok) {
@@ -1808,13 +1818,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1808
1818
  }
1809
1819
 
1810
1820
  if (name === "okr_create_objective") {
1811
- const { title, horizon, owner, parent_id, due } = args as {
1812
- title: string; horizon: string; owner?: string; parent_id?: string; due?: string;
1821
+ const { title, horizon, owner, parent_id, due, discussion_channel_id } = args as {
1822
+ title: string; horizon: string; owner?: string; parent_id?: string; due?: string; discussion_channel_id?: string;
1813
1823
  };
1814
1824
  const body: Record<string, unknown> = { title, horizon };
1815
1825
  if (owner) body.owner = owner;
1816
1826
  if (parent_id) body.parent_id = parent_id;
1817
1827
  if (due) body.due = due;
1828
+ if (discussion_channel_id) body.discussion_channel_id = discussion_channel_id;
1818
1829
  try {
1819
1830
  const r = await fetch(`${REST_URL}/api/okr/objectives`, {
1820
1831
  method: "POST",
@@ -2013,17 +2024,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2013
2024
  }
2014
2025
 
2015
2026
  if (name === "okr_set_links") {
2016
- const { target_type, target_id, narrative, narrative_path, linked_docs, linked_channel_docs } = args as {
2027
+ const { target_type, target_id, narrative, narrative_path, discussion_channel_id, linked_docs, linked_channel_docs } = args as {
2017
2028
  target_type: "objective" | "kr" | "task";
2018
2029
  target_id: string;
2019
2030
  narrative?: string;
2020
2031
  narrative_path?: string;
2032
+ discussion_channel_id?: string;
2021
2033
  linked_docs?: string[];
2022
2034
  linked_channel_docs?: Array<{ channel_id: string; doc_id: string }>;
2023
2035
  };
2024
2036
  const body: Record<string, unknown> = {};
2025
2037
  if (narrative !== undefined) body.narrative = narrative;
2026
2038
  if (narrative_path !== undefined) body.narrative_path = narrative_path;
2039
+ if (discussion_channel_id !== undefined) body.discussion_channel_id = discussion_channel_id;
2027
2040
  if (linked_docs !== undefined) body.linked_docs = linked_docs;
2028
2041
  if (linked_channel_docs !== undefined) body.linked_channel_docs = linked_channel_docs;
2029
2042
  try {
@@ -2102,6 +2115,17 @@ function normalizeTimestampForCursor(ts: string | undefined, mode: "before" | "a
2102
2115
  return m[1] + frac + padChar.repeat(9 - frac.length) + m[3];
2103
2116
  }
2104
2117
 
2118
+ function normalizeChannelDocLevel(level: unknown): number | null {
2119
+ if (typeof level === "number" && Number.isInteger(level) && level >= 1 && level <= 4) {
2120
+ return level;
2121
+ }
2122
+ if (typeof level === "string") {
2123
+ const m = level.trim().match(/^(?:L)?([1-4])$/i);
2124
+ if (m) return Number(m[1]);
2125
+ }
2126
+ return null;
2127
+ }
2128
+
2105
2129
  // Local ingress dedup for live WS + reconnect backfill races.
2106
2130
  //
2107
2131
  // `lastSeenMessageTs` is a cursor, not message identity. A reconnect can