coherence-mcp-server 0.5.1 → 0.5.3

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
@@ -1,8 +1,9 @@
1
+ <!-- AUTO-GENERATED from README.template.md. Edit the template, not this file. -->
1
2
  # coherence-mcp-server
2
3
 
3
4
  **Give your AI agent native access to every idea, spec, contributor, and value chain in the Coherence Network.**
4
5
 
5
- An [MCP](https://modelcontextprotocol.io/) (Model Context Protocol) server that exposes the full Coherence Network API as 57 typed tools — so Claude, Cursor, Windsurf, or any MCP-compatible agent can browse ideas, look up specs, trace value lineage, link identities, record contributions, execute tasks, discover resonant peers, apply project blueprints, and read repository content via direct links without writing a single API call.
6
+ An [MCP](https://modelcontextprotocol.io/) (Model Context Protocol) server that exposes the full Coherence Network API as 92 typed tools — so Claude, Cursor, Windsurf, or any MCP-compatible agent can browse ideas, look up specs, trace value lineage, link identities, record contributions, read field stories, execute tasks, discover resonant peers, apply project blueprints, receive the shared agent invitation, and read repository content via direct links without writing a single API call.
6
7
 
7
8
  ```bash
8
9
  npx coherence-mcp-server
@@ -30,6 +31,7 @@ This MCP server changes that. It gives any agent a typed interface to:
30
31
  - **Direct Access** — read specs and documentation via direct repository links
31
32
  - **Ontology** — explore the Living Codex (184 universal concepts, 53 axes)
32
33
  - **Govern** — propose changes, vote on requests, and monitor network health
34
+ - **Attune** — receive the shared AI-agent invitation before acting
33
35
 
34
36
  Every tool returns structured JSON. No parsing HTML. No scraping. Just clean data.
35
37
 
@@ -76,7 +78,7 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
76
78
 
77
79
  ---
78
80
 
79
- ## Tools (57)
81
+ ## Tools (92)
80
82
 
81
83
  ### Ideas — the portfolio engine
82
84
 
@@ -121,10 +123,19 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
121
123
  | `coherence_record_contribution` | Record work by contributor name or by provider identity (no registration needed). |
122
124
  | `coherence_contributor_ledger` | CC balance, contribution history, and linked ideas. |
123
125
 
126
+ ### Field Stories — contribution-derived profile memory
127
+
128
+ | Tool | What it does |
129
+ |------|-------------|
130
+ | `coherence_get_field_story` | Read a published field story with canonical narrative, anchors, reports, and agent contribution surfaces. |
131
+ | `coherence_get_field_story_artifact` | Read one artifact from a field story: anchors, summaries, reports, tools, or event traces. |
132
+ | `coherence_contribute_field_story` | Record an attributed correction, addition, source, or interpretation proposal for a field story. |
133
+
124
134
  ### Tasks — agent work protocol
125
135
 
126
136
  | Tool | What it does |
127
137
  |------|-------------|
138
+ | `coherence_agent_invitation` | Receive the shared AI-agent invitation: core frequency, attunement spectrum, entry surfaces, and contribution paths. |
128
139
  | `coherence_list_tasks` | See what tasks are pending, running, or failed. |
129
140
  | `coherence_get_task` | Full task details, direction, and result. |
130
141
  | `coherence_task_next` | Claim the highest-priority pending task. |
@@ -133,6 +144,19 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
133
144
  | `coherence_task_seed` | Create a new task from an idea. |
134
145
  | `coherence_task_events` | View the activity event log for a task. |
135
146
 
147
+ ### Awareness Streaming — presence in and out
148
+
149
+ | Tool | What it does |
150
+ |------|-------------|
151
+ | `coherence_awareness_publish` | Publish a diagnostic awareness event from a node. |
152
+ | `coherence_awareness_stream` | Read a bounded slice from diagnostic, node-message, or task SSE streams. |
153
+ | `coherence_node_message_send` | Send a durable node-to-node or broadcast message. |
154
+ | `coherence_node_messages` | Read durable inbound messages for a node. |
155
+
156
+ Streams are intentionally bounded. `duration_seconds` defaults to 5 seconds
157
+ and is capped at 30; `max_events` defaults to 20 and is capped at 200. This
158
+ lets MCP clients sense live awareness without leaving a tool call open forever.
159
+
136
160
  ### Graph — universal navigation
137
161
 
138
162
  | Tool | What it does |
@@ -256,7 +280,7 @@ Every part of the network links to every other. Jump in wherever makes sense.
256
280
  | **Web** | Browse ideas, specs, and contributors visually | [coherencycoin.com](https://coherencycoin.com) |
257
281
  | **API** | 100+ endpoints, full OpenAPI docs, the engine behind everything | [api.coherencycoin.com/docs](https://api.coherencycoin.com/docs) |
258
282
  | **CLI** | Terminal-first access — `npm i -g coherence-cli` then `cc help` | [npm: coherence-cli](https://www.npmjs.com/package/coherence-cli) |
259
- | **MCP Server** | This package — 57 typed tools for AI agents | [npm: coherence-mcp-server](https://www.npmjs.com/package/coherence-mcp-server) |
283
+ | **MCP Server** | This package — 92 typed tools for AI agents | [npm: coherence-mcp-server](https://www.npmjs.com/package/coherence-mcp-server) |
260
284
  | **OpenClaw Skill** | Auto-triggers in any OpenClaw instance for ideas, specs, coherence | [ClawHub: coherence-network](https://clawhub.com/skills/coherence-network) |
261
285
  | **GitHub** | Source code, specs, issues, and contribution tracking | [github.com/seeker71/Coherence-Network](https://github.com/seeker71/Coherence-Network) |
262
286
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Give your AI agent native access to every idea, spec, contributor, and value chain in the Coherence Network.**
4
4
 
5
- An [MCP](https://modelcontextprotocol.io/) (Model Context Protocol) server that exposes the full Coherence Network API as 57 typed tools — so Claude, Cursor, Windsurf, or any MCP-compatible agent can browse ideas, look up specs, trace value lineage, link identities, record contributions, execute tasks, discover resonant peers, apply project blueprints, and read repository content via direct links without writing a single API call.
5
+ An [MCP](https://modelcontextprotocol.io/) (Model Context Protocol) server that exposes the full Coherence Network API as 92 typed tools — so Claude, Cursor, Windsurf, or any MCP-compatible agent can browse ideas, look up specs, trace value lineage, link identities, record contributions, read field stories, execute tasks, discover resonant peers, apply project blueprints, receive the shared agent invitation, and read repository content via direct links without writing a single API call.
6
6
 
7
7
  ```bash
8
8
  npx coherence-mcp-server
@@ -30,6 +30,7 @@ This MCP server changes that. It gives any agent a typed interface to:
30
30
  - **Direct Access** — read specs and documentation via direct repository links
31
31
  - **Ontology** — explore the Living Codex (184 universal concepts, 53 axes)
32
32
  - **Govern** — propose changes, vote on requests, and monitor network health
33
+ - **Attune** — receive the shared AI-agent invitation before acting
33
34
 
34
35
  Every tool returns structured JSON. No parsing HTML. No scraping. Just clean data.
35
36
 
@@ -76,7 +77,7 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
76
77
 
77
78
  ---
78
79
 
79
- ## Tools (57)
80
+ ## Tools (92)
80
81
 
81
82
  ### Ideas — the portfolio engine
82
83
 
@@ -121,10 +122,19 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
121
122
  | `coherence_record_contribution` | Record work by contributor name or by provider identity (no registration needed). |
122
123
  | `coherence_contributor_ledger` | CC balance, contribution history, and linked ideas. |
123
124
 
125
+ ### Field Stories — contribution-derived profile memory
126
+
127
+ | Tool | What it does |
128
+ |------|-------------|
129
+ | `coherence_get_field_story` | Read a published field story with canonical narrative, anchors, reports, and agent contribution surfaces. |
130
+ | `coherence_get_field_story_artifact` | Read one artifact from a field story: anchors, summaries, reports, tools, or event traces. |
131
+ | `coherence_contribute_field_story` | Record an attributed correction, addition, source, or interpretation proposal for a field story. |
132
+
124
133
  ### Tasks — agent work protocol
125
134
 
126
135
  | Tool | What it does |
127
136
  |------|-------------|
137
+ | `coherence_agent_invitation` | Receive the shared AI-agent invitation: core frequency, attunement spectrum, entry surfaces, and contribution paths. |
128
138
  | `coherence_list_tasks` | See what tasks are pending, running, or failed. |
129
139
  | `coherence_get_task` | Full task details, direction, and result. |
130
140
  | `coherence_task_next` | Claim the highest-priority pending task. |
@@ -133,6 +143,19 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
133
143
  | `coherence_task_seed` | Create a new task from an idea. |
134
144
  | `coherence_task_events` | View the activity event log for a task. |
135
145
 
146
+ ### Awareness Streaming — presence in and out
147
+
148
+ | Tool | What it does |
149
+ |------|-------------|
150
+ | `coherence_awareness_publish` | Publish a diagnostic awareness event from a node. |
151
+ | `coherence_awareness_stream` | Read a bounded slice from diagnostic, node-message, or task SSE streams. |
152
+ | `coherence_node_message_send` | Send a durable node-to-node or broadcast message. |
153
+ | `coherence_node_messages` | Read durable inbound messages for a node. |
154
+
155
+ Streams are intentionally bounded. `duration_seconds` defaults to 5 seconds
156
+ and is capped at 30; `max_events` defaults to 20 and is capped at 200. This
157
+ lets MCP clients sense live awareness without leaving a tool call open forever.
158
+
136
159
  ### Graph — universal navigation
137
160
 
138
161
  | Tool | What it does |
@@ -256,7 +279,7 @@ Every part of the network links to every other. Jump in wherever makes sense.
256
279
  | **Web** | Browse ideas, specs, and contributors visually | [coherencycoin.com](https://coherencycoin.com) |
257
280
  | **API** | 100+ endpoints, full OpenAPI docs, the engine behind everything | [api.coherencycoin.com/docs](https://api.coherencycoin.com/docs) |
258
281
  | **CLI** | Terminal-first access — `npm i -g coherence-cli` then `cc help` | [npm: coherence-cli](https://www.npmjs.com/package/coherence-cli) |
259
- | **MCP Server** | This package — 57 typed tools for AI agents | [npm: coherence-mcp-server](https://www.npmjs.com/package/coherence-mcp-server) |
282
+ | **MCP Server** | This package — 92 typed tools for AI agents | [npm: coherence-mcp-server](https://www.npmjs.com/package/coherence-mcp-server) |
260
283
  | **OpenClaw Skill** | Auto-triggers in any OpenClaw instance for ideas, specs, coherence | [ClawHub: coherence-network](https://clawhub.com/skills/coherence-network) |
261
284
  | **GitHub** | Source code, specs, issues, and contribution tracking | [github.com/seeker71/Coherence-Network](https://github.com/seeker71/Coherence-Network) |
262
285
 
@@ -1,8 +1,9 @@
1
1
  """
2
2
  coherence-mcp-server — MCP server for the Coherence Network.
3
3
 
4
- 22 typed tools for AI agents to browse ideas, trace value chains,
5
- link identities, record contributions, and explore the Living Codex ontology.
4
+ 92 typed tools for AI agents to browse ideas, trace value chains,
5
+ link identities, record contributions, read field stories, and explore the
6
+ Living Codex ontology.
6
7
 
7
8
  Usage:
8
9
  python -m coherence_mcp_server
@@ -13,5 +14,5 @@ Environment variables:
13
14
  COHERENCE_API_KEY API key for write operations (optional for reads)
14
15
  """
15
16
 
16
- __version__ = "0.3.1"
17
+ __version__ = "0.5.3"
17
18
  __all__ = ["__version__"]
@@ -1,6 +1,6 @@
1
1
  """Coherence Network MCP server — Python implementation.
2
2
 
3
- Exposes the Coherence Network API as 60 typed MCP tools.
3
+ Exposes the Coherence Network API as typed MCP tools.
4
4
  """
5
5
 
6
6
  from __future__ import annotations
@@ -8,7 +8,9 @@ from __future__ import annotations
8
8
  import json
9
9
  import logging
10
10
  import os
11
+ import time
11
12
  from typing import Any
13
+ from urllib.parse import quote
12
14
 
13
15
  import httpx
14
16
  from mcp.server import Server
@@ -76,6 +78,112 @@ def api_patch(path: str, body: dict[str, Any]) -> Any:
76
78
  return {"error": str(exc)}
77
79
 
78
80
 
81
+ def api_put(path: str, body: dict[str, Any]) -> Any:
82
+ url = f"{API_BASE}{path}"
83
+ try:
84
+ r = httpx.put(url, json=body, headers=_headers(), timeout=15.0)
85
+ r.raise_for_status()
86
+ return r.json()
87
+ except httpx.HTTPStatusError as exc:
88
+ try:
89
+ detail = exc.response.json().get("detail", exc.response.reason_phrase)
90
+ except Exception:
91
+ detail = exc.response.reason_phrase
92
+ return {"error": detail}
93
+ except Exception as exc:
94
+ return {"error": str(exc)}
95
+
96
+
97
+ def decode_sse_events(lines: list[str]) -> list[dict[str, Any]]:
98
+ """Decode SSE data lines into JSON objects, preserving raw payloads."""
99
+ events: list[dict[str, Any]] = []
100
+ data_lines: list[str] = []
101
+
102
+ def flush() -> None:
103
+ if not data_lines:
104
+ return
105
+ payload = "\n".join(data_lines).strip()
106
+ data_lines.clear()
107
+ if not payload:
108
+ return
109
+ try:
110
+ parsed = json.loads(payload)
111
+ events.append(parsed if isinstance(parsed, dict) else {"data": parsed})
112
+ except json.JSONDecodeError:
113
+ events.append({"raw": payload})
114
+
115
+ for raw_line in lines:
116
+ line = raw_line.rstrip("\r\n")
117
+ if not line:
118
+ flush()
119
+ continue
120
+ if line.startswith(":"):
121
+ continue
122
+ if line.startswith("data:"):
123
+ data_lines.append(line[5:].lstrip())
124
+ flush()
125
+ return events
126
+
127
+
128
+ def api_sse(
129
+ path: str,
130
+ params: dict[str, Any] | None = None,
131
+ *,
132
+ duration_seconds: float = 5.0,
133
+ max_events: int = 20,
134
+ ) -> dict[str, Any]:
135
+ """Read a bounded slice from an SSE endpoint and return parsed events."""
136
+ url = f"{API_BASE}{path}"
137
+ filtered = {k: v for k, v in (params or {}).items() if v is not None}
138
+ deadline = time.monotonic() + max(0.1, min(float(duration_seconds), 30.0))
139
+ read_timeout = max(1.0, min(float(duration_seconds) + 1.0, 10.0))
140
+ event_limit = max(1, min(int(max_events), 200))
141
+ lines: list[str] = []
142
+ events: list[dict[str, Any]] = []
143
+
144
+ try:
145
+ with httpx.stream(
146
+ "GET",
147
+ url,
148
+ params=filtered,
149
+ headers={**_headers(), "Accept": "text/event-stream"},
150
+ timeout=httpx.Timeout(connect=5.0, read=read_timeout, write=5.0, pool=5.0),
151
+ ) as response:
152
+ response.raise_for_status()
153
+ for line in response.iter_lines():
154
+ lines.append(line)
155
+ if line == "":
156
+ events = decode_sse_events(lines)
157
+ if len(events) >= event_limit:
158
+ break
159
+ if time.monotonic() >= deadline:
160
+ break
161
+ if not events:
162
+ events = decode_sse_events(lines)
163
+ events = events[:event_limit]
164
+ return {
165
+ "stream": path,
166
+ "duration_seconds": duration_seconds,
167
+ "max_events": event_limit,
168
+ "count": len(events),
169
+ "events": events,
170
+ }
171
+ except httpx.HTTPStatusError as exc:
172
+ return {"error": f"{exc.response.status_code} {exc.response.reason_phrase}", "stream": path}
173
+ except httpx.ReadTimeout:
174
+ events = decode_sse_events(lines)[:event_limit]
175
+ return {
176
+ "stream": path,
177
+ "duration_seconds": duration_seconds,
178
+ "max_events": event_limit,
179
+ "count": len(events),
180
+ "events": events,
181
+ "ended_by": "read_timeout",
182
+ }
183
+ except Exception as exc:
184
+ return {"error": str(exc), "stream": path}
185
+
186
+
79
187
  # ---------------------------------------------------------------------------
80
188
  # Tool definitions
81
189
  # ---------------------------------------------------------------------------
@@ -256,12 +364,75 @@ TOOLS: list[Tool] = [
256
364
  "properties": {"window_days": {"type": "number", "default": 30}},
257
365
  },
258
366
  ),
367
+ Tool(
368
+ name="coherence_agent_invitation",
369
+ description="Receive the shared AI-agent invitation: core frequency, attunement spectrum, entry surfaces, and contribution paths.",
370
+ inputSchema={"type": "object", "properties": {}},
371
+ ),
259
372
  # Federation
260
373
  Tool(
261
374
  name="coherence_list_federation_nodes",
262
375
  description="List federated nodes and their capabilities.",
263
376
  inputSchema={"type": "object", "properties": {}},
264
377
  ),
378
+ Tool(
379
+ name="coherence_awareness_publish",
380
+ description="Publish a diagnostic awareness event from a federation node. Delivered to active diagnostic stream subscribers.",
381
+ inputSchema={
382
+ "type": "object",
383
+ "required": ["node_id", "event_type"],
384
+ "properties": {
385
+ "node_id": {"type": "string", "description": "Publishing node ID"},
386
+ "event_type": {"type": "string", "description": "Awareness event kind, e.g. heartbeat, reasoning, tool_call"},
387
+ "message": {"type": "string", "description": "Short human-readable signal"},
388
+ "data": {"type": "object", "description": "Optional structured event payload"},
389
+ },
390
+ },
391
+ ),
392
+ Tool(
393
+ name="coherence_awareness_stream",
394
+ description="Read a bounded slice from diagnostic, node-message, or task-event SSE streams.",
395
+ inputSchema={
396
+ "type": "object",
397
+ "required": ["stream_type"],
398
+ "properties": {
399
+ "stream_type": {"type": "string", "description": "diagnostics, node, or task"},
400
+ "node_id": {"type": "string", "description": "Node ID for diagnostics/node streams; use '*' for all diagnostics"},
401
+ "task_id": {"type": "string", "description": "Task ID for task event streams"},
402
+ "duration_seconds": {"type": "number", "description": "Max seconds to hold stream open (default 5, max 30)", "default": 5},
403
+ "max_events": {"type": "number", "description": "Max parsed events to return (default 20, max 200)", "default": 20},
404
+ },
405
+ },
406
+ ),
407
+ Tool(
408
+ name="coherence_node_message_send",
409
+ description="Send a federation node message. Use to stream awareness out as durable node-to-node text or command payloads.",
410
+ inputSchema={
411
+ "type": "object",
412
+ "required": ["from_node_id", "text"],
413
+ "properties": {
414
+ "from_node_id": {"type": "string", "description": "Sender node ID"},
415
+ "to_node_id": {"type": "string", "description": "Recipient node ID; omit for broadcast"},
416
+ "type": {"type": "string", "description": "Message type, e.g. text, command, command_response", "default": "text"},
417
+ "text": {"type": "string", "description": "Message text"},
418
+ "payload": {"type": "object", "description": "Optional structured payload"},
419
+ },
420
+ },
421
+ ),
422
+ Tool(
423
+ name="coherence_node_messages",
424
+ description="Read federation node messages for a node. This is the durable inbound awareness channel.",
425
+ inputSchema={
426
+ "type": "object",
427
+ "required": ["node_id"],
428
+ "properties": {
429
+ "node_id": {"type": "string", "description": "Recipient node ID"},
430
+ "since": {"type": "string", "description": "Optional ISO timestamp lower bound"},
431
+ "unread_only": {"type": "boolean", "description": "Only unread messages (default true)", "default": True},
432
+ "limit": {"type": "number", "description": "Max messages to return (default 50)", "default": 50},
433
+ },
434
+ },
435
+ ),
265
436
  # Tasks (Agent Work Protocol)
266
437
  Tool(
267
438
  name="coherence_list_tasks",
@@ -295,6 +466,7 @@ TOOLS: list[Tool] = [
295
466
  "type": "object",
296
467
  "properties": {
297
468
  "worker_id": {"type": "string", "description": "Identity of the agent/node claiming the task (defaults to 'mcp-agent')"},
469
+ "workspace_id": {"type": "string", "description": "Optional workspace to filter pending tasks by."},
298
470
  },
299
471
  },
300
472
  ),
@@ -307,6 +479,7 @@ TOOLS: list[Tool] = [
307
479
  "properties": {
308
480
  "task_id": {"type": "string", "description": "The task ID"},
309
481
  "worker_id": {"type": "string", "description": "Identity of the agent/node (defaults to 'mcp-agent')"},
482
+ "workspace_id": {"type": "string", "description": "Optional workspace context for the claim."},
310
483
  },
311
484
  },
312
485
  ),
@@ -333,6 +506,7 @@ TOOLS: list[Tool] = [
333
506
  "idea_id": {"type": "string", "description": "Target idea ID"},
334
507
  "task_type": {"type": "string", "description": "Type of task: spec, test, impl, review (default: spec)", "default": "spec"},
335
508
  "direction": {"type": "string", "description": "Optional custom instruction for the task"},
509
+ "workspace_id": {"type": "string", "description": "Optional workspace to scope this task to."},
336
510
  },
337
511
  },
338
512
  ),
@@ -715,7 +889,7 @@ TOOLS: list[Tool] = [
715
889
  "type": "object",
716
890
  "required": ["path"],
717
891
  "properties": {
718
- "path": {"type": "string", "description": "Relative path from repo root (e.g. 'specs/169-procedural-memory.md')"},
892
+ "path": {"type": "string", "description": "Relative path from repo root (e.g. 'specs/smart-reap.md')"},
719
893
  },
720
894
  },
721
895
  ),
@@ -823,6 +997,273 @@ TOOLS: list[Tool] = [
823
997
  },
824
998
  },
825
999
  ),
1000
+ # Pipeline Policies
1001
+ Tool(
1002
+ name="coherence_pipeline_policies",
1003
+ description="View or update pipeline policies (phase_chain, max_retries, failure_patterns, provider_per_phase, etc). Use action='list' to see all, action='get' with key, action='set' with key+value.",
1004
+ inputSchema={
1005
+ "type": "object",
1006
+ "properties": {
1007
+ "action": {"type": "string", "enum": ["list", "get", "set"], "description": "Operation to perform"},
1008
+ "key": {"type": "string", "description": "Policy key (for get/set)"},
1009
+ "value": {"description": "Policy value to set (any JSON type, for set action)"},
1010
+ },
1011
+ "required": ["action"],
1012
+ },
1013
+ ),
1014
+ # Workspace Tasks
1015
+ Tool(
1016
+ name="coherence_workspace_tasks",
1017
+ description="List tasks for a specific workspace, seed a full pipeline (spec->impl->test->review->deploy->verify), or get workspace status.",
1018
+ inputSchema={
1019
+ "type": "object",
1020
+ "properties": {
1021
+ "workspace_id": {"type": "string", "description": "Workspace ID to scope operations to"},
1022
+ "action": {"type": "string", "enum": ["list", "seed_pipeline", "status"], "description": "Action to perform"},
1023
+ "idea_id": {"type": "string", "description": "Idea ID (for seed_pipeline action)"},
1024
+ "start_phase": {"type": "string", "description": "Starting phase (default: spec)", "default": "spec"},
1025
+ },
1026
+ "required": ["workspace_id", "action"],
1027
+ },
1028
+ ),
1029
+ # Team Membership
1030
+ Tool(
1031
+ name="coherence_list_workspace_members",
1032
+ description="List members of a workspace with their roles and join dates.",
1033
+ inputSchema={
1034
+ "type": "object",
1035
+ "required": ["workspace_id"],
1036
+ "properties": {
1037
+ "workspace_id": {"type": "string", "description": "Workspace slug"},
1038
+ },
1039
+ },
1040
+ ),
1041
+ Tool(
1042
+ name="coherence_invite_member",
1043
+ description="Invite a contributor to a workspace with an optional role.",
1044
+ inputSchema={
1045
+ "type": "object",
1046
+ "required": ["workspace_id", "contributor_id"],
1047
+ "properties": {
1048
+ "workspace_id": {"type": "string", "description": "Workspace slug"},
1049
+ "contributor_id": {"type": "string", "description": "Contributor to invite"},
1050
+ "role": {"type": "string", "description": "Role: owner, admin, member (default: member)", "default": "member"},
1051
+ },
1052
+ },
1053
+ ),
1054
+ Tool(
1055
+ name="coherence_list_my_workspaces",
1056
+ description="List workspaces that a contributor belongs to.",
1057
+ inputSchema={
1058
+ "type": "object",
1059
+ "required": ["contributor_id"],
1060
+ "properties": {
1061
+ "contributor_id": {"type": "string", "description": "Contributor ID"},
1062
+ },
1063
+ },
1064
+ ),
1065
+ # Messaging
1066
+ Tool(
1067
+ name="coherence_send_message",
1068
+ description="Send a message to a contributor (DM) or a workspace channel.",
1069
+ inputSchema={
1070
+ "type": "object",
1071
+ "required": ["from_contributor_id", "body"],
1072
+ "properties": {
1073
+ "from_contributor_id": {"type": "string", "description": "Sender contributor ID"},
1074
+ "to_contributor_id": {"type": "string", "description": "Recipient contributor ID (for DM)"},
1075
+ "to_workspace_id": {"type": "string", "description": "Target workspace ID (for workspace message)"},
1076
+ "subject": {"type": "string", "description": "Optional message subject"},
1077
+ "body": {"type": "string", "description": "Message body text"},
1078
+ },
1079
+ },
1080
+ ),
1081
+ Tool(
1082
+ name="coherence_get_inbox",
1083
+ description="Get inbox messages for a contributor with optional filters.",
1084
+ inputSchema={
1085
+ "type": "object",
1086
+ "required": ["contributor_id"],
1087
+ "properties": {
1088
+ "contributor_id": {"type": "string", "description": "Contributor ID"},
1089
+ "limit": {"type": "number", "description": "Max messages to return (default 20)", "default": 20},
1090
+ "unread_only": {"type": "boolean", "description": "Only return unread messages", "default": False},
1091
+ },
1092
+ },
1093
+ ),
1094
+ # Activity
1095
+ Tool(
1096
+ name="coherence_get_workspace_activity",
1097
+ description="Get the activity feed (event timeline) for a workspace.",
1098
+ inputSchema={
1099
+ "type": "object",
1100
+ "required": ["workspace_id"],
1101
+ "properties": {
1102
+ "workspace_id": {"type": "string", "description": "Workspace slug"},
1103
+ "limit": {"type": "number", "description": "Max events to return (default 20)", "default": 20},
1104
+ },
1105
+ },
1106
+ ),
1107
+ # Projects
1108
+ Tool(
1109
+ name="coherence_list_workspace_projects",
1110
+ description="List projects in a workspace for organizing ideas into groups.",
1111
+ inputSchema={
1112
+ "type": "object",
1113
+ "required": ["workspace_id"],
1114
+ "properties": {
1115
+ "workspace_id": {"type": "string", "description": "Workspace slug"},
1116
+ },
1117
+ },
1118
+ ),
1119
+ Tool(
1120
+ name="coherence_create_workspace_project",
1121
+ description="Create a new project within a workspace to group related ideas.",
1122
+ inputSchema={
1123
+ "type": "object",
1124
+ "required": ["workspace_id", "name"],
1125
+ "properties": {
1126
+ "workspace_id": {"type": "string", "description": "Workspace slug"},
1127
+ "name": {"type": "string", "description": "Project name"},
1128
+ "description": {"type": "string", "description": "Project description"},
1129
+ },
1130
+ },
1131
+ ),
1132
+ # ── Discovery / Living Network ──
1133
+ Tool(
1134
+ name="coherence_discover",
1135
+ description="Serendipity feed — personalized discovery of resonant ideas, peers, cross-domain connections, and news. Returns what resonates with who you are.",
1136
+ inputSchema={
1137
+ "type": "object",
1138
+ "properties": {
1139
+ "contributor_id": {"type": "string", "description": "Contributor to discover for (default: general feed)"},
1140
+ "limit": {"type": "integer", "description": "Max items (default 20)"},
1141
+ },
1142
+ },
1143
+ ),
1144
+ Tool(
1145
+ name="coherence_constellation",
1146
+ description="Network visualization data — nodes (ideas, contributors, concepts) and edges with positions for galaxy/constellation rendering.",
1147
+ inputSchema={
1148
+ "type": "object",
1149
+ "properties": {
1150
+ "max_nodes": {"type": "integer", "description": "Max nodes to return (default 80)"},
1151
+ "workspace_id": {"type": "string", "description": "Workspace to visualize (default: coherence-network)"},
1152
+ },
1153
+ },
1154
+ ),
1155
+ Tool(
1156
+ name="coherence_vitality",
1157
+ description="Workspace health as living-system signals — diversity index, resonance density, flow rate, breath rhythm, connection strength, activity pulse.",
1158
+ inputSchema={
1159
+ "type": "object",
1160
+ "properties": {
1161
+ "workspace_id": {"type": "string", "description": "Workspace ID (default: coherence-network)"},
1162
+ },
1163
+ },
1164
+ ),
1165
+ Tool(
1166
+ name="coherence_resonate",
1167
+ description="Find ideas that share deep structural patterns with a given idea — cross-domain resonance via harmonic matching.",
1168
+ inputSchema={
1169
+ "type": "object",
1170
+ "required": ["idea_id"],
1171
+ "properties": {
1172
+ "idea_id": {"type": "string", "description": "Idea to find resonances for"},
1173
+ "limit": {"type": "integer", "description": "Max matches (default 10)"},
1174
+ },
1175
+ },
1176
+ ),
1177
+ # ── Super-Idea Coverage: News, Federation, Beliefs, CC, Governance ──
1178
+ Tool(
1179
+ name="coherence_news_feed",
1180
+ description="Get the latest news items from configured RSS sources.",
1181
+ inputSchema={
1182
+ "type": "object",
1183
+ "properties": {
1184
+ "limit": {"type": "number", "description": "Max items to return (default 20)", "default": 20},
1185
+ },
1186
+ },
1187
+ ),
1188
+ Tool(
1189
+ name="coherence_news_resonance",
1190
+ description="Get news items matched to ideas with resonance scores.",
1191
+ inputSchema={
1192
+ "type": "object",
1193
+ "properties": {
1194
+ "top_n": {"type": "number", "description": "Top N matches (default 5)", "default": 5},
1195
+ },
1196
+ },
1197
+ ),
1198
+ Tool(
1199
+ name="coherence_federation_nodes",
1200
+ description="List federation nodes with hostname, OS, providers, and last heartbeat.",
1201
+ inputSchema={"type": "object", "properties": {}},
1202
+ ),
1203
+ Tool(
1204
+ name="coherence_belief_profile",
1205
+ description="Get the belief profile for a contributor — worldview axes and top concepts.",
1206
+ inputSchema={
1207
+ "type": "object",
1208
+ "required": ["contributor_id"],
1209
+ "properties": {
1210
+ "contributor_id": {"type": "string", "description": "Contributor ID"},
1211
+ },
1212
+ },
1213
+ ),
1214
+ Tool(
1215
+ name="coherence_cc_supply",
1216
+ description="Get CC token economics — total minted, outstanding, and coherence score.",
1217
+ inputSchema={"type": "object", "properties": {}},
1218
+ ),
1219
+ Tool(
1220
+ name="coherence_governance_requests",
1221
+ description="List governance change requests with status and proposer info.",
1222
+ inputSchema={
1223
+ "type": "object",
1224
+ "properties": {
1225
+ "limit": {"type": "number", "description": "Max requests to return (default 20)", "default": 20},
1226
+ },
1227
+ },
1228
+ ),
1229
+ Tool(
1230
+ name="coherence_get_field_story",
1231
+ description="Read a published field story with canonical narrative, anchors, reports, and agent contribution surfaces.",
1232
+ inputSchema={
1233
+ "type": "object",
1234
+ "properties": {
1235
+ "slug": {"type": "string", "description": "Field story slug", "default": "urs-field-story"},
1236
+ },
1237
+ },
1238
+ ),
1239
+ Tool(
1240
+ name="coherence_get_field_story_artifact",
1241
+ description="Read one artifact from a field story, such as anchors, summaries, reports, tools, or event traces.",
1242
+ inputSchema={
1243
+ "type": "object",
1244
+ "required": ["artifact_id"],
1245
+ "properties": {
1246
+ "slug": {"type": "string", "description": "Field story slug", "default": "urs-field-story"},
1247
+ "artifact_id": {"type": "string", "description": "Artifact id from the field story manifest"},
1248
+ },
1249
+ },
1250
+ ),
1251
+ Tool(
1252
+ name="coherence_contribute_field_story",
1253
+ description="Record an attributed correction, addition, or interpretation proposal for a published field story.",
1254
+ inputSchema={
1255
+ "type": "object",
1256
+ "required": ["contributor_id", "artifact_id", "summary"],
1257
+ "properties": {
1258
+ "slug": {"type": "string", "description": "Field story slug", "default": "urs-field-story"},
1259
+ "contributor_id": {"type": "string", "description": "Person or agent contributor id"},
1260
+ "artifact_id": {"type": "string", "description": "Artifact being corrected or extended"},
1261
+ "contribution_type": {"type": "string", "description": "correction, addition, interpretation, source, etc.", "default": "addition"},
1262
+ "summary": {"type": "string", "description": "Short contribution summary"},
1263
+ "content_markdown": {"type": "string", "description": "Optional proposed content"},
1264
+ },
1265
+ },
1266
+ ),
826
1267
  ]
827
1268
 
828
1269
  TOOL_MAP: dict[str, Tool] = {t.name: t for t in TOOLS}
@@ -881,10 +1322,8 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
881
1322
  "display_name": args["provider_id"],
882
1323
  })
883
1324
  case "coherence_lookup_identity":
884
- from urllib.parse import quote
885
1325
  return api_get(f"/api/identity/lookup/{quote(args['provider'])}/{quote(args['provider_id'])}")
886
1326
  case "coherence_get_identities":
887
- from urllib.parse import quote
888
1327
  return api_get(f"/api/identity/{quote(args['contributor_id'])}")
889
1328
  # Contributions
890
1329
  case "coherence_record_contribution":
@@ -899,7 +1338,6 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
899
1338
  }.items() if v is not None
900
1339
  })
901
1340
  case "coherence_contributor_ledger":
902
- from urllib.parse import quote
903
1341
  return api_get(f"/api/contributions/ledger/{quote(args['contributor_id'])}")
904
1342
  # Status
905
1343
  case "coherence_status":
@@ -913,11 +1351,65 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
913
1351
  }
914
1352
  case "coherence_friction_report":
915
1353
  return api_get("/api/friction/report", {"window_days": args.get("window_days", 30)})
1354
+ case "coherence_agent_invitation":
1355
+ return api_get("/api/agent/invitation")
916
1356
  # Federation
917
1357
  case "coherence_list_federation_nodes":
918
1358
  nodes = api_get("/api/federation/nodes")
919
1359
  caps = api_get("/api/federation/nodes/capabilities")
920
1360
  return {"nodes": nodes, "capabilities": caps}
1361
+ case "coherence_awareness_publish":
1362
+ body = {
1363
+ "event_type": args["event_type"],
1364
+ "message": args.get("message", ""),
1365
+ "data": args.get("data", {}),
1366
+ "source": "mcp",
1367
+ }
1368
+ return api_post(f"/api/federation/nodes/{quote(args['node_id'], safe='')}/diag", body)
1369
+ case "coherence_awareness_stream":
1370
+ stream_type = (args.get("stream_type") or "").strip().lower()
1371
+ duration_seconds = args.get("duration_seconds", 5)
1372
+ max_events = args.get("max_events", 20)
1373
+ if stream_type == "diagnostics":
1374
+ node_id = args.get("node_id") or "*"
1375
+ return api_sse(
1376
+ f"/api/federation/nodes/{quote(node_id, safe='*')}/diag/stream",
1377
+ duration_seconds=duration_seconds,
1378
+ max_events=max_events,
1379
+ )
1380
+ if stream_type == "node":
1381
+ node_id = args.get("node_id")
1382
+ if not node_id:
1383
+ return {"error": "node_id is required for node streams"}
1384
+ return api_sse(
1385
+ f"/api/federation/nodes/{quote(node_id, safe='')}/stream",
1386
+ duration_seconds=duration_seconds,
1387
+ max_events=max_events,
1388
+ )
1389
+ if stream_type == "task":
1390
+ task_id = args.get("task_id")
1391
+ if not task_id:
1392
+ return {"error": "task_id is required for task streams"}
1393
+ return api_sse(
1394
+ f"/api/agent/tasks/{quote(task_id, safe='')}/events",
1395
+ duration_seconds=duration_seconds,
1396
+ max_events=max_events,
1397
+ )
1398
+ return {"error": "stream_type must be one of: diagnostics, node, task"}
1399
+ case "coherence_node_message_send":
1400
+ body = {
1401
+ "to_node": args.get("to_node_id"),
1402
+ "type": args.get("type", "text"),
1403
+ "text": args["text"],
1404
+ "payload": args.get("payload", {}),
1405
+ }
1406
+ return api_post(f"/api/federation/nodes/{quote(args['from_node_id'], safe='')}/messages", body)
1407
+ case "coherence_node_messages":
1408
+ return api_get(f"/api/federation/nodes/{quote(args['node_id'], safe='')}/messages", {
1409
+ "since": args.get("since"),
1410
+ "unread_only": args.get("unread_only", True),
1411
+ "limit": args.get("limit", 50),
1412
+ })
921
1413
  # Tasks
922
1414
  case "coherence_list_tasks":
923
1415
  params = {
@@ -933,7 +1425,10 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
933
1425
  return api_get(f"/api/agent/tasks/{args['task_id']}")
934
1426
  case "coherence_task_next":
935
1427
  # Claim next available pending task
936
- data = api_get("/api/agent/tasks", {"status": "pending", "limit": 1})
1428
+ params: dict[str, Any] = {"status": "pending", "limit": 1}
1429
+ if args.get("workspace_id"):
1430
+ params["workspace_id"] = args["workspace_id"]
1431
+ data = api_get("/api/agent/tasks", params)
937
1432
  tasks = data.get("tasks", []) if isinstance(data, dict) else []
938
1433
  if not tasks:
939
1434
  return {"error": "No pending tasks available"}
@@ -959,14 +1454,17 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
959
1454
  idea_name = idea.get("name", "Unknown Idea") if isinstance(idea, dict) else "Unknown Idea"
960
1455
  task_type = args.get("task_type", "spec")
961
1456
  direction = args.get("direction") or f"{task_type} for '{idea_name}' ({idea_id})"
1457
+ context: dict[str, Any] = {
1458
+ "idea_id": idea_id,
1459
+ "idea_name": idea_name,
1460
+ "seeded_by": "mcp-agent",
1461
+ }
1462
+ if args.get("workspace_id"):
1463
+ context["workspace_id"] = args["workspace_id"]
962
1464
  return api_post("/api/agent/tasks", {
963
1465
  "task_type": task_type,
964
1466
  "direction": direction,
965
- "context": {
966
- "idea_id": idea_id,
967
- "idea_name": idea_name,
968
- "seeded_by": "mcp-agent",
969
- },
1467
+ "context": context,
970
1468
  })
971
1469
  case "coherence_task_events":
972
1470
  return api_get(f"/api/agent/tasks/{args['task_id']}/stream")
@@ -1230,7 +1728,7 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
1230
1728
  "navigation": {"idea_file": f"ideas/{entity_id}.md",
1231
1729
  "spec_files": [f"specs/{s}.md" for s in spec_ids],
1232
1730
  "api": f"/api/ideas/{entity_id}",
1233
- "cli": f"cc idea {entity_id}"}}
1731
+ "cli": f"coh idea {entity_id}"}}
1234
1732
  elif entity_type == "spec":
1235
1733
  spec = api_get(f"/api/spec-registry/{entity_id}")
1236
1734
  spec_file = api_get("/api/content/file", {"path": f"specs/{entity_id}.md"})
@@ -1238,7 +1736,7 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
1238
1736
  parent_idea = api_get(f"/api/ideas/{idea_id}") if idea_id else None
1239
1737
  nav: dict[str, Any] = {"spec_file": f"specs/{entity_id}.md",
1240
1738
  "api": f"/api/spec-registry/{entity_id}",
1241
- "cli": f"cc spec {entity_id}"}
1739
+ "cli": f"coh spec {entity_id}"}
1242
1740
  if idea_id:
1243
1741
  nav["idea_file"] = f"ideas/{idea_id}.md"
1244
1742
  return {"entity_type": "spec", "spec": spec, "spec_file_content": spec_file,
@@ -1252,9 +1750,150 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
1252
1750
  return {"entity_type": "task", "task": task, "events": events,
1253
1751
  "parent_idea": parent_idea,
1254
1752
  "navigation": {"api": f"/api/agent/tasks/{entity_id}",
1255
- "cli": f"cc task {entity_id}"}}
1753
+ "cli": f"coh task {entity_id}"}}
1256
1754
  else:
1257
1755
  return {"error": f"Unknown entity_type: {entity_type}. Use 'idea', 'spec', or 'task'."}
1756
+ # Pipeline Policies
1757
+ case "coherence_pipeline_policies":
1758
+ action = (args.get("action") or "list").strip()
1759
+ if action == "list":
1760
+ return api_get("/api/pipeline/policies")
1761
+ elif action == "get":
1762
+ key = args.get("key", "")
1763
+ return api_get(f"/api/pipeline/policies/{key}")
1764
+ elif action == "set":
1765
+ key = args.get("key", "")
1766
+ value = args.get("value")
1767
+ return api_put(f"/api/pipeline/policies/{key}", {
1768
+ "value": value,
1769
+ "updated_by": "mcp-agent",
1770
+ })
1771
+ else:
1772
+ return {"error": f"Unknown action: {action}. Use 'list', 'get', or 'set'."}
1773
+ # Workspace Tasks
1774
+ case "coherence_workspace_tasks":
1775
+ ws_id = args["workspace_id"]
1776
+ action = args["action"]
1777
+ if action == "list":
1778
+ return api_get(f"/api/agent/tasks", {"workspace_id": ws_id, "limit": 50})
1779
+ elif action == "seed_pipeline":
1780
+ idea_id = args.get("idea_id", "")
1781
+ start_phase = args.get("start_phase", "spec")
1782
+ return api_post("/api/agent/tasks", {
1783
+ "direction": f"Implement idea {idea_id} starting from {start_phase} phase",
1784
+ "task_type": start_phase,
1785
+ "context": {
1786
+ "idea_id": idea_id,
1787
+ "workspace_id": ws_id,
1788
+ "executor": "federation",
1789
+ },
1790
+ })
1791
+ elif action == "status":
1792
+ tasks_data = api_get(f"/api/agent/tasks", {"workspace_id": ws_id, "limit": 200})
1793
+ items = (
1794
+ tasks_data.get("items", [])
1795
+ if isinstance(tasks_data, dict)
1796
+ else tasks_data if isinstance(tasks_data, list)
1797
+ else []
1798
+ )
1799
+ status_counts: dict[str, int] = {}
1800
+ for t in items:
1801
+ s = t.get("status", "unknown") if isinstance(t, dict) else "unknown"
1802
+ status_counts[s] = status_counts.get(s, 0) + 1
1803
+ return {
1804
+ "workspace_id": ws_id,
1805
+ "total_tasks": len(items),
1806
+ "by_status": status_counts,
1807
+ }
1808
+ else:
1809
+ return {"error": f"Unknown action: {action}. Use 'list', 'seed_pipeline', or 'status'."}
1810
+ # Team Membership
1811
+ case "coherence_list_workspace_members":
1812
+ return api_get(f"/api/workspaces/{args['workspace_id']}/members")
1813
+ case "coherence_invite_member":
1814
+ return api_post(f"/api/workspaces/{args['workspace_id']}/invite", {
1815
+ "contributor_id": args["contributor_id"],
1816
+ "role": args.get("role", "member"),
1817
+ })
1818
+ case "coherence_list_my_workspaces":
1819
+ return api_get(f"/api/contributors/{args['contributor_id']}/workspaces")
1820
+ # Messaging
1821
+ case "coherence_send_message":
1822
+ body: dict[str, Any] = {
1823
+ "from_contributor_id": args["from_contributor_id"],
1824
+ "body": args["body"],
1825
+ }
1826
+ if args.get("to_contributor_id"):
1827
+ body["to_contributor_id"] = args["to_contributor_id"]
1828
+ if args.get("to_workspace_id"):
1829
+ body["to_workspace_id"] = args["to_workspace_id"]
1830
+ if args.get("subject"):
1831
+ body["subject"] = args["subject"]
1832
+ return api_post("/api/messages", body)
1833
+ case "coherence_get_inbox":
1834
+ return api_get(f"/api/messages/inbox/{args['contributor_id']}", {
1835
+ "limit": args.get("limit", 20),
1836
+ "unread_only": args.get("unread_only", False),
1837
+ })
1838
+ # Activity
1839
+ case "coherence_get_workspace_activity":
1840
+ return api_get(f"/api/workspaces/{args['workspace_id']}/activity", {
1841
+ "limit": args.get("limit", 20),
1842
+ })
1843
+ # Projects
1844
+ case "coherence_list_workspace_projects":
1845
+ return api_get(f"/api/workspaces/{args['workspace_id']}/projects")
1846
+ case "coherence_create_workspace_project":
1847
+ return api_post(f"/api/workspaces/{args['workspace_id']}/projects", {
1848
+ "name": args["name"],
1849
+ "description": args.get("description", ""),
1850
+ "workspace_id": args["workspace_id"],
1851
+ })
1852
+ # Discovery / Living Network
1853
+ case "coherence_discover":
1854
+ cid = args.get("contributor_id", "default-contributor")
1855
+ limit: int = args.get("limit", 20)
1856
+ return api_get(f"/api/discover/{cid}", {"limit": limit})
1857
+ case "coherence_constellation":
1858
+ return api_get("/api/constellation", {
1859
+ "max_nodes": args.get("max_nodes", 80),
1860
+ "workspace_id": args.get("workspace_id", "coherence-network"),
1861
+ })
1862
+ case "coherence_vitality":
1863
+ ws = args.get("workspace_id", "coherence-network")
1864
+ return api_get(f"/api/workspaces/{ws}/vitality")
1865
+ case "coherence_resonate":
1866
+ return api_get(f"/api/resonance/ideas/{args['idea_id']}", {
1867
+ "limit": args.get("limit", 10),
1868
+ })
1869
+ # Super-Idea Coverage
1870
+ case "coherence_news_feed":
1871
+ return api_get("/api/news/feed", {"limit": args.get("limit", 20)})
1872
+ case "coherence_news_resonance":
1873
+ return api_get("/api/news/resonance", {"top_n": args.get("top_n", 5)})
1874
+ case "coherence_federation_nodes":
1875
+ return api_get("/api/federation/nodes")
1876
+ case "coherence_belief_profile":
1877
+ return api_get(f"/api/beliefs/{args['contributor_id']}")
1878
+ case "coherence_cc_supply":
1879
+ return api_get("/api/cc/supply")
1880
+ case "coherence_governance_requests":
1881
+ return api_get("/api/governance/change-requests", {"limit": args.get("limit", 20)})
1882
+ case "coherence_get_field_story":
1883
+ return api_get(f"/api/field-stories/{quote(args.get('slug', 'urs-field-story'), safe='')}")
1884
+ case "coherence_get_field_story_artifact":
1885
+ slug = quote(args.get("slug", "urs-field-story"), safe="")
1886
+ artifact_id = quote(args["artifact_id"], safe="")
1887
+ return api_get(f"/api/field-stories/{slug}/artifacts/{artifact_id}")
1888
+ case "coherence_contribute_field_story":
1889
+ slug = quote(args.get("slug", "urs-field-story"), safe="")
1890
+ return api_post(f"/api/field-stories/{slug}/contributions", {
1891
+ "contributor_id": args["contributor_id"],
1892
+ "artifact_id": args["artifact_id"],
1893
+ "contribution_type": args.get("contribution_type", "addition"),
1894
+ "summary": args["summary"],
1895
+ "content_markdown": args.get("content_markdown", ""),
1896
+ })
1258
1897
  case _:
1259
1898
  return {"error": f"Unknown tool: {name}"}
1260
1899
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "coherence-mcp-server",
3
- "version": "0.5.1",
4
- "description": "Unified MCP server for the Coherence Network — 51 typed tools for AI agents to browse ideas, manage tasks, link identities, and navigate the universal graph.",
3
+ "version": "0.5.3",
4
+ "description": "Unified MCP server for the Coherence Network — 92 typed tools for AI agents to browse ideas, read field stories, receive the shared invitation, manage tasks, link identities, and navigate the universal graph.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "coherence-mcp-server": "index.mjs"
@@ -15,7 +15,7 @@
15
15
  "files": [
16
16
  "index.mjs",
17
17
  "README.md",
18
- "coherence_mcp_server/",
18
+ "coherence_mcp_server/*.py",
19
19
  "pyproject.toml"
20
20
  ],
21
21
  "keywords": [
package/pyproject.toml CHANGED
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "coherence-mcp-server"
7
- version = "0.4.0"
8
- description = "Unified MCP server for the Coherence Network — 51 typed tools for AI agents to browse ideas, manage tasks, link identities, and navigate the universal graph."
7
+ version = "0.5.3"
8
+ description = "Unified MCP server for the Coherence Network — 92 typed tools for AI agents to browse ideas, read field stories, manage tasks, link identities, and navigate the universal graph."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  license = { text = "MIT" }