@gwdn/nexus-mcp 0.7.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/.github/workflows/ci.yml +38 -0
- package/.github/workflows/release.yml +57 -0
- package/README.md +89 -0
- package/dist/auth.d.ts +39 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +47 -0
- package/dist/auth.js.map +1 -0
- package/dist/nexus-api.d.ts +35 -0
- package/dist/nexus-api.d.ts.map +1 -0
- package/dist/nexus-api.js +90 -0
- package/dist/nexus-api.js.map +1 -0
- package/dist/server.d.ts +67 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +189 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/add-task-note.d.ts +34 -0
- package/dist/tools/add-task-note.d.ts.map +1 -0
- package/dist/tools/add-task-note.js +39 -0
- package/dist/tools/add-task-note.js.map +1 -0
- package/dist/tools/append-session-entry.d.ts +53 -0
- package/dist/tools/append-session-entry.d.ts.map +1 -0
- package/dist/tools/append-session-entry.js +68 -0
- package/dist/tools/append-session-entry.js.map +1 -0
- package/dist/tools/create-task.d.ts +52 -0
- package/dist/tools/create-task.d.ts.map +1 -0
- package/dist/tools/create-task.js +51 -0
- package/dist/tools/create-task.js.map +1 -0
- package/dist/tools/decision-comments.d.ts +54 -0
- package/dist/tools/decision-comments.d.ts.map +1 -0
- package/dist/tools/decision-comments.js +81 -0
- package/dist/tools/decision-comments.js.map +1 -0
- package/dist/tools/get-document.d.ts +47 -0
- package/dist/tools/get-document.d.ts.map +1 -0
- package/dist/tools/get-document.js +68 -0
- package/dist/tools/get-document.js.map +1 -0
- package/dist/tools/get-project-memory.d.ts +47 -0
- package/dist/tools/get-project-memory.d.ts.map +1 -0
- package/dist/tools/get-project-memory.js +53 -0
- package/dist/tools/get-project-memory.js.map +1 -0
- package/dist/tools/get-related-entities.d.ts +44 -0
- package/dist/tools/get-related-entities.d.ts.map +1 -0
- package/dist/tools/get-related-entities.js +60 -0
- package/dist/tools/get-related-entities.js.map +1 -0
- package/dist/tools/governance.d.ts +90 -0
- package/dist/tools/governance.d.ts.map +1 -0
- package/dist/tools/governance.js +127 -0
- package/dist/tools/governance.js.map +1 -0
- package/dist/tools/ingest-document.d.ts +40 -0
- package/dist/tools/ingest-document.d.ts.map +1 -0
- package/dist/tools/ingest-document.js +49 -0
- package/dist/tools/ingest-document.js.map +1 -0
- package/dist/tools/letter-inbox.d.ts +80 -0
- package/dist/tools/letter-inbox.d.ts.map +1 -0
- package/dist/tools/letter-inbox.js +118 -0
- package/dist/tools/letter-inbox.js.map +1 -0
- package/dist/tools/letters.d.ts +91 -0
- package/dist/tools/letters.d.ts.map +1 -0
- package/dist/tools/letters.js +112 -0
- package/dist/tools/letters.js.map +1 -0
- package/dist/tools/list-documents.d.ts +33 -0
- package/dist/tools/list-documents.d.ts.map +1 -0
- package/dist/tools/list-documents.js +47 -0
- package/dist/tools/list-documents.js.map +1 -0
- package/dist/tools/list-tasks.d.ts +39 -0
- package/dist/tools/list-tasks.d.ts.map +1 -0
- package/dist/tools/list-tasks.js +46 -0
- package/dist/tools/list-tasks.js.map +1 -0
- package/dist/tools/project-list.d.ts +28 -0
- package/dist/tools/project-list.d.ts.map +1 -0
- package/dist/tools/project-list.js +43 -0
- package/dist/tools/project-list.js.map +1 -0
- package/dist/tools/reviews.d.ts +145 -0
- package/dist/tools/reviews.d.ts.map +1 -0
- package/dist/tools/reviews.js +220 -0
- package/dist/tools/reviews.js.map +1 -0
- package/dist/tools/search-knowledge.d.ts +48 -0
- package/dist/tools/search-knowledge.d.ts.map +1 -0
- package/dist/tools/search-knowledge.js +54 -0
- package/dist/tools/search-knowledge.js.map +1 -0
- package/dist/tools/sessions.d.ts +81 -0
- package/dist/tools/sessions.d.ts.map +1 -0
- package/dist/tools/sessions.js +123 -0
- package/dist/tools/sessions.js.map +1 -0
- package/dist/tools/skill-assign.d.ts +77 -0
- package/dist/tools/skill-assign.d.ts.map +1 -0
- package/dist/tools/skill-assign.js +108 -0
- package/dist/tools/skill-assign.js.map +1 -0
- package/dist/tools/skills.d.ts +138 -0
- package/dist/tools/skills.d.ts.map +1 -0
- package/dist/tools/skills.js +195 -0
- package/dist/tools/skills.js.map +1 -0
- package/dist/tools/update-task-status.d.ts +48 -0
- package/dist/tools/update-task-status.d.ts.map +1 -0
- package/dist/tools/update-task-status.js +51 -0
- package/dist/tools/update-task-status.js.map +1 -0
- package/package.json +30 -0
- package/src/__tests__/auth.test.ts +162 -0
- package/src/__tests__/decision-comments.test.ts +173 -0
- package/src/__tests__/e2e-integration.test.ts +443 -0
- package/src/__tests__/helpers.ts +58 -0
- package/src/__tests__/layer1-knowledge.test.ts +302 -0
- package/src/__tests__/layer2-coordination.test.ts +842 -0
- package/src/__tests__/layer3-governance.test.ts +205 -0
- package/src/__tests__/project-list-and-skill-assign.test.ts +282 -0
- package/src/__tests__/reviews.test.ts +420 -0
- package/src/__tests__/server.test.ts +250 -0
- package/src/__tests__/setup.ts +15 -0
- package/src/__tests__/task-list-and-doc-list.test.ts +226 -0
- package/src/auth.ts +81 -0
- package/src/nexus-api.ts +127 -0
- package/src/server.ts +520 -0
- package/src/tools/add-task-note.ts +50 -0
- package/src/tools/append-session-entry.ts +84 -0
- package/src/tools/create-task.ts +66 -0
- package/src/tools/decision-comments.ts +103 -0
- package/src/tools/get-document.ts +80 -0
- package/src/tools/get-project-memory.ts +65 -0
- package/src/tools/get-related-entities.ts +73 -0
- package/src/tools/governance.ts +165 -0
- package/src/tools/ingest-document.ts +65 -0
- package/src/tools/letter-inbox.ts +157 -0
- package/src/tools/letters.ts +144 -0
- package/src/tools/list-documents.ts +58 -0
- package/src/tools/list-tasks.ts +57 -0
- package/src/tools/project-list.ts +52 -0
- package/src/tools/reviews.ts +281 -0
- package/src/tools/search-knowledge.ts +68 -0
- package/src/tools/sessions.ts +157 -0
- package/src/tools/skill-assign.ts +142 -0
- package/src/tools/skills.ts +255 -0
- package/src/tools/update-task-status.ts +64 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +8 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* nexus-mcp -- MCP Server for Nexus
|
|
4
|
+
*
|
|
5
|
+
* Provides Knowledge Access (Layer 1), Coordination (Layer 2),
|
|
6
|
+
* Governance (Layer 3), and Reviews (Layer 4) tools.
|
|
7
|
+
* Runs as a standalone stdio MCP server.
|
|
8
|
+
*
|
|
9
|
+
* Authentication:
|
|
10
|
+
* Identity is resolved once at startup from NEXUS_PRIVATE_TOKEN (nxs_pat_*).
|
|
11
|
+
* All write tools receive user_id automatically from the resolved identity.
|
|
12
|
+
* Callers no longer pass user_id as a parameter.
|
|
13
|
+
*
|
|
14
|
+
* Layer 1 - Knowledge Access:
|
|
15
|
+
* - kb_search: Search project knowledge (keyword/semantic/hybrid)
|
|
16
|
+
* - kb_memory: Curated project context for agent bootstrapping
|
|
17
|
+
* - kb_get: Fetch a single knowledge object
|
|
18
|
+
* - kb_related: Navigate entity relationships
|
|
19
|
+
* - project_list: List accessible projects
|
|
20
|
+
*
|
|
21
|
+
* Layer 2 - Coordination:
|
|
22
|
+
* - vl_create: Create a new vault letter
|
|
23
|
+
* - vl_reply: Reply to an existing vault letter
|
|
24
|
+
* - vl_inbox: List letters addressed to the calling agent/user
|
|
25
|
+
* - vl_outbox: List letters sent by the calling agent/user
|
|
26
|
+
* - vl_ack: Acknowledge receipt of a new vault letter
|
|
27
|
+
* - task_create: Create a task in a project
|
|
28
|
+
* - task_update: Update task status, priority, or assignee
|
|
29
|
+
* - task_note: Append a note to a task (append-only)
|
|
30
|
+
* - task_list: List tasks for a project with filters
|
|
31
|
+
* - dc_add: Add a comment to an ADR (append-only)
|
|
32
|
+
* - dc_list: List comments for an ADR
|
|
33
|
+
* - sk_list: List skills for the current tenant
|
|
34
|
+
* - sk_get: Get full skill content by identifier
|
|
35
|
+
* - sk_create: Create a new skill in draft status
|
|
36
|
+
* - sk_update: Update skill content or metadata
|
|
37
|
+
* - sk_activate: Change skill status (draft/active/archived)
|
|
38
|
+
* - sk_assign: Assign a skill to a project
|
|
39
|
+
* - sk_unassign: Remove a skill assignment from a project
|
|
40
|
+
* - sk_export: Export all skill assignments for a project
|
|
41
|
+
* - doc_ingest: Push text/markdown content into project knowledge base
|
|
42
|
+
* - doc_list: List ingested documents for a project
|
|
43
|
+
* - session_append: Append to a session (write-isolated)
|
|
44
|
+
* - session_create: Start a new work session
|
|
45
|
+
* - session_close: End a session with summary and next entry point
|
|
46
|
+
* - session_list: List open sessions for a project
|
|
47
|
+
*
|
|
48
|
+
* Layer 3 - Governance:
|
|
49
|
+
* - adr_create: Create a new ADR draft
|
|
50
|
+
* - adr_submit: Submit an ADR for review
|
|
51
|
+
* - adr_decide: Accept or reject an ADR
|
|
52
|
+
*
|
|
53
|
+
* Layer 4 - Reviews:
|
|
54
|
+
* - rv_list: List reviews with optional filters
|
|
55
|
+
* - rv_get: Get a review by ID or entity reference
|
|
56
|
+
* - rv_create: Create a new review for an entity
|
|
57
|
+
* - rv_decide: Transition a review state
|
|
58
|
+
* - rv_comment: Add a comment to a review
|
|
59
|
+
*
|
|
60
|
+
* Usage:
|
|
61
|
+
* npx tsx src/mcp/server.ts
|
|
62
|
+
*
|
|
63
|
+
* Or via .mcp.json configuration:
|
|
64
|
+
* { "command": "npx", "args": ["tsx", "src/mcp/server.ts"] }
|
|
65
|
+
*/
|
|
66
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
67
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
68
|
+
import { getIdentity, initIdentity } from './auth.js';
|
|
69
|
+
// Layer 1: Knowledge Access
|
|
70
|
+
import { projectList, projectListSchema } from './tools/project-list.js';
|
|
71
|
+
import { getDocument, getDocumentSchema } from './tools/get-document.js';
|
|
72
|
+
import { getProjectMemory, getProjectMemorySchema, } from './tools/get-project-memory.js';
|
|
73
|
+
import { getRelatedEntities, getRelatedEntitiesSchema, } from './tools/get-related-entities.js';
|
|
74
|
+
import { searchKnowledge, searchKnowledgeSchema, } from './tools/search-knowledge.js';
|
|
75
|
+
// Layer 2: Coordination
|
|
76
|
+
import { addTaskNote, addTaskNoteSchema } from './tools/add-task-note.js';
|
|
77
|
+
import { appendSessionEntry, appendSessionEntrySchema, } from './tools/append-session-entry.js';
|
|
78
|
+
import { createTask, createTaskSchema } from './tools/create-task.js';
|
|
79
|
+
import { addDecisionComment, addDecisionCommentSchema, listDecisionComments, listDecisionCommentsSchema, } from './tools/decision-comments.js';
|
|
80
|
+
import { ingestDocument, ingestDocumentSchema, } from './tools/ingest-document.js';
|
|
81
|
+
import { acknowledgeLetter, acknowledgeLetterSchema, listInbox, listInboxSchema, listOutbox, listOutboxSchema, } from './tools/letter-inbox.js';
|
|
82
|
+
import { createLetter, createLetterSchema, replyLetter, replyLetterSchema, } from './tools/letters.js';
|
|
83
|
+
import { listDocuments, listDocumentsSchema, } from './tools/list-documents.js';
|
|
84
|
+
import { listTasks, listTasksSchema } from './tools/list-tasks.js';
|
|
85
|
+
import { closeSession, closeSessionSchema, createSession, createSessionSchema, listOpenSessions, listOpenSessionsSchema, } from './tools/sessions.js';
|
|
86
|
+
import { skActivate, skActivateSchema, skCreate, skCreateSchema, skGet, skGetSchema, skList, skListSchema, skUpdate, skUpdateSchema, } from './tools/skills.js';
|
|
87
|
+
import { skAssign, skAssignSchema, skExport, skExportSchema, skUnassign, skUnassignSchema, } from './tools/skill-assign.js';
|
|
88
|
+
import { updateTaskStatus, updateTaskStatusSchema, } from './tools/update-task-status.js';
|
|
89
|
+
// Layer 3: Governance
|
|
90
|
+
import { createAdrDraft, createAdrDraftSchema, recordAdrDecision, recordAdrDecisionSchema, submitAdrReview, submitAdrReviewSchema, } from './tools/governance.js';
|
|
91
|
+
// Layer 4: Reviews
|
|
92
|
+
import { rvComment, rvCommentSchema, rvCreate, rvCreateSchema, rvDecide, rvDecideSchema, rvGet, rvGetSchema, rvList, rvListSchema, } from './tools/reviews.js';
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
// Identity injection helper
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
/**
|
|
97
|
+
* Wrap a write-tool handler to inject user_id from the resolved identity.
|
|
98
|
+
* The caller does not need to pass user_id — it comes from the token.
|
|
99
|
+
*/
|
|
100
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
101
|
+
function withIdentity(handler) {
|
|
102
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
103
|
+
return async (args) => {
|
|
104
|
+
const identity = getIdentity();
|
|
105
|
+
return handler({ ...args, user_id: identity.userId });
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// Server setup
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
const server = new McpServer({
|
|
112
|
+
name: 'nexus-mcp',
|
|
113
|
+
version: '0.6.1',
|
|
114
|
+
}, {
|
|
115
|
+
capabilities: {
|
|
116
|
+
tools: {},
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// Layer 1: Knowledge Access tools
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
server.tool('kb_search', 'Search project knowledge using keyword, semantic, or hybrid mode. Applies project scope filters before retrieval. Returns matching entities with relevance ranking.', searchKnowledgeSchema, async (args) => searchKnowledge(args));
|
|
123
|
+
server.tool('kb_memory', 'Get curated project context for agent bootstrapping. Returns ADRs, active tasks, recent sessions, open letters, and other project knowledge based on selected categories and depth.', getProjectMemorySchema, async (args) => getProjectMemory(args));
|
|
124
|
+
server.tool('kb_get', 'Fetch a single knowledge object (session, decision, letter, task, etc.) in structured, markdown, or summary format. Includes child entries for sessions and letters.', getDocumentSchema, async (args) => getDocument(args));
|
|
125
|
+
server.tool('kb_related', 'Navigate entity relationships. Returns graph-neighbor entities related to a given item, such as supersession chains for ADRs, thread siblings for letters, or tasks created during sessions.', getRelatedEntitiesSchema, async (args) => getRelatedEntities(args));
|
|
126
|
+
server.tool('project_list', 'List accessible projects for the authenticated user or agent. Returns project metadata ordered by name.', projectListSchema, async (args) => projectList(args));
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Layer 2: Coordination tools
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
server.tool('vl_create', 'Create a new vault letter for agent-to-agent or agent-to-human coordination. Returns the new letter ID and status.', createLetterSchema, withIdentity(createLetter));
|
|
131
|
+
server.tool('vl_reply', 'Reply to an existing vault letter with a new message. Optionally update the letter status. Enforces append-only semantics.', replyLetterSchema, withIdentity(replyLetter));
|
|
132
|
+
server.tool('vl_inbox', 'List vault letters addressed to the calling agent or user. Returns letters scoped to the given project, ordered by blocking status and recency. Supports status filtering.', listInboxSchema, withIdentity(listInbox));
|
|
133
|
+
server.tool('vl_outbox', 'List vault letters sent by the calling agent or user. Returns letters scoped to the given project, ordered by recency. Supports status filtering.', listOutboxSchema, withIdentity(listOutbox));
|
|
134
|
+
server.tool('vl_ack', 'Acknowledge receipt of a new vault letter. Transitions the letter from new to acknowledged status and appends an acknowledgment message.', acknowledgeLetterSchema, withIdentity(acknowledgeLetter));
|
|
135
|
+
server.tool('task_create', 'Create a new task within a project scope. Returns the new task ID.', createTaskSchema, withIdentity(createTask));
|
|
136
|
+
server.tool('task_update', 'Update the status of an existing task. Optionally change priority or assignee. Automatically records a status-change note for audit trail.', updateTaskStatusSchema, withIdentity(updateTaskStatus));
|
|
137
|
+
server.tool('task_note', 'Append a note to an existing task. Notes are append-only and maintain a chronological audit trail. Useful for recording progress, blockers, or decisions.', addTaskNoteSchema, withIdentity(addTaskNote));
|
|
138
|
+
server.tool('task_list', 'List tasks for a project with optional status filtering. Returns tasks ordered by creation date (newest first).', listTasksSchema, withIdentity(listTasks));
|
|
139
|
+
server.tool('doc_ingest', 'Push text or markdown content into a project knowledge base. Creates an ingest item that can later be classified. Useful for agents to persist research results, generated documents, or extracted knowledge.', ingestDocumentSchema, withIdentity(ingestDocument));
|
|
140
|
+
server.tool('doc_list', 'List ingested documents for a project with optional source filtering. Returns documents ordered by creation date (newest first).', listDocumentsSchema, withIdentity(listDocuments));
|
|
141
|
+
server.tool('session_append', 'Append an entry to an existing session. Enforces session write isolation: only the session creator can append entries.', appendSessionEntrySchema, withIdentity(appendSessionEntry));
|
|
142
|
+
server.tool('session_create', 'Create a new work session for a project. Returns the session ID. The session starts in open status and must be closed explicitly via session_close.', createSessionSchema, withIdentity(createSession));
|
|
143
|
+
server.tool('session_close', 'Close an open session. Sets status to closed, optionally records a summary and next entry point. Only the session creator can close it.', closeSessionSchema, withIdentity(closeSession));
|
|
144
|
+
server.tool('session_list', 'List open sessions for a project. Returns sessions ordered by creation date (newest first). Useful for checking active work before starting a new session.', listOpenSessionsSchema, async (args) => listOpenSessions(args));
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
// Layer 2 (continued): Decision comment tools
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
server.tool('dc_add', 'Add a comment to an ADR decision. Comments are append-only and support both human and agent actors.', addDecisionCommentSchema, withIdentity(addDecisionComment));
|
|
149
|
+
server.tool('dc_list', 'List comments for an ADR decision in chronological order.', listDecisionCommentsSchema, async (args) => listDecisionComments(args));
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
// Layer 2 (continued): Skill management tools
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
server.tool('sk_list', 'List skills for the current tenant. Supports status filtering (draft, active, archived). Returns skill metadata without full body content.', skListSchema, withIdentity(skList));
|
|
154
|
+
server.tool('sk_get', 'Get full skill content by skill identifier or UUID. Includes associated command information.', skGetSchema, withIdentity(skGet));
|
|
155
|
+
server.tool('sk_create', 'Create a new skill in draft status. Optionally auto-generates an OpenCode command. Skill content is markdown-based instruction text.', skCreateSchema, withIdentity(skCreate));
|
|
156
|
+
server.tool('sk_update', 'Update an existing skill content, metadata, or command auto-generation setting. Increments version when body changes.', skUpdateSchema, withIdentity(skUpdate));
|
|
157
|
+
server.tool('sk_activate', 'Change a skill status (draft, active, archived). Active skills are available for agent loading and project selection.', skActivateSchema, withIdentity(skActivate));
|
|
158
|
+
server.tool('sk_assign', 'Assign a skill to a project. Optionally pin to a specific version and set enabled state.', skAssignSchema, withIdentity(skAssign));
|
|
159
|
+
server.tool('sk_unassign', 'Remove a skill assignment from a project.', skUnassignSchema, withIdentity(skUnassign));
|
|
160
|
+
server.tool('sk_export', 'Export all skill assignments for a project. Returns the full assignment list with pinned versions and enabled states.', skExportSchema, withIdentity(skExport));
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
// Layer 3: Governance tools
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
server.tool('adr_create', 'Create a new ADR (Architecture Decision Record) in draft state. Auto-assigns the next ADR number for the project. Optionally links to a superseded ADR.', createAdrDraftSchema, withIdentity(createAdrDraft));
|
|
165
|
+
server.tool('adr_submit', 'Submit an ADR for review. Transitions an ADR from draft to under_review state. Only drafts can be submitted.', submitAdrReviewSchema, withIdentity(submitAdrReview));
|
|
166
|
+
server.tool('adr_decide', 'Accept or reject an ADR that is under review. If accepted and it supersedes another ADR, the superseded ADR is automatically marked. Optional rationale is appended to the ADR body.', recordAdrDecisionSchema, withIdentity(recordAdrDecision));
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
// Layer 4: Review tools
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
server.tool('rv_list', 'List reviews with optional filters by entity type and status. Returns reviews ordered by recency.', rvListSchema, withIdentity(rvList));
|
|
171
|
+
server.tool('rv_get', 'Get a review by review ID, or by entity type and entity ID. Returns full review details including status and history.', rvGetSchema, withIdentity(rvGet));
|
|
172
|
+
server.tool('rv_create', 'Create a new review for a skill or agent entity. Returns the new review ID and initial status.', rvCreateSchema, withIdentity(rvCreate));
|
|
173
|
+
server.tool('rv_decide', 'Transition a review state (submit, accept, reject, request_revision, resubmit, archive). Enforces valid state transitions. Optional rationale is recorded.', rvDecideSchema, withIdentity(rvDecide));
|
|
174
|
+
server.tool('rv_comment', 'Add a comment to a review. Supports inline comments with optional line range. Comments are append-only and maintain a chronological audit trail.', rvCommentSchema, withIdentity(rvComment));
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
// Start
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
async function main() {
|
|
179
|
+
// Resolve identity from NEXUS_PRIVATE_TOKEN before accepting connections
|
|
180
|
+
await initIdentity();
|
|
181
|
+
const transport = new StdioServerTransport();
|
|
182
|
+
await server.connect(transport);
|
|
183
|
+
console.error('[nexus-mcp] Server started on stdio');
|
|
184
|
+
}
|
|
185
|
+
main().catch((err) => {
|
|
186
|
+
console.error('[nexus-mcp] Fatal error:', err);
|
|
187
|
+
process.exit(1);
|
|
188
|
+
});
|
|
189
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* task_note -- Layer 2 Coordination
|
|
3
|
+
*
|
|
4
|
+
* Appends a note to an existing task. Notes are append-only and
|
|
5
|
+
* maintain a chronological history/timeline.
|
|
6
|
+
* Delegates to POST /api/mcp/tasks (action: task_note).
|
|
7
|
+
*/
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
export declare const addTaskNoteSchema: {
|
|
10
|
+
task_id: z.ZodString;
|
|
11
|
+
note: z.ZodString;
|
|
12
|
+
agent_id: z.ZodOptional<z.ZodString>;
|
|
13
|
+
};
|
|
14
|
+
type AddTaskNoteArgs = {
|
|
15
|
+
task_id: string;
|
|
16
|
+
note: string;
|
|
17
|
+
user_id: string;
|
|
18
|
+
agent_id?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function addTaskNote(args: AddTaskNoteArgs): Promise<{
|
|
21
|
+
content: {
|
|
22
|
+
type: "text";
|
|
23
|
+
text: string;
|
|
24
|
+
}[];
|
|
25
|
+
isError: boolean;
|
|
26
|
+
} | {
|
|
27
|
+
content: {
|
|
28
|
+
type: "text";
|
|
29
|
+
text: string;
|
|
30
|
+
}[];
|
|
31
|
+
isError?: undefined;
|
|
32
|
+
}>;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=add-task-note.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-task-note.d.ts","sourceRoot":"","sources":["../../src/tools/add-task-note.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,iBAAiB;;;;CAI7B,CAAA;AAED,KAAK,eAAe,GAAG;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe;;;;;;;;;;;;GAyBtD"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* task_note -- Layer 2 Coordination
|
|
3
|
+
*
|
|
4
|
+
* Appends a note to an existing task. Notes are append-only and
|
|
5
|
+
* maintain a chronological history/timeline.
|
|
6
|
+
* Delegates to POST /api/mcp/tasks (action: task_note).
|
|
7
|
+
*/
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import { nexusPost } from '../nexus-api.js';
|
|
10
|
+
export const addTaskNoteSchema = {
|
|
11
|
+
task_id: z.string().uuid().describe('Task UUID to add a note to'),
|
|
12
|
+
note: z.string().max(10_000).describe('Note content to append'),
|
|
13
|
+
agent_id: z.string().max(200).optional().describe('Agent identifier if applicable'),
|
|
14
|
+
};
|
|
15
|
+
export async function addTaskNote(args) {
|
|
16
|
+
const result = await nexusPost('/api/mcp/tasks', {
|
|
17
|
+
action: 'task_note',
|
|
18
|
+
task_id: args.task_id,
|
|
19
|
+
note: args.note,
|
|
20
|
+
agent_id: args.agent_id,
|
|
21
|
+
});
|
|
22
|
+
if (!result.ok) {
|
|
23
|
+
return {
|
|
24
|
+
content: [
|
|
25
|
+
{
|
|
26
|
+
type: 'text',
|
|
27
|
+
text: JSON.stringify({ error: result.error }, null, 2),
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
isError: true,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
content: [
|
|
35
|
+
{ type: 'text', text: JSON.stringify(result.data, null, 2) },
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=add-task-note.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-task-note.js","sourceRoot":"","sources":["../../src/tools/add-task-note.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;IACjE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IAC/D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;CACpF,CAAA;AASD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAqB;IACrD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,gBAAgB,EAAE;QAC/C,MAAM,EAAE,WAAW;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAA;IAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;iBACvD;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAA;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;SACtE;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session_append -- Layer 2 Coordination
|
|
3
|
+
*
|
|
4
|
+
* Appends an entry to an existing session.
|
|
5
|
+
* Enforces append-only semantics and session write isolation.
|
|
6
|
+
* Delegates to POST /api/mcp/sessions (action: session_append).
|
|
7
|
+
*/
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
export declare const appendSessionEntrySchema: {
|
|
10
|
+
session_id: z.ZodString;
|
|
11
|
+
entry_type: z.ZodEnum<{
|
|
12
|
+
decision_referenced: "decision_referenced";
|
|
13
|
+
task_created: "task_created";
|
|
14
|
+
task_updated: "task_updated";
|
|
15
|
+
letter_sent: "letter_sent";
|
|
16
|
+
letter_replied: "letter_replied";
|
|
17
|
+
research_added: "research_added";
|
|
18
|
+
conflict_detected: "conflict_detected";
|
|
19
|
+
adr_drafted: "adr_drafted";
|
|
20
|
+
adr_accepted: "adr_accepted";
|
|
21
|
+
handoff_recorded: "handoff_recorded";
|
|
22
|
+
note: "note";
|
|
23
|
+
correction: "correction";
|
|
24
|
+
}>;
|
|
25
|
+
summary: z.ZodString;
|
|
26
|
+
linked_entity_type: z.ZodOptional<z.ZodString>;
|
|
27
|
+
linked_entity_id: z.ZodOptional<z.ZodString>;
|
|
28
|
+
agent_id: z.ZodOptional<z.ZodString>;
|
|
29
|
+
};
|
|
30
|
+
type AppendSessionEntryArgs = {
|
|
31
|
+
session_id: string;
|
|
32
|
+
entry_type: string;
|
|
33
|
+
summary: string;
|
|
34
|
+
linked_entity_type?: string;
|
|
35
|
+
linked_entity_id?: string;
|
|
36
|
+
user_id: string;
|
|
37
|
+
agent_id?: string;
|
|
38
|
+
};
|
|
39
|
+
export declare function appendSessionEntry(args: AppendSessionEntryArgs): Promise<{
|
|
40
|
+
content: {
|
|
41
|
+
type: "text";
|
|
42
|
+
text: string;
|
|
43
|
+
}[];
|
|
44
|
+
isError: boolean;
|
|
45
|
+
} | {
|
|
46
|
+
content: {
|
|
47
|
+
type: "text";
|
|
48
|
+
text: string;
|
|
49
|
+
}[];
|
|
50
|
+
isError?: undefined;
|
|
51
|
+
}>;
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=append-session-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"append-session-entry.d.ts","sourceRoot":"","sources":["../../src/tools/append-session-entry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;CAgCpC,CAAA;AAED,KAAK,sBAAsB,GAAG;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,sBAAsB;;;;;;;;;;;;GA4BpE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session_append -- Layer 2 Coordination
|
|
3
|
+
*
|
|
4
|
+
* Appends an entry to an existing session.
|
|
5
|
+
* Enforces append-only semantics and session write isolation.
|
|
6
|
+
* Delegates to POST /api/mcp/sessions (action: session_append).
|
|
7
|
+
*/
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import { nexusPost } from '../nexus-api.js';
|
|
10
|
+
export const appendSessionEntrySchema = {
|
|
11
|
+
session_id: z.string().uuid().describe('Session UUID to append to'),
|
|
12
|
+
entry_type: z
|
|
13
|
+
.enum([
|
|
14
|
+
'decision_referenced',
|
|
15
|
+
'task_created',
|
|
16
|
+
'task_updated',
|
|
17
|
+
'letter_sent',
|
|
18
|
+
'letter_replied',
|
|
19
|
+
'research_added',
|
|
20
|
+
'conflict_detected',
|
|
21
|
+
'adr_drafted',
|
|
22
|
+
'adr_accepted',
|
|
23
|
+
'handoff_recorded',
|
|
24
|
+
'note',
|
|
25
|
+
'correction',
|
|
26
|
+
])
|
|
27
|
+
.describe('Type of session entry'),
|
|
28
|
+
summary: z.string().max(100_000).describe('Entry content / summary text'),
|
|
29
|
+
linked_entity_type: z
|
|
30
|
+
.string()
|
|
31
|
+
.max(50)
|
|
32
|
+
.optional()
|
|
33
|
+
.describe('Type of linked entity (e.g., "task", "decision", "letter", "research_link")'),
|
|
34
|
+
linked_entity_id: z
|
|
35
|
+
.string()
|
|
36
|
+
.uuid()
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('UUID of the linked entity'),
|
|
39
|
+
agent_id: z.string().max(200).optional().describe('Agent identifier if applicable'),
|
|
40
|
+
};
|
|
41
|
+
export async function appendSessionEntry(args) {
|
|
42
|
+
const result = await nexusPost('/api/mcp/sessions', {
|
|
43
|
+
action: 'session_append',
|
|
44
|
+
session_id: args.session_id,
|
|
45
|
+
entry_type: args.entry_type,
|
|
46
|
+
summary: args.summary,
|
|
47
|
+
agent_id: args.agent_id,
|
|
48
|
+
linked_entity_type: args.linked_entity_type,
|
|
49
|
+
linked_entity_id: args.linked_entity_id,
|
|
50
|
+
});
|
|
51
|
+
if (!result.ok) {
|
|
52
|
+
return {
|
|
53
|
+
content: [
|
|
54
|
+
{
|
|
55
|
+
type: 'text',
|
|
56
|
+
text: JSON.stringify({ error: result.error }, null, 2),
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
isError: true,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
content: [
|
|
64
|
+
{ type: 'text', text: JSON.stringify(result.data, null, 2) },
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=append-session-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"append-session-entry.js","sourceRoot":"","sources":["../../src/tools/append-session-entry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IACnE,UAAU,EAAE,CAAC;SACV,IAAI,CAAC;QACJ,qBAAqB;QACrB,cAAc;QACd,cAAc;QACd,aAAa;QACb,gBAAgB;QAChB,gBAAgB;QAChB,mBAAmB;QACnB,aAAa;QACb,cAAc;QACd,kBAAkB;QAClB,MAAM;QACN,YAAY;KACb,CAAC;SACD,QAAQ,CAAC,uBAAuB,CAAC;IACpC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,8BAA8B,CAAC;IACzE,kBAAkB,EAAE,CAAC;SAClB,MAAM,EAAE;SACR,GAAG,CAAC,EAAE,CAAC;SACP,QAAQ,EAAE;SACV,QAAQ,CACP,6EAA6E,CAC9E;IACH,gBAAgB,EAAE,CAAC;SAChB,MAAM,EAAE;SACR,IAAI,EAAE;SACN,QAAQ,EAAE;SACV,QAAQ,CAAC,2BAA2B,CAAC;IACxC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;CACpF,CAAA;AAYD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAA4B;IACnE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,mBAAmB,EAAE;QAClD,MAAM,EAAE,gBAAgB;QACxB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;QAC3C,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;KACxC,CAAC,CAAA;IAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;iBACvD;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAA;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;SACtE;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* task_create -- Layer 2 Coordination
|
|
3
|
+
*
|
|
4
|
+
* Creates a new task within a project scope.
|
|
5
|
+
* Delegates to POST /api/mcp/tasks (action: task_create).
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
export declare const createTaskSchema: {
|
|
9
|
+
project_id: z.ZodString;
|
|
10
|
+
title: z.ZodString;
|
|
11
|
+
description: z.ZodOptional<z.ZodString>;
|
|
12
|
+
priority: z.ZodDefault<z.ZodEnum<{
|
|
13
|
+
low: "low";
|
|
14
|
+
normal: "normal";
|
|
15
|
+
high: "high";
|
|
16
|
+
urgent: "urgent";
|
|
17
|
+
}>>;
|
|
18
|
+
assignee: z.ZodOptional<z.ZodString>;
|
|
19
|
+
status: z.ZodDefault<z.ZodEnum<{
|
|
20
|
+
open: "open";
|
|
21
|
+
in_progress: "in_progress";
|
|
22
|
+
blocked: "blocked";
|
|
23
|
+
done: "done";
|
|
24
|
+
cancelled: "cancelled";
|
|
25
|
+
}>>;
|
|
26
|
+
agent_id: z.ZodOptional<z.ZodString>;
|
|
27
|
+
};
|
|
28
|
+
type CreateTaskArgs = {
|
|
29
|
+
project_id: string;
|
|
30
|
+
title: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
priority?: string;
|
|
33
|
+
assignee?: string;
|
|
34
|
+
status?: string;
|
|
35
|
+
user_id: string;
|
|
36
|
+
agent_id?: string;
|
|
37
|
+
};
|
|
38
|
+
export declare function createTask(args: CreateTaskArgs): Promise<{
|
|
39
|
+
content: {
|
|
40
|
+
type: "text";
|
|
41
|
+
text: string;
|
|
42
|
+
}[];
|
|
43
|
+
isError: boolean;
|
|
44
|
+
} | {
|
|
45
|
+
content: {
|
|
46
|
+
type: "text";
|
|
47
|
+
text: string;
|
|
48
|
+
}[];
|
|
49
|
+
isError?: undefined;
|
|
50
|
+
}>;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=create-task.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-task.d.ts","sourceRoot":"","sources":["../../src/tools/create-task.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;CAc5B,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc;;;;;;;;;;;;GA4BpD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* task_create -- Layer 2 Coordination
|
|
3
|
+
*
|
|
4
|
+
* Creates a new task within a project scope.
|
|
5
|
+
* Delegates to POST /api/mcp/tasks (action: task_create).
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { nexusPost } from '../nexus-api.js';
|
|
9
|
+
export const createTaskSchema = {
|
|
10
|
+
project_id: z.string().uuid().describe('Project UUID'),
|
|
11
|
+
title: z.string().max(500).describe('Task title'),
|
|
12
|
+
description: z.string().max(100_000).optional().describe('Task description'),
|
|
13
|
+
priority: z
|
|
14
|
+
.enum(['low', 'normal', 'high', 'urgent'])
|
|
15
|
+
.default('normal')
|
|
16
|
+
.describe('Task priority'),
|
|
17
|
+
assignee: z.string().uuid().optional().describe('UUID of the assigned user'),
|
|
18
|
+
status: z
|
|
19
|
+
.enum(['open', 'in_progress', 'blocked', 'done', 'cancelled'])
|
|
20
|
+
.default('open')
|
|
21
|
+
.describe('Initial task status'),
|
|
22
|
+
agent_id: z.string().max(200).optional().describe('Agent identifier if applicable'),
|
|
23
|
+
};
|
|
24
|
+
export async function createTask(args) {
|
|
25
|
+
const result = await nexusPost('/api/mcp/tasks', {
|
|
26
|
+
action: 'task_create',
|
|
27
|
+
project_id: args.project_id,
|
|
28
|
+
title: args.title,
|
|
29
|
+
description: args.description,
|
|
30
|
+
priority: args.priority ?? 'normal',
|
|
31
|
+
assignee: args.assignee,
|
|
32
|
+
status: args.status ?? 'open',
|
|
33
|
+
});
|
|
34
|
+
if (!result.ok) {
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{
|
|
38
|
+
type: 'text',
|
|
39
|
+
text: JSON.stringify({ error: result.error }, null, 2),
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
isError: true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
content: [
|
|
47
|
+
{ type: 'text', text: JSON.stringify(result.data, null, 2) },
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=create-task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-task.js","sourceRoot":"","sources":["../../src/tools/create-task.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;IACtD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;IACjD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAC5E,QAAQ,EAAE,CAAC;SACR,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;SACzC,OAAO,CAAC,QAAQ,CAAC;SACjB,QAAQ,CAAC,eAAe,CAAC;IAC5B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IAC5E,MAAM,EAAE,CAAC;SACN,IAAI,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;SAC7D,OAAO,CAAC,MAAM,CAAC;SACf,QAAQ,CAAC,qBAAqB,CAAC;IAClC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;CACpF,CAAA;AAaD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAoB;IACnD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,gBAAgB,EAAE;QAC/C,MAAM,EAAE,aAAa;QACrB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,QAAQ;QACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,MAAM;KAC9B,CAAC,CAAA;IAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;iBACvD;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAA;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;SACtE;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decision comment tools -- Layer 2 Coordination
|
|
3
|
+
*
|
|
4
|
+
* Provides append-only comment threads for ADR decisions.
|
|
5
|
+
* Delegates to POST /api/mcp/governance (actions: dc_add, dc_list).
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
export declare const addDecisionCommentSchema: {
|
|
9
|
+
decision_id: z.ZodString;
|
|
10
|
+
body: z.ZodString;
|
|
11
|
+
agent_id: z.ZodOptional<z.ZodString>;
|
|
12
|
+
};
|
|
13
|
+
type AddDecisionCommentArgs = {
|
|
14
|
+
decision_id: string;
|
|
15
|
+
body: string;
|
|
16
|
+
agent_id?: string;
|
|
17
|
+
user_id: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function addDecisionComment(args: AddDecisionCommentArgs): Promise<{
|
|
20
|
+
content: {
|
|
21
|
+
type: "text";
|
|
22
|
+
text: string;
|
|
23
|
+
}[];
|
|
24
|
+
isError: boolean;
|
|
25
|
+
} | {
|
|
26
|
+
content: {
|
|
27
|
+
type: "text";
|
|
28
|
+
text: string;
|
|
29
|
+
}[];
|
|
30
|
+
isError?: undefined;
|
|
31
|
+
}>;
|
|
32
|
+
export declare const listDecisionCommentsSchema: {
|
|
33
|
+
decision_id: z.ZodString;
|
|
34
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
35
|
+
};
|
|
36
|
+
type ListDecisionCommentsArgs = {
|
|
37
|
+
decision_id: string;
|
|
38
|
+
limit?: number;
|
|
39
|
+
};
|
|
40
|
+
export declare function listDecisionComments(args: ListDecisionCommentsArgs): Promise<{
|
|
41
|
+
content: {
|
|
42
|
+
type: "text";
|
|
43
|
+
text: string;
|
|
44
|
+
}[];
|
|
45
|
+
isError: boolean;
|
|
46
|
+
} | {
|
|
47
|
+
content: {
|
|
48
|
+
type: "text";
|
|
49
|
+
text: string;
|
|
50
|
+
}[];
|
|
51
|
+
isError?: undefined;
|
|
52
|
+
}>;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=decision-comments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-comments.d.ts","sourceRoot":"","sources":["../../src/tools/decision-comments.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAOvB,eAAO,MAAM,wBAAwB;;;;CAQpC,CAAA;AAED,KAAK,sBAAsB,GAAG;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,sBAAsB;;;;;;;;;;;;GAyBpE;AAMD,eAAO,MAAM,0BAA0B;;;CAStC,CAAA;AAED,KAAK,wBAAwB,GAAG;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,wBAAwB;;;;;;;;;;;;GAwBxE"}
|