coherence-mcp-server 0.4.5 → 0.5.1
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.
|
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",
|
|
@@ -275,6 +273,7 @@ TOOLS: list[Tool] = [
|
|
|
275
273
|
"task_type": {"type": "string", "description": "Filter by type: spec, test, impl, review, code-review"},
|
|
276
274
|
"limit": {"type": "number", "description": "Max tasks to return (default 20)", "default": 20},
|
|
277
275
|
"offset": {"type": "number", "description": "Pagination offset", "default": 0},
|
|
276
|
+
"workspace_id": {"type": "string", "description": "Optional workspace to filter by (via each task's linked idea)."},
|
|
278
277
|
},
|
|
279
278
|
},
|
|
280
279
|
),
|
|
@@ -351,7 +350,7 @@ TOOLS: list[Tool] = [
|
|
|
351
350
|
# Ideas (Lifecycle)
|
|
352
351
|
Tool(
|
|
353
352
|
name="coherence_create_idea",
|
|
354
|
-
description="Create a new idea in the portfolio.",
|
|
353
|
+
description="Create a new idea in the portfolio. Scoped to a workspace (default: coherence-network).",
|
|
355
354
|
inputSchema={
|
|
356
355
|
"type": "object",
|
|
357
356
|
"required": ["id", "name", "description"],
|
|
@@ -361,8 +360,54 @@ TOOLS: list[Tool] = [
|
|
|
361
360
|
"description": {"type": "string", "description": "Detailed vision and value proposition"},
|
|
362
361
|
"potential_value": {"type": "number", "description": "Estimated CC value (0-1000)", "default": 100},
|
|
363
362
|
"estimated_cost": {"type": "number", "description": "Estimated CC cost (0-1000)", "default": 50},
|
|
364
|
-
"parent_idea_id": {"type": "string", "description": "Optional parent idea for hierarchy"},
|
|
363
|
+
"parent_idea_id": {"type": "string", "description": "Optional parent idea for hierarchy. Must belong to the same workspace."},
|
|
365
364
|
"tags": {"type": "array", "items": {"type": "string"}, "description": "List of tags"},
|
|
365
|
+
"workspace_id": {"type": "string", "description": "Owning workspace slug. Defaults to 'coherence-network'."},
|
|
366
|
+
"pillar": {"type": "string", "description": "Top-level pillar (must be one of the workspace's declared pillars)."},
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
),
|
|
370
|
+
# Workspaces (Tenant primitive)
|
|
371
|
+
Tool(
|
|
372
|
+
name="coherence_list_workspaces",
|
|
373
|
+
description="List all workspaces (tenants). Each workspace owns its own ideas, specs, pillars, and agent personas.",
|
|
374
|
+
inputSchema={"type": "object", "properties": {}},
|
|
375
|
+
),
|
|
376
|
+
Tool(
|
|
377
|
+
name="coherence_get_workspace",
|
|
378
|
+
description="Get a workspace's full manifest (name, description, pillars, visibility).",
|
|
379
|
+
inputSchema={
|
|
380
|
+
"type": "object",
|
|
381
|
+
"required": ["workspace_id"],
|
|
382
|
+
"properties": {
|
|
383
|
+
"workspace_id": {"type": "string", "description": "Workspace slug (e.g. 'coherence-network')"},
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
),
|
|
387
|
+
Tool(
|
|
388
|
+
name="coherence_create_workspace",
|
|
389
|
+
description="Create a new workspace (tenant) with its own pillar taxonomy. Use this to onboard a contributor team with isolated ideas/specs/agents.",
|
|
390
|
+
inputSchema={
|
|
391
|
+
"type": "object",
|
|
392
|
+
"required": ["id", "name"],
|
|
393
|
+
"properties": {
|
|
394
|
+
"id": {"type": "string", "description": "Slug: lowercase + hyphens (e.g. 'my-startup')"},
|
|
395
|
+
"name": {"type": "string", "description": "Human name"},
|
|
396
|
+
"description": {"type": "string", "description": "Workspace purpose"},
|
|
397
|
+
"pillars": {"type": "array", "items": {"type": "string"}, "description": "Top-level taxonomy for grouping ideas"},
|
|
398
|
+
"visibility": {"type": "string", "description": "public | federation | private", "default": "public"},
|
|
399
|
+
"owner_contributor_id": {"type": "string", "description": "Contributor who owns this workspace"},
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
),
|
|
403
|
+
Tool(
|
|
404
|
+
name="coherence_get_workspace_pillars",
|
|
405
|
+
description="Get the pillar taxonomy declared by a workspace. Use this before setting `pillar` on a new idea.",
|
|
406
|
+
inputSchema={
|
|
407
|
+
"type": "object",
|
|
408
|
+
"required": ["workspace_id"],
|
|
409
|
+
"properties": {
|
|
410
|
+
"workspace_id": {"type": "string"},
|
|
366
411
|
},
|
|
367
412
|
},
|
|
368
413
|
),
|
|
@@ -713,6 +758,71 @@ TOOLS: list[Tool] = [
|
|
|
713
758
|
},
|
|
714
759
|
},
|
|
715
760
|
),
|
|
761
|
+
# Spec CRUD
|
|
762
|
+
Tool(
|
|
763
|
+
name="coherence_create_spec",
|
|
764
|
+
description="Create a new spec in the registry. Requires spec_id (slug), title, summary, and idea_id.",
|
|
765
|
+
inputSchema={
|
|
766
|
+
"type": "object",
|
|
767
|
+
"required": ["spec_id", "title", "summary"],
|
|
768
|
+
"properties": {
|
|
769
|
+
"spec_id": {"type": "string", "description": "Unique spec slug (e.g. '170-my-feature')"},
|
|
770
|
+
"title": {"type": "string", "description": "Spec title"},
|
|
771
|
+
"summary": {"type": "string", "description": "Spec summary"},
|
|
772
|
+
"idea_id": {"type": "string", "description": "Parent idea ID"},
|
|
773
|
+
"potential_value": {"type": "number", "description": "Estimated CC value", "default": 0},
|
|
774
|
+
"estimated_cost": {"type": "number", "description": "Estimated CC cost", "default": 0},
|
|
775
|
+
"content_path": {"type": "string", "description": "Path to spec content file"},
|
|
776
|
+
"implementation_summary": {"type": "string", "description": "Implementation summary text"},
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
),
|
|
780
|
+
Tool(
|
|
781
|
+
name="coherence_update_spec",
|
|
782
|
+
description="Update an existing spec's properties (title, summary, value, cost, implementation summary).",
|
|
783
|
+
inputSchema={
|
|
784
|
+
"type": "object",
|
|
785
|
+
"required": ["spec_id"],
|
|
786
|
+
"properties": {
|
|
787
|
+
"spec_id": {"type": "string", "description": "The spec ID"},
|
|
788
|
+
"title": {"type": "string"},
|
|
789
|
+
"summary": {"type": "string"},
|
|
790
|
+
"potential_value": {"type": "number"},
|
|
791
|
+
"estimated_cost": {"type": "number"},
|
|
792
|
+
"actual_value": {"type": "number"},
|
|
793
|
+
"actual_cost": {"type": "number"},
|
|
794
|
+
"idea_id": {"type": "string"},
|
|
795
|
+
"implementation_summary": {"type": "string"},
|
|
796
|
+
"process_summary": {"type": "string"},
|
|
797
|
+
"content_path": {"type": "string"},
|
|
798
|
+
},
|
|
799
|
+
},
|
|
800
|
+
),
|
|
801
|
+
# Workflow
|
|
802
|
+
Tool(
|
|
803
|
+
name="coherence_advance_idea",
|
|
804
|
+
description="Check prerequisites and advance an idea to its next lifecycle stage. Returns current state, prerequisite check results, and whether advancement succeeded.",
|
|
805
|
+
inputSchema={
|
|
806
|
+
"type": "object",
|
|
807
|
+
"required": ["idea_id"],
|
|
808
|
+
"properties": {
|
|
809
|
+
"idea_id": {"type": "string", "description": "The idea ID to advance"},
|
|
810
|
+
"force": {"type": "boolean", "description": "Skip prerequisite checks", "default": False},
|
|
811
|
+
},
|
|
812
|
+
},
|
|
813
|
+
),
|
|
814
|
+
Tool(
|
|
815
|
+
name="coherence_trace",
|
|
816
|
+
description="Trace the full lineage of any entity — from idea to specs to tasks to source files. Provides navigation breadcrumbs across the entire system.",
|
|
817
|
+
inputSchema={
|
|
818
|
+
"type": "object",
|
|
819
|
+
"required": ["entity_id"],
|
|
820
|
+
"properties": {
|
|
821
|
+
"entity_id": {"type": "string", "description": "An idea slug, spec slug, or task ID"},
|
|
822
|
+
"entity_type": {"type": "string", "description": "idea, spec, or task", "default": "idea"},
|
|
823
|
+
},
|
|
824
|
+
},
|
|
825
|
+
),
|
|
716
826
|
]
|
|
717
827
|
|
|
718
828
|
TOOL_MAP: dict[str, Tool] = {t.name: t for t in TOOLS}
|
|
@@ -727,7 +837,14 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
727
837
|
case "coherence_list_ideas":
|
|
728
838
|
if args.get("search"):
|
|
729
839
|
return api_get("/api/ideas/cards", {"search": args["search"], "limit": args.get("limit", 20)})
|
|
730
|
-
|
|
840
|
+
params = {"limit": args.get("limit", 20)}
|
|
841
|
+
if args.get("workspace_id"):
|
|
842
|
+
params["workspace_id"] = args["workspace_id"]
|
|
843
|
+
if args.get("pillar"):
|
|
844
|
+
params["pillar"] = args["pillar"]
|
|
845
|
+
if args.get("curated_only"):
|
|
846
|
+
params["curated_only"] = "true"
|
|
847
|
+
return api_get("/api/ideas", params)
|
|
731
848
|
case "coherence_get_idea":
|
|
732
849
|
return api_get(f"/api/ideas/{args['idea_id']}")
|
|
733
850
|
case "coherence_idea_progress":
|
|
@@ -742,7 +859,10 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
742
859
|
case "coherence_list_specs":
|
|
743
860
|
if args.get("search"):
|
|
744
861
|
return api_get("/api/spec-registry/cards", {"search": args["search"], "limit": args.get("limit", 20)})
|
|
745
|
-
|
|
862
|
+
params = {"limit": args.get("limit", 20)}
|
|
863
|
+
if args.get("workspace_id"):
|
|
864
|
+
params["workspace_id"] = args["workspace_id"]
|
|
865
|
+
return api_get("/api/spec-registry", params)
|
|
746
866
|
case "coherence_get_spec":
|
|
747
867
|
return api_get(f"/api/spec-registry/{args['spec_id']}")
|
|
748
868
|
# Lineage
|
|
@@ -793,9 +913,6 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
793
913
|
}
|
|
794
914
|
case "coherence_friction_report":
|
|
795
915
|
return api_get("/api/friction/report", {"window_days": args.get("window_days", 30)})
|
|
796
|
-
# Governance
|
|
797
|
-
case "coherence_list_change_requests":
|
|
798
|
-
return api_get("/api/governance/change-requests")
|
|
799
916
|
# Federation
|
|
800
917
|
case "coherence_list_federation_nodes":
|
|
801
918
|
nodes = api_get("/api/federation/nodes")
|
|
@@ -803,12 +920,15 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
803
920
|
return {"nodes": nodes, "capabilities": caps}
|
|
804
921
|
# Tasks
|
|
805
922
|
case "coherence_list_tasks":
|
|
806
|
-
|
|
923
|
+
params = {
|
|
807
924
|
"status": args.get("status"),
|
|
808
925
|
"task_type": args.get("task_type"),
|
|
809
926
|
"limit": args.get("limit", 20),
|
|
810
927
|
"offset": args.get("offset", 0),
|
|
811
|
-
}
|
|
928
|
+
}
|
|
929
|
+
if args.get("workspace_id"):
|
|
930
|
+
params["workspace_id"] = args["workspace_id"]
|
|
931
|
+
return api_get("/api/agent/tasks", params)
|
|
812
932
|
case "coherence_get_task":
|
|
813
933
|
return api_get(f"/api/agent/tasks/{args['task_id']}")
|
|
814
934
|
case "coherence_task_next":
|
|
@@ -860,7 +980,25 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
860
980
|
"estimated_cost": args.get("estimated_cost", 50),
|
|
861
981
|
"parent_idea_id": args.get("parent_idea_id"),
|
|
862
982
|
"tags": args.get("tags"),
|
|
983
|
+
"workspace_id": args.get("workspace_id"),
|
|
984
|
+
"pillar": args.get("pillar"),
|
|
985
|
+
})
|
|
986
|
+
# Workspaces
|
|
987
|
+
case "coherence_list_workspaces":
|
|
988
|
+
return api_get("/api/workspaces")
|
|
989
|
+
case "coherence_get_workspace":
|
|
990
|
+
return api_get(f"/api/workspaces/{args['workspace_id']}")
|
|
991
|
+
case "coherence_create_workspace":
|
|
992
|
+
return api_post("/api/workspaces", {
|
|
993
|
+
"id": args["id"],
|
|
994
|
+
"name": args["name"],
|
|
995
|
+
"description": args.get("description", ""),
|
|
996
|
+
"pillars": args.get("pillars", []),
|
|
997
|
+
"visibility": args.get("visibility", "public"),
|
|
998
|
+
"owner_contributor_id": args.get("owner_contributor_id"),
|
|
863
999
|
})
|
|
1000
|
+
case "coherence_get_workspace_pillars":
|
|
1001
|
+
return api_get(f"/api/workspaces/{args['workspace_id']}/pillars")
|
|
864
1002
|
case "coherence_update_idea":
|
|
865
1003
|
return api_patch(f"/api/ideas/{args['idea_id']}", {
|
|
866
1004
|
"name": args.get("name"),
|
|
@@ -1000,6 +1138,123 @@ def dispatch(name: str, args: dict[str, Any]) -> Any:
|
|
|
1000
1138
|
"relationship_type": args["relationship_type"],
|
|
1001
1139
|
"created_by": args.get("created_by", "mcp"),
|
|
1002
1140
|
})
|
|
1141
|
+
# Spec CRUD
|
|
1142
|
+
case "coherence_create_spec":
|
|
1143
|
+
return api_post("/api/spec-registry", {
|
|
1144
|
+
"spec_id": args["spec_id"],
|
|
1145
|
+
"title": args["title"],
|
|
1146
|
+
"summary": args["summary"],
|
|
1147
|
+
"idea_id": args.get("idea_id"),
|
|
1148
|
+
"potential_value": args.get("potential_value", 0),
|
|
1149
|
+
"estimated_cost": args.get("estimated_cost", 0),
|
|
1150
|
+
"content_path": args.get("content_path"),
|
|
1151
|
+
"implementation_summary": args.get("implementation_summary"),
|
|
1152
|
+
})
|
|
1153
|
+
case "coherence_update_spec":
|
|
1154
|
+
body = {
|
|
1155
|
+
k: v for k, v in {
|
|
1156
|
+
"title": args.get("title"),
|
|
1157
|
+
"summary": args.get("summary"),
|
|
1158
|
+
"potential_value": args.get("potential_value"),
|
|
1159
|
+
"estimated_cost": args.get("estimated_cost"),
|
|
1160
|
+
"actual_value": args.get("actual_value"),
|
|
1161
|
+
"actual_cost": args.get("actual_cost"),
|
|
1162
|
+
"idea_id": args.get("idea_id"),
|
|
1163
|
+
"implementation_summary": args.get("implementation_summary"),
|
|
1164
|
+
"process_summary": args.get("process_summary"),
|
|
1165
|
+
"content_path": args.get("content_path"),
|
|
1166
|
+
}.items() if v is not None
|
|
1167
|
+
}
|
|
1168
|
+
return api_patch(f"/api/spec-registry/{args['spec_id']}", body)
|
|
1169
|
+
# Workflow
|
|
1170
|
+
case "coherence_advance_idea":
|
|
1171
|
+
idea_id = args["idea_id"]
|
|
1172
|
+
force = args.get("force", False)
|
|
1173
|
+
idea = api_get(f"/api/ideas/{idea_id}")
|
|
1174
|
+
if isinstance(idea, dict) and "error" in idea:
|
|
1175
|
+
return idea
|
|
1176
|
+
progress = api_get(f"/api/ideas/{idea_id}/progress")
|
|
1177
|
+
current_stage = idea.get("stage", "none") if isinstance(idea, dict) else "none"
|
|
1178
|
+
stage_order = ["none", "specced", "implementing", "testing", "reviewing", "complete"]
|
|
1179
|
+
idx = stage_order.index(current_stage) if current_stage in stage_order else 0
|
|
1180
|
+
if idx >= len(stage_order) - 1:
|
|
1181
|
+
return {"idea_id": idea_id, "current_stage": current_stage, "next_stage": None,
|
|
1182
|
+
"prerequisites_met": False, "prerequisite_details": {"reason": "already at final stage"},
|
|
1183
|
+
"advanced": False, "result": None}
|
|
1184
|
+
next_stage = stage_order[idx + 1]
|
|
1185
|
+
# Check prerequisites from progress tasks
|
|
1186
|
+
tasks_by_phase = progress.get("tasks_by_phase", {}) if isinstance(progress, dict) else {}
|
|
1187
|
+
prereq_checks = {
|
|
1188
|
+
"specced": ("spec", "at least 1 spec task completed"),
|
|
1189
|
+
"implementing": ("impl", "at least 1 impl task exists"),
|
|
1190
|
+
"testing": ("impl", "at least 1 impl task completed"),
|
|
1191
|
+
"reviewing": ("test", "at least 1 test task completed"),
|
|
1192
|
+
"complete": ("review", "at least 1 review task completed"),
|
|
1193
|
+
}
|
|
1194
|
+
prereqs_met = True
|
|
1195
|
+
prereq_details: dict[str, Any] = {}
|
|
1196
|
+
if next_stage in prereq_checks:
|
|
1197
|
+
phase_key, description = prereq_checks[next_stage]
|
|
1198
|
+
phase_tasks = tasks_by_phase.get(phase_key, [])
|
|
1199
|
+
if next_stage == "implementing":
|
|
1200
|
+
prereqs_met = len(phase_tasks) > 0
|
|
1201
|
+
prereq_details = {"check": description, "phase": phase_key, "task_count": len(phase_tasks)}
|
|
1202
|
+
else:
|
|
1203
|
+
completed = [t for t in phase_tasks if isinstance(t, dict) and t.get("status") == "completed"]
|
|
1204
|
+
prereqs_met = len(completed) > 0
|
|
1205
|
+
prereq_details = {"check": description, "phase": phase_key,
|
|
1206
|
+
"completed_count": len(completed), "total_count": len(phase_tasks)}
|
|
1207
|
+
advanced = False
|
|
1208
|
+
result = None
|
|
1209
|
+
if prereqs_met or force:
|
|
1210
|
+
result = api_patch(f"/api/ideas/{idea_id}", {"stage": next_stage})
|
|
1211
|
+
advanced = not (isinstance(result, dict) and "error" in result)
|
|
1212
|
+
return {"idea_id": idea_id, "current_stage": current_stage, "next_stage": next_stage,
|
|
1213
|
+
"prerequisites_met": prereqs_met, "prerequisite_details": prereq_details,
|
|
1214
|
+
"advanced": advanced, "result": result}
|
|
1215
|
+
case "coherence_trace":
|
|
1216
|
+
entity_id = args["entity_id"]
|
|
1217
|
+
entity_type = args.get("entity_type", "idea")
|
|
1218
|
+
if entity_type == "idea":
|
|
1219
|
+
idea = api_get(f"/api/ideas/{entity_id}")
|
|
1220
|
+
progress = api_get(f"/api/ideas/{entity_id}/progress")
|
|
1221
|
+
specs = api_get("/api/spec-registry/cards", {"q": entity_id, "limit": 50})
|
|
1222
|
+
all_tasks = api_get("/api/agent/tasks", {"status": None, "limit": 50})
|
|
1223
|
+
task_list = all_tasks.get("tasks", []) if isinstance(all_tasks, dict) else []
|
|
1224
|
+
idea_tasks = [t for t in task_list if isinstance(t, dict)
|
|
1225
|
+
and isinstance(t.get("context"), dict) and t["context"].get("idea_id") == entity_id]
|
|
1226
|
+
spec_items = specs if isinstance(specs, list) else specs.get("items", []) if isinstance(specs, dict) else []
|
|
1227
|
+
spec_ids = [s.get("spec_id", s.get("id", "")) for s in spec_items if isinstance(s, dict)]
|
|
1228
|
+
return {"entity_type": "idea", "idea": idea, "progress": progress,
|
|
1229
|
+
"specs": spec_items, "tasks": idea_tasks,
|
|
1230
|
+
"navigation": {"idea_file": f"ideas/{entity_id}.md",
|
|
1231
|
+
"spec_files": [f"specs/{s}.md" for s in spec_ids],
|
|
1232
|
+
"api": f"/api/ideas/{entity_id}",
|
|
1233
|
+
"cli": f"cc idea {entity_id}"}}
|
|
1234
|
+
elif entity_type == "spec":
|
|
1235
|
+
spec = api_get(f"/api/spec-registry/{entity_id}")
|
|
1236
|
+
spec_file = api_get("/api/content/file", {"path": f"specs/{entity_id}.md"})
|
|
1237
|
+
idea_id = spec.get("idea_id") if isinstance(spec, dict) else None
|
|
1238
|
+
parent_idea = api_get(f"/api/ideas/{idea_id}") if idea_id else None
|
|
1239
|
+
nav: dict[str, Any] = {"spec_file": f"specs/{entity_id}.md",
|
|
1240
|
+
"api": f"/api/spec-registry/{entity_id}",
|
|
1241
|
+
"cli": f"cc spec {entity_id}"}
|
|
1242
|
+
if idea_id:
|
|
1243
|
+
nav["idea_file"] = f"ideas/{idea_id}.md"
|
|
1244
|
+
return {"entity_type": "spec", "spec": spec, "spec_file_content": spec_file,
|
|
1245
|
+
"parent_idea": parent_idea, "navigation": nav}
|
|
1246
|
+
elif entity_type == "task":
|
|
1247
|
+
task = api_get(f"/api/agent/tasks/{entity_id}")
|
|
1248
|
+
events = api_get(f"/api/agent/tasks/{entity_id}/stream")
|
|
1249
|
+
context = task.get("context", {}) if isinstance(task, dict) else {}
|
|
1250
|
+
idea_id = context.get("idea_id") if isinstance(context, dict) else None
|
|
1251
|
+
parent_idea = api_get(f"/api/ideas/{idea_id}") if idea_id else None
|
|
1252
|
+
return {"entity_type": "task", "task": task, "events": events,
|
|
1253
|
+
"parent_idea": parent_idea,
|
|
1254
|
+
"navigation": {"api": f"/api/agent/tasks/{entity_id}",
|
|
1255
|
+
"cli": f"cc task {entity_id}"}}
|
|
1256
|
+
else:
|
|
1257
|
+
return {"error": f"Unknown entity_type: {entity_type}. Use 'idea', 'spec', or 'task'."}
|
|
1003
1258
|
case _:
|
|
1004
1259
|
return {"error": f"Unknown tool: {name}"}
|
|
1005
1260
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coherence-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
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
|