coherence-mcp-server 0.4.4 → 0.5.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 +11 -4
- package/README.template.md +11 -4
- package/coherence_mcp_server/__pycache__/__init__.cpython-314.pyc +0 -0
- package/coherence_mcp_server/__pycache__/server.cpython-314.pyc +0 -0
- package/coherence_mcp_server/server.py +278 -14
- package/package.json +1 -1
- package/coherence_mcp_server/__pycache__/__main__.cpython-314.pyc +0 -0
package/README.md
CHANGED
|
@@ -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
|
|
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
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npx coherence-mcp-server
|
|
@@ -27,6 +27,7 @@ This MCP server changes that. It gives any agent a typed interface to:
|
|
|
27
27
|
- **Signal** — ingest news, track trending keywords, and measure concept resonance
|
|
28
28
|
- **Peers** — discover resonant contributors by shared interests or proximity
|
|
29
29
|
- **Blueprint** — apply standardized project roadmaps (templates) to instantly seed work
|
|
30
|
+
- **Direct Access** — read specs and documentation via direct repository links
|
|
30
31
|
- **Ontology** — explore the Living Codex (184 universal concepts, 53 axes)
|
|
31
32
|
- **Govern** — propose changes, vote on requests, and monitor network health
|
|
32
33
|
|
|
@@ -75,7 +76,7 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
|
|
|
75
76
|
|
|
76
77
|
---
|
|
77
78
|
|
|
78
|
-
## Tools (
|
|
79
|
+
## Tools (57)
|
|
79
80
|
|
|
80
81
|
### Ideas — the portfolio engine
|
|
81
82
|
|
|
@@ -95,7 +96,7 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
|
|
|
95
96
|
| Tool | What it does |
|
|
96
97
|
|------|-------------|
|
|
97
98
|
| `coherence_list_specs` | Specs with ROI metrics and value gaps. Searchable. |
|
|
98
|
-
| `coherence_get_spec
|
|
99
|
+
| `coherence_get_spec` | Full spec: summary, implementation plan, pseudocode, estimated ROI. |
|
|
99
100
|
|
|
100
101
|
### Value lineage — end-to-end traceability
|
|
101
102
|
|
|
@@ -154,6 +155,12 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
|
|
|
154
155
|
| `coherence_list_blueprints` | List available project roadmap templates. |
|
|
155
156
|
| `coherence_apply_blueprint` | Seed a full roadmap of ideas and edges from a template. |
|
|
156
157
|
|
|
158
|
+
### Repository Content — direct access
|
|
159
|
+
|
|
160
|
+
| Tool | What it does |
|
|
161
|
+
|------|-------------|
|
|
162
|
+
| `coherence_read_file` | Read raw file content (specs, docs) via direct link. |
|
|
163
|
+
|
|
157
164
|
### Assets — tracked artifacts
|
|
158
165
|
|
|
159
166
|
| Tool | What it does |
|
|
@@ -249,7 +256,7 @@ Every part of the network links to every other. Jump in wherever makes sense.
|
|
|
249
256
|
| **Web** | Browse ideas, specs, and contributors visually | [coherencycoin.com](https://coherencycoin.com) |
|
|
250
257
|
| **API** | 100+ endpoints, full OpenAPI docs, the engine behind everything | [api.coherencycoin.com/docs](https://api.coherencycoin.com/docs) |
|
|
251
258
|
| **CLI** | Terminal-first access — `npm i -g coherence-cli` then `cc help` | [npm: coherence-cli](https://www.npmjs.com/package/coherence-cli) |
|
|
252
|
-
| **MCP Server** | This package —
|
|
259
|
+
| **MCP Server** | This package — 57 typed tools for AI agents | [npm: coherence-mcp-server](https://www.npmjs.com/package/coherence-mcp-server) |
|
|
253
260
|
| **OpenClaw Skill** | Auto-triggers in any OpenClaw instance for ideas, specs, coherence | [ClawHub: coherence-network](https://clawhub.com/skills/coherence-network) |
|
|
254
261
|
| **GitHub** | Source code, specs, issues, and contribution tracking | [github.com/seeker71/Coherence-Network](https://github.com/seeker71/Coherence-Network) |
|
|
255
262
|
|
package/README.template.md
CHANGED
|
@@ -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
|
|
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
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npx coherence-mcp-server
|
|
@@ -27,6 +27,7 @@ This MCP server changes that. It gives any agent a typed interface to:
|
|
|
27
27
|
- **Signal** — ingest news, track trending keywords, and measure concept resonance
|
|
28
28
|
- **Peers** — discover resonant contributors by shared interests or proximity
|
|
29
29
|
- **Blueprint** — apply standardized project roadmaps (templates) to instantly seed work
|
|
30
|
+
- **Direct Access** — read specs and documentation via direct repository links
|
|
30
31
|
- **Ontology** — explore the Living Codex (184 universal concepts, 53 axes)
|
|
31
32
|
- **Govern** — propose changes, vote on requests, and monitor network health
|
|
32
33
|
|
|
@@ -75,7 +76,7 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
|
|
|
75
76
|
|
|
76
77
|
---
|
|
77
78
|
|
|
78
|
-
## Tools (
|
|
79
|
+
## Tools (57)
|
|
79
80
|
|
|
80
81
|
### Ideas — the portfolio engine
|
|
81
82
|
|
|
@@ -95,7 +96,7 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
|
|
|
95
96
|
| Tool | What it does |
|
|
96
97
|
|------|-------------|
|
|
97
98
|
| `coherence_list_specs` | Specs with ROI metrics and value gaps. Searchable. |
|
|
98
|
-
| `coherence_get_spec
|
|
99
|
+
| `coherence_get_spec` | Full spec: summary, implementation plan, pseudocode, estimated ROI. |
|
|
99
100
|
|
|
100
101
|
### Value lineage — end-to-end traceability
|
|
101
102
|
|
|
@@ -154,6 +155,12 @@ Point your MCP client at `npx coherence-mcp-server` via stdio transport.
|
|
|
154
155
|
| `coherence_list_blueprints` | List available project roadmap templates. |
|
|
155
156
|
| `coherence_apply_blueprint` | Seed a full roadmap of ideas and edges from a template. |
|
|
156
157
|
|
|
158
|
+
### Repository Content — direct access
|
|
159
|
+
|
|
160
|
+
| Tool | What it does |
|
|
161
|
+
|------|-------------|
|
|
162
|
+
| `coherence_read_file` | Read raw file content (specs, docs) via direct link. |
|
|
163
|
+
|
|
157
164
|
### Assets — tracked artifacts
|
|
158
165
|
|
|
159
166
|
| Tool | What it does |
|
|
@@ -249,7 +256,7 @@ Every part of the network links to every other. Jump in wherever makes sense.
|
|
|
249
256
|
| **Web** | Browse ideas, specs, and contributors visually | [coherencycoin.com](https://coherencycoin.com) |
|
|
250
257
|
| **API** | 100+ endpoints, full OpenAPI docs, the engine behind everything | [api.coherencycoin.com/docs](https://api.coherencycoin.com/docs) |
|
|
251
258
|
| **CLI** | Terminal-first access — `npm i -g coherence-cli` then `cc help` | [npm: coherence-cli](https://www.npmjs.com/package/coherence-cli) |
|
|
252
|
-
| **MCP Server** | This package —
|
|
259
|
+
| **MCP Server** | This package — 57 typed tools for AI agents | [npm: coherence-mcp-server](https://www.npmjs.com/package/coherence-mcp-server) |
|
|
253
260
|
| **OpenClaw Skill** | Auto-triggers in any OpenClaw instance for ideas, specs, coherence | [ClawHub: coherence-network](https://clawhub.com/skills/coherence-network) |
|
|
254
261
|
| **GitHub** | Source code, specs, issues, and contribution tracking | [github.com/seeker71/Coherence-Network](https://github.com/seeker71/Coherence-Network) |
|
|
255
262
|
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Coherence Network MCP server — Python implementation.
|
|
2
2
|
|
|
3
|
-
Exposes the Coherence Network API as
|
|
3
|
+
Exposes the Coherence Network API as 60 typed MCP tools.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
@@ -90,6 +90,9 @@ TOOLS: list[Tool] = [
|
|
|
90
90
|
"properties": {
|
|
91
91
|
"limit": {"type": "number", "description": "Max ideas to return (default 20)", "default": 20},
|
|
92
92
|
"search": {"type": "string", "description": "Search keyword to filter ideas"},
|
|
93
|
+
"workspace_id": {"type": "string", "description": "Optional workspace filter. Defaults to all workspaces."},
|
|
94
|
+
"pillar": {"type": "string", "description": "Optional pillar filter."},
|
|
95
|
+
"curated_only": {"type": "boolean", "description": "If true, only return curated super-ideas."},
|
|
93
96
|
},
|
|
94
97
|
},
|
|
95
98
|
),
|
|
@@ -142,6 +145,7 @@ TOOLS: list[Tool] = [
|
|
|
142
145
|
"properties": {
|
|
143
146
|
"limit": {"type": "number", "default": 20},
|
|
144
147
|
"search": {"type": "string", "description": "Search keyword"},
|
|
148
|
+
"workspace_id": {"type": "string", "description": "Optional workspace filter. Defaults to all workspaces."},
|
|
145
149
|
},
|
|
146
150
|
},
|
|
147
151
|
),
|
|
@@ -252,12 +256,6 @@ TOOLS: list[Tool] = [
|
|
|
252
256
|
"properties": {"window_days": {"type": "number", "default": 30}},
|
|
253
257
|
},
|
|
254
258
|
),
|
|
255
|
-
# Governance
|
|
256
|
-
Tool(
|
|
257
|
-
name="coherence_list_change_requests",
|
|
258
|
-
description="List governance change requests.",
|
|
259
|
-
inputSchema={"type": "object", "properties": {}},
|
|
260
|
-
),
|
|
261
259
|
# Federation
|
|
262
260
|
Tool(
|
|
263
261
|
name="coherence_list_federation_nodes",
|
|
@@ -351,7 +349,7 @@ TOOLS: list[Tool] = [
|
|
|
351
349
|
# Ideas (Lifecycle)
|
|
352
350
|
Tool(
|
|
353
351
|
name="coherence_create_idea",
|
|
354
|
-
description="Create a new idea in the portfolio.",
|
|
352
|
+
description="Create a new idea in the portfolio. Scoped to a workspace (default: coherence-network).",
|
|
355
353
|
inputSchema={
|
|
356
354
|
"type": "object",
|
|
357
355
|
"required": ["id", "name", "description"],
|
|
@@ -361,8 +359,54 @@ TOOLS: list[Tool] = [
|
|
|
361
359
|
"description": {"type": "string", "description": "Detailed vision and value proposition"},
|
|
362
360
|
"potential_value": {"type": "number", "description": "Estimated CC value (0-1000)", "default": 100},
|
|
363
361
|
"estimated_cost": {"type": "number", "description": "Estimated CC cost (0-1000)", "default": 50},
|
|
364
|
-
"parent_idea_id": {"type": "string", "description": "Optional parent idea for hierarchy"},
|
|
362
|
+
"parent_idea_id": {"type": "string", "description": "Optional parent idea for hierarchy. Must belong to the same workspace."},
|
|
365
363
|
"tags": {"type": "array", "items": {"type": "string"}, "description": "List of tags"},
|
|
364
|
+
"workspace_id": {"type": "string", "description": "Owning workspace slug. Defaults to 'coherence-network'."},
|
|
365
|
+
"pillar": {"type": "string", "description": "Top-level pillar (must be one of the workspace's declared pillars)."},
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
),
|
|
369
|
+
# Workspaces (Tenant primitive)
|
|
370
|
+
Tool(
|
|
371
|
+
name="coherence_list_workspaces",
|
|
372
|
+
description="List all workspaces (tenants). Each workspace owns its own ideas, specs, pillars, and agent personas.",
|
|
373
|
+
inputSchema={"type": "object", "properties": {}},
|
|
374
|
+
),
|
|
375
|
+
Tool(
|
|
376
|
+
name="coherence_get_workspace",
|
|
377
|
+
description="Get a workspace's full manifest (name, description, pillars, visibility).",
|
|
378
|
+
inputSchema={
|
|
379
|
+
"type": "object",
|
|
380
|
+
"required": ["workspace_id"],
|
|
381
|
+
"properties": {
|
|
382
|
+
"workspace_id": {"type": "string", "description": "Workspace slug (e.g. 'coherence-network')"},
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
),
|
|
386
|
+
Tool(
|
|
387
|
+
name="coherence_create_workspace",
|
|
388
|
+
description="Create a new workspace (tenant) with its own pillar taxonomy. Use this to onboard a contributor team with isolated ideas/specs/agents.",
|
|
389
|
+
inputSchema={
|
|
390
|
+
"type": "object",
|
|
391
|
+
"required": ["id", "name"],
|
|
392
|
+
"properties": {
|
|
393
|
+
"id": {"type": "string", "description": "Slug: lowercase + hyphens (e.g. 'my-startup')"},
|
|
394
|
+
"name": {"type": "string", "description": "Human name"},
|
|
395
|
+
"description": {"type": "string", "description": "Workspace purpose"},
|
|
396
|
+
"pillars": {"type": "array", "items": {"type": "string"}, "description": "Top-level taxonomy for grouping ideas"},
|
|
397
|
+
"visibility": {"type": "string", "description": "public | federation | private", "default": "public"},
|
|
398
|
+
"owner_contributor_id": {"type": "string", "description": "Contributor who owns this workspace"},
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
),
|
|
402
|
+
Tool(
|
|
403
|
+
name="coherence_get_workspace_pillars",
|
|
404
|
+
description="Get the pillar taxonomy declared by a workspace. Use this before setting `pillar` on a new idea.",
|
|
405
|
+
inputSchema={
|
|
406
|
+
"type": "object",
|
|
407
|
+
"required": ["workspace_id"],
|
|
408
|
+
"properties": {
|
|
409
|
+
"workspace_id": {"type": "string"},
|
|
366
410
|
},
|
|
367
411
|
},
|
|
368
412
|
),
|
|
@@ -663,6 +707,17 @@ TOOLS: list[Tool] = [
|
|
|
663
707
|
},
|
|
664
708
|
},
|
|
665
709
|
),
|
|
710
|
+
Tool(
|
|
711
|
+
name="coherence_read_file",
|
|
712
|
+
description="Read raw file content from the repository (specs, docs, etc.) via direct link.",
|
|
713
|
+
inputSchema={
|
|
714
|
+
"type": "object",
|
|
715
|
+
"required": ["path"],
|
|
716
|
+
"properties": {
|
|
717
|
+
"path": {"type": "string", "description": "Relative path from repo root (e.g. 'specs/169-procedural-memory.md')"},
|
|
718
|
+
},
|
|
719
|
+
},
|
|
720
|
+
),
|
|
666
721
|
# Concepts (Living Codex ontology)
|
|
667
722
|
Tool(
|
|
668
723
|
name="coherence_list_concepts",
|
|
@@ -702,6 +757,71 @@ TOOLS: list[Tool] = [
|
|
|
702
757
|
},
|
|
703
758
|
},
|
|
704
759
|
),
|
|
760
|
+
# Spec CRUD
|
|
761
|
+
Tool(
|
|
762
|
+
name="coherence_create_spec",
|
|
763
|
+
description="Create a new spec in the registry. Requires spec_id (slug), title, summary, and idea_id.",
|
|
764
|
+
inputSchema={
|
|
765
|
+
"type": "object",
|
|
766
|
+
"required": ["spec_id", "title", "summary"],
|
|
767
|
+
"properties": {
|
|
768
|
+
"spec_id": {"type": "string", "description": "Unique spec slug (e.g. '170-my-feature')"},
|
|
769
|
+
"title": {"type": "string", "description": "Spec title"},
|
|
770
|
+
"summary": {"type": "string", "description": "Spec summary"},
|
|
771
|
+
"idea_id": {"type": "string", "description": "Parent idea ID"},
|
|
772
|
+
"potential_value": {"type": "number", "description": "Estimated CC value", "default": 0},
|
|
773
|
+
"estimated_cost": {"type": "number", "description": "Estimated CC cost", "default": 0},
|
|
774
|
+
"content_path": {"type": "string", "description": "Path to spec content file"},
|
|
775
|
+
"implementation_summary": {"type": "string", "description": "Implementation summary text"},
|
|
776
|
+
},
|
|
777
|
+
},
|
|
778
|
+
),
|
|
779
|
+
Tool(
|
|
780
|
+
name="coherence_update_spec",
|
|
781
|
+
description="Update an existing spec's properties (title, summary, value, cost, implementation summary).",
|
|
782
|
+
inputSchema={
|
|
783
|
+
"type": "object",
|
|
784
|
+
"required": ["spec_id"],
|
|
785
|
+
"properties": {
|
|
786
|
+
"spec_id": {"type": "string", "description": "The spec ID"},
|
|
787
|
+
"title": {"type": "string"},
|
|
788
|
+
"summary": {"type": "string"},
|
|
789
|
+
"potential_value": {"type": "number"},
|
|
790
|
+
"estimated_cost": {"type": "number"},
|
|
791
|
+
"actual_value": {"type": "number"},
|
|
792
|
+
"actual_cost": {"type": "number"},
|
|
793
|
+
"idea_id": {"type": "string"},
|
|
794
|
+
"implementation_summary": {"type": "string"},
|
|
795
|
+
"process_summary": {"type": "string"},
|
|
796
|
+
"content_path": {"type": "string"},
|
|
797
|
+
},
|
|
798
|
+
},
|
|
799
|
+
),
|
|
800
|
+
# Workflow
|
|
801
|
+
Tool(
|
|
802
|
+
name="coherence_advance_idea",
|
|
803
|
+
description="Check prerequisites and advance an idea to its next lifecycle stage. Returns current state, prerequisite check results, and whether advancement succeeded.",
|
|
804
|
+
inputSchema={
|
|
805
|
+
"type": "object",
|
|
806
|
+
"required": ["idea_id"],
|
|
807
|
+
"properties": {
|
|
808
|
+
"idea_id": {"type": "string", "description": "The idea ID to advance"},
|
|
809
|
+
"force": {"type": "boolean", "description": "Skip prerequisite checks", "default": False},
|
|
810
|
+
},
|
|
811
|
+
},
|
|
812
|
+
),
|
|
813
|
+
Tool(
|
|
814
|
+
name="coherence_trace",
|
|
815
|
+
description="Trace the full lineage of any entity — from idea to specs to tasks to source files. Provides navigation breadcrumbs across the entire system.",
|
|
816
|
+
inputSchema={
|
|
817
|
+
"type": "object",
|
|
818
|
+
"required": ["entity_id"],
|
|
819
|
+
"properties": {
|
|
820
|
+
"entity_id": {"type": "string", "description": "An idea slug, spec slug, or task ID"},
|
|
821
|
+
"entity_type": {"type": "string", "description": "idea, spec, or task", "default": "idea"},
|
|
822
|
+
},
|
|
823
|
+
},
|
|
824
|
+
),
|
|
705
825
|
]
|
|
706
826
|
|
|
707
827
|
TOOL_MAP: dict[str, Tool] = {t.name: t for t in TOOLS}
|
|
@@ -716,7 +836,14 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
716
836
|
case "coherence_list_ideas":
|
|
717
837
|
if args.get("search"):
|
|
718
838
|
return api_get("/api/ideas/cards", {"search": args["search"], "limit": args.get("limit", 20)})
|
|
719
|
-
|
|
839
|
+
params = {"limit": args.get("limit", 20)}
|
|
840
|
+
if args.get("workspace_id"):
|
|
841
|
+
params["workspace_id"] = args["workspace_id"]
|
|
842
|
+
if args.get("pillar"):
|
|
843
|
+
params["pillar"] = args["pillar"]
|
|
844
|
+
if args.get("curated_only"):
|
|
845
|
+
params["curated_only"] = "true"
|
|
846
|
+
return api_get("/api/ideas", params)
|
|
720
847
|
case "coherence_get_idea":
|
|
721
848
|
return api_get(f"/api/ideas/{args['idea_id']}")
|
|
722
849
|
case "coherence_idea_progress":
|
|
@@ -731,7 +858,10 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
731
858
|
case "coherence_list_specs":
|
|
732
859
|
if args.get("search"):
|
|
733
860
|
return api_get("/api/spec-registry/cards", {"search": args["search"], "limit": args.get("limit", 20)})
|
|
734
|
-
|
|
861
|
+
params = {"limit": args.get("limit", 20)}
|
|
862
|
+
if args.get("workspace_id"):
|
|
863
|
+
params["workspace_id"] = args["workspace_id"]
|
|
864
|
+
return api_get("/api/spec-registry", params)
|
|
735
865
|
case "coherence_get_spec":
|
|
736
866
|
return api_get(f"/api/spec-registry/{args['spec_id']}")
|
|
737
867
|
# Lineage
|
|
@@ -782,9 +912,6 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
782
912
|
}
|
|
783
913
|
case "coherence_friction_report":
|
|
784
914
|
return api_get("/api/friction/report", {"window_days": args.get("window_days", 30)})
|
|
785
|
-
# Governance
|
|
786
|
-
case "coherence_list_change_requests":
|
|
787
|
-
return api_get("/api/governance/change-requests")
|
|
788
915
|
# Federation
|
|
789
916
|
case "coherence_list_federation_nodes":
|
|
790
917
|
nodes = api_get("/api/federation/nodes")
|
|
@@ -849,7 +976,25 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
849
976
|
"estimated_cost": args.get("estimated_cost", 50),
|
|
850
977
|
"parent_idea_id": args.get("parent_idea_id"),
|
|
851
978
|
"tags": args.get("tags"),
|
|
979
|
+
"workspace_id": args.get("workspace_id"),
|
|
980
|
+
"pillar": args.get("pillar"),
|
|
981
|
+
})
|
|
982
|
+
# Workspaces
|
|
983
|
+
case "coherence_list_workspaces":
|
|
984
|
+
return api_get("/api/workspaces")
|
|
985
|
+
case "coherence_get_workspace":
|
|
986
|
+
return api_get(f"/api/workspaces/{args['workspace_id']}")
|
|
987
|
+
case "coherence_create_workspace":
|
|
988
|
+
return api_post("/api/workspaces", {
|
|
989
|
+
"id": args["id"],
|
|
990
|
+
"name": args["name"],
|
|
991
|
+
"description": args.get("description", ""),
|
|
992
|
+
"pillars": args.get("pillars", []),
|
|
993
|
+
"visibility": args.get("visibility", "public"),
|
|
994
|
+
"owner_contributor_id": args.get("owner_contributor_id"),
|
|
852
995
|
})
|
|
996
|
+
case "coherence_get_workspace_pillars":
|
|
997
|
+
return api_get(f"/api/workspaces/{args['workspace_id']}/pillars")
|
|
853
998
|
case "coherence_update_idea":
|
|
854
999
|
return api_patch(f"/api/ideas/{args['idea_id']}", {
|
|
855
1000
|
"name": args.get("name"),
|
|
@@ -968,6 +1113,8 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
968
1113
|
return api_get("/api/blueprints")
|
|
969
1114
|
case "coherence_apply_blueprint":
|
|
970
1115
|
return api_post(f"/api/blueprints/{args['blueprint_id']}/apply", {"prefix": args.get("prefix", "")})
|
|
1116
|
+
case "coherence_read_file":
|
|
1117
|
+
return api_get("/api/content/file", {"path": args["path"]})
|
|
971
1118
|
# Concepts
|
|
972
1119
|
case "coherence_list_concepts":
|
|
973
1120
|
if args.get("search"):
|
|
@@ -987,6 +1134,123 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
987
1134
|
"relationship_type": args["relationship_type"],
|
|
988
1135
|
"created_by": args.get("created_by", "mcp"),
|
|
989
1136
|
})
|
|
1137
|
+
# Spec CRUD
|
|
1138
|
+
case "coherence_create_spec":
|
|
1139
|
+
return api_post("/api/spec-registry", {
|
|
1140
|
+
"spec_id": args["spec_id"],
|
|
1141
|
+
"title": args["title"],
|
|
1142
|
+
"summary": args["summary"],
|
|
1143
|
+
"idea_id": args.get("idea_id"),
|
|
1144
|
+
"potential_value": args.get("potential_value", 0),
|
|
1145
|
+
"estimated_cost": args.get("estimated_cost", 0),
|
|
1146
|
+
"content_path": args.get("content_path"),
|
|
1147
|
+
"implementation_summary": args.get("implementation_summary"),
|
|
1148
|
+
})
|
|
1149
|
+
case "coherence_update_spec":
|
|
1150
|
+
body = {
|
|
1151
|
+
k: v for k, v in {
|
|
1152
|
+
"title": args.get("title"),
|
|
1153
|
+
"summary": args.get("summary"),
|
|
1154
|
+
"potential_value": args.get("potential_value"),
|
|
1155
|
+
"estimated_cost": args.get("estimated_cost"),
|
|
1156
|
+
"actual_value": args.get("actual_value"),
|
|
1157
|
+
"actual_cost": args.get("actual_cost"),
|
|
1158
|
+
"idea_id": args.get("idea_id"),
|
|
1159
|
+
"implementation_summary": args.get("implementation_summary"),
|
|
1160
|
+
"process_summary": args.get("process_summary"),
|
|
1161
|
+
"content_path": args.get("content_path"),
|
|
1162
|
+
}.items() if v is not None
|
|
1163
|
+
}
|
|
1164
|
+
return api_patch(f"/api/spec-registry/{args['spec_id']}", body)
|
|
1165
|
+
# Workflow
|
|
1166
|
+
case "coherence_advance_idea":
|
|
1167
|
+
idea_id = args["idea_id"]
|
|
1168
|
+
force = args.get("force", False)
|
|
1169
|
+
idea = api_get(f"/api/ideas/{idea_id}")
|
|
1170
|
+
if isinstance(idea, dict) and "error" in idea:
|
|
1171
|
+
return idea
|
|
1172
|
+
progress = api_get(f"/api/ideas/{idea_id}/progress")
|
|
1173
|
+
current_stage = idea.get("stage", "none") if isinstance(idea, dict) else "none"
|
|
1174
|
+
stage_order = ["none", "specced", "implementing", "testing", "reviewing", "complete"]
|
|
1175
|
+
idx = stage_order.index(current_stage) if current_stage in stage_order else 0
|
|
1176
|
+
if idx >= len(stage_order) - 1:
|
|
1177
|
+
return {"idea_id": idea_id, "current_stage": current_stage, "next_stage": None,
|
|
1178
|
+
"prerequisites_met": False, "prerequisite_details": {"reason": "already at final stage"},
|
|
1179
|
+
"advanced": False, "result": None}
|
|
1180
|
+
next_stage = stage_order[idx + 1]
|
|
1181
|
+
# Check prerequisites from progress tasks
|
|
1182
|
+
tasks_by_phase = progress.get("tasks_by_phase", {}) if isinstance(progress, dict) else {}
|
|
1183
|
+
prereq_checks = {
|
|
1184
|
+
"specced": ("spec", "at least 1 spec task completed"),
|
|
1185
|
+
"implementing": ("impl", "at least 1 impl task exists"),
|
|
1186
|
+
"testing": ("impl", "at least 1 impl task completed"),
|
|
1187
|
+
"reviewing": ("test", "at least 1 test task completed"),
|
|
1188
|
+
"complete": ("review", "at least 1 review task completed"),
|
|
1189
|
+
}
|
|
1190
|
+
prereqs_met = True
|
|
1191
|
+
prereq_details: dict[str, Any] = {}
|
|
1192
|
+
if next_stage in prereq_checks:
|
|
1193
|
+
phase_key, description = prereq_checks[next_stage]
|
|
1194
|
+
phase_tasks = tasks_by_phase.get(phase_key, [])
|
|
1195
|
+
if next_stage == "implementing":
|
|
1196
|
+
prereqs_met = len(phase_tasks) > 0
|
|
1197
|
+
prereq_details = {"check": description, "phase": phase_key, "task_count": len(phase_tasks)}
|
|
1198
|
+
else:
|
|
1199
|
+
completed = [t for t in phase_tasks if isinstance(t, dict) and t.get("status") == "completed"]
|
|
1200
|
+
prereqs_met = len(completed) > 0
|
|
1201
|
+
prereq_details = {"check": description, "phase": phase_key,
|
|
1202
|
+
"completed_count": len(completed), "total_count": len(phase_tasks)}
|
|
1203
|
+
advanced = False
|
|
1204
|
+
result = None
|
|
1205
|
+
if prereqs_met or force:
|
|
1206
|
+
result = api_patch(f"/api/ideas/{idea_id}", {"stage": next_stage})
|
|
1207
|
+
advanced = not (isinstance(result, dict) and "error" in result)
|
|
1208
|
+
return {"idea_id": idea_id, "current_stage": current_stage, "next_stage": next_stage,
|
|
1209
|
+
"prerequisites_met": prereqs_met, "prerequisite_details": prereq_details,
|
|
1210
|
+
"advanced": advanced, "result": result}
|
|
1211
|
+
case "coherence_trace":
|
|
1212
|
+
entity_id = args["entity_id"]
|
|
1213
|
+
entity_type = args.get("entity_type", "idea")
|
|
1214
|
+
if entity_type == "idea":
|
|
1215
|
+
idea = api_get(f"/api/ideas/{entity_id}")
|
|
1216
|
+
progress = api_get(f"/api/ideas/{entity_id}/progress")
|
|
1217
|
+
specs = api_get("/api/spec-registry/cards", {"q": entity_id, "limit": 50})
|
|
1218
|
+
all_tasks = api_get("/api/agent/tasks", {"status": None, "limit": 50})
|
|
1219
|
+
task_list = all_tasks.get("tasks", []) if isinstance(all_tasks, dict) else []
|
|
1220
|
+
idea_tasks = [t for t in task_list if isinstance(t, dict)
|
|
1221
|
+
and isinstance(t.get("context"), dict) and t["context"].get("idea_id") == entity_id]
|
|
1222
|
+
spec_items = specs if isinstance(specs, list) else specs.get("items", []) if isinstance(specs, dict) else []
|
|
1223
|
+
spec_ids = [s.get("spec_id", s.get("id", "")) for s in spec_items if isinstance(s, dict)]
|
|
1224
|
+
return {"entity_type": "idea", "idea": idea, "progress": progress,
|
|
1225
|
+
"specs": spec_items, "tasks": idea_tasks,
|
|
1226
|
+
"navigation": {"idea_file": f"ideas/{entity_id}.md",
|
|
1227
|
+
"spec_files": [f"specs/{s}.md" for s in spec_ids],
|
|
1228
|
+
"api": f"/api/ideas/{entity_id}",
|
|
1229
|
+
"cli": f"cc idea {entity_id}"}}
|
|
1230
|
+
elif entity_type == "spec":
|
|
1231
|
+
spec = api_get(f"/api/spec-registry/{entity_id}")
|
|
1232
|
+
spec_file = api_get("/api/content/file", {"path": f"specs/{entity_id}.md"})
|
|
1233
|
+
idea_id = spec.get("idea_id") if isinstance(spec, dict) else None
|
|
1234
|
+
parent_idea = api_get(f"/api/ideas/{idea_id}") if idea_id else None
|
|
1235
|
+
nav: dict[str, Any] = {"spec_file": f"specs/{entity_id}.md",
|
|
1236
|
+
"api": f"/api/spec-registry/{entity_id}",
|
|
1237
|
+
"cli": f"cc spec {entity_id}"}
|
|
1238
|
+
if idea_id:
|
|
1239
|
+
nav["idea_file"] = f"ideas/{idea_id}.md"
|
|
1240
|
+
return {"entity_type": "spec", "spec": spec, "spec_file_content": spec_file,
|
|
1241
|
+
"parent_idea": parent_idea, "navigation": nav}
|
|
1242
|
+
elif entity_type == "task":
|
|
1243
|
+
task = api_get(f"/api/agent/tasks/{entity_id}")
|
|
1244
|
+
events = api_get(f"/api/agent/tasks/{entity_id}/stream")
|
|
1245
|
+
context = task.get("context", {}) if isinstance(task, dict) else {}
|
|
1246
|
+
idea_id = context.get("idea_id") if isinstance(context, dict) else None
|
|
1247
|
+
parent_idea = api_get(f"/api/ideas/{idea_id}") if idea_id else None
|
|
1248
|
+
return {"entity_type": "task", "task": task, "events": events,
|
|
1249
|
+
"parent_idea": parent_idea,
|
|
1250
|
+
"navigation": {"api": f"/api/agent/tasks/{entity_id}",
|
|
1251
|
+
"cli": f"cc task {entity_id}"}}
|
|
1252
|
+
else:
|
|
1253
|
+
return {"error": f"Unknown entity_type: {entity_type}. Use 'idea', 'spec', or 'task'."}
|
|
990
1254
|
case _:
|
|
991
1255
|
return {"error": f"Unknown tool: {name}"}
|
|
992
1256
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coherence-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
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.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
Binary file
|