@gwdn/nexus-mcp 0.8.6 → 0.8.8
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 +3 -4
- package/dist/nexus-api.d.ts.map +1 -1
- package/dist/nexus-api.js +10 -1
- package/dist/nexus-api.js.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +9 -2
- package/.github/workflows/ci.yml +0 -38
- package/.github/workflows/release.yml +0 -57
- package/src/__tests__/auth.test.ts +0 -162
- package/src/__tests__/decision-comments.test.ts +0 -173
- package/src/__tests__/e2e-integration.test.ts +0 -443
- package/src/__tests__/helpers.ts +0 -58
- package/src/__tests__/layer1-knowledge.test.ts +0 -302
- package/src/__tests__/layer2-coordination.test.ts +0 -918
- package/src/__tests__/layer3-governance.test.ts +0 -205
- package/src/__tests__/machine-id.test.ts +0 -136
- package/src/__tests__/nexus-api.test.ts +0 -127
- package/src/__tests__/project-list-and-skill-assign.test.ts +0 -282
- package/src/__tests__/reviews.test.ts +0 -420
- package/src/__tests__/server.test.ts +0 -251
- package/src/__tests__/setup.ts +0 -15
- package/src/__tests__/task-list-and-doc-list.test.ts +0 -226
- package/src/auth.ts +0 -81
- package/src/machine-id.ts +0 -60
- package/src/nexus-api.ts +0 -141
- package/src/server.ts +0 -629
- package/src/tools/add-task-note.ts +0 -50
- package/src/tools/append-session-entry.ts +0 -113
- package/src/tools/classify-document.ts +0 -55
- package/src/tools/create-task.ts +0 -66
- package/src/tools/decision-comments.ts +0 -103
- package/src/tools/delete-document.ts +0 -43
- package/src/tools/directives.ts +0 -303
- package/src/tools/get-document.ts +0 -80
- package/src/tools/get-project-memory.ts +0 -65
- package/src/tools/get-related-entities.ts +0 -73
- package/src/tools/governance.ts +0 -165
- package/src/tools/ingest-document.ts +0 -65
- package/src/tools/letter-inbox.ts +0 -157
- package/src/tools/letters.ts +0 -144
- package/src/tools/list-documents.ts +0 -58
- package/src/tools/list-tasks.ts +0 -57
- package/src/tools/project-list.ts +0 -52
- package/src/tools/reviews.ts +0 -281
- package/src/tools/search-knowledge.ts +0 -68
- package/src/tools/sessions.ts +0 -157
- package/src/tools/skill-assign.ts +0 -142
- package/src/tools/skills.ts +0 -255
- package/src/tools/update-document.ts +0 -66
- package/src/tools/update-task-status.ts +0 -64
- package/tsconfig.json +0 -20
- package/vitest.config.ts +0 -8
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* kb_get -- Layer 1 Knowledge Access
|
|
3
|
-
*
|
|
4
|
-
* Fetches a single knowledge object in canonical form.
|
|
5
|
-
* Returns metadata, current version, body, and linked references.
|
|
6
|
-
* Delegates to POST /api/mcp/documents (action: kb_get).
|
|
7
|
-
*
|
|
8
|
-
* ADR-0001 spec: kb_get(entity_type, entity_id, render_mode)
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { z } from 'zod'
|
|
12
|
-
import { nexusPost } from '../nexus-api.js'
|
|
13
|
-
|
|
14
|
-
export const getDocumentSchema = {
|
|
15
|
-
entity_type: z
|
|
16
|
-
.enum([
|
|
17
|
-
'session',
|
|
18
|
-
'decision',
|
|
19
|
-
'letter',
|
|
20
|
-
'task',
|
|
21
|
-
'research_note',
|
|
22
|
-
'planning_item',
|
|
23
|
-
'ingest_item',
|
|
24
|
-
])
|
|
25
|
-
.describe('Type of the knowledge object'),
|
|
26
|
-
entity_id: z.string().uuid().describe('UUID of the entity'),
|
|
27
|
-
render_mode: z
|
|
28
|
-
.enum(['structured', 'markdown', 'summary'])
|
|
29
|
-
.default('structured')
|
|
30
|
-
.describe('Output format: structured JSON, markdown, or summary'),
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
type GetDocumentArgs = {
|
|
34
|
-
entity_type: string
|
|
35
|
-
entity_id: string
|
|
36
|
-
render_mode?: string
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export async function getDocument(args: GetDocumentArgs) {
|
|
40
|
-
const result = await nexusPost('/api/mcp/documents', {
|
|
41
|
-
action: 'kb_get',
|
|
42
|
-
entity_type: args.entity_type,
|
|
43
|
-
entity_id: args.entity_id,
|
|
44
|
-
render_mode: args.render_mode ?? 'structured',
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
if (!result.ok) {
|
|
48
|
-
return {
|
|
49
|
-
content: [
|
|
50
|
-
{
|
|
51
|
-
type: 'text' as const,
|
|
52
|
-
text: JSON.stringify({ error: result.error }, null, 2),
|
|
53
|
-
},
|
|
54
|
-
],
|
|
55
|
-
isError: true,
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// For markdown and summary modes, the API returns { content: "..." }
|
|
60
|
-
// For structured mode, the API returns the full object
|
|
61
|
-
const data = result.data as Record<string, unknown>
|
|
62
|
-
const renderMode = args.render_mode ?? 'structured'
|
|
63
|
-
|
|
64
|
-
if (renderMode === 'markdown' || renderMode === 'summary') {
|
|
65
|
-
return {
|
|
66
|
-
content: [
|
|
67
|
-
{
|
|
68
|
-
type: 'text' as const,
|
|
69
|
-
text: (data.content as string) ?? JSON.stringify(data, null, 2),
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
content: [
|
|
77
|
-
{ type: 'text' as const, text: JSON.stringify(data, null, 2) },
|
|
78
|
-
],
|
|
79
|
-
}
|
|
80
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* kb_memory -- Layer 1 Knowledge Access
|
|
3
|
-
*
|
|
4
|
-
* Returns curated project context for agent bootstrapping.
|
|
5
|
-
* Includes ADRs, active tasks, recent sessions, open letters, etc.
|
|
6
|
-
* Delegates to POST /api/mcp/memory.
|
|
7
|
-
*
|
|
8
|
-
* ADR-0001 spec: kb_memory(project_id, include[], depth)
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { z } from 'zod'
|
|
12
|
-
import { nexusPost } from '../nexus-api.js'
|
|
13
|
-
|
|
14
|
-
export const getProjectMemorySchema = {
|
|
15
|
-
project_id: z.string().uuid().describe('Project UUID'),
|
|
16
|
-
include: z
|
|
17
|
-
.array(
|
|
18
|
-
z.enum([
|
|
19
|
-
'adrs',
|
|
20
|
-
'rules',
|
|
21
|
-
'active_tasks',
|
|
22
|
-
'recent_sessions',
|
|
23
|
-
'open_letters',
|
|
24
|
-
'planning',
|
|
25
|
-
'research',
|
|
26
|
-
]),
|
|
27
|
-
)
|
|
28
|
-
.describe('Categories of knowledge to include'),
|
|
29
|
-
depth: z
|
|
30
|
-
.enum(['light', 'standard', 'deep'])
|
|
31
|
-
.default('standard')
|
|
32
|
-
.describe('Detail level: light (summaries), standard, deep (full bodies)'),
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
type GetProjectMemoryArgs = {
|
|
36
|
-
project_id: string
|
|
37
|
-
include: string[]
|
|
38
|
-
depth?: string
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export async function getProjectMemory(args: GetProjectMemoryArgs) {
|
|
42
|
-
const result = await nexusPost('/api/mcp/memory', {
|
|
43
|
-
project_id: args.project_id,
|
|
44
|
-
include: args.include,
|
|
45
|
-
depth: args.depth ?? 'standard',
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
if (!result.ok) {
|
|
49
|
-
return {
|
|
50
|
-
content: [
|
|
51
|
-
{
|
|
52
|
-
type: 'text' as const,
|
|
53
|
-
text: JSON.stringify({ error: result.error }, null, 2),
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
isError: true,
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
content: [
|
|
62
|
-
{ type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
|
|
63
|
-
],
|
|
64
|
-
}
|
|
65
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* kb_related -- Layer 1 Knowledge Access
|
|
3
|
-
*
|
|
4
|
-
* Returns graph-neighbor entities related to a given entity.
|
|
5
|
-
* Delegates to POST /api/mcp/related.
|
|
6
|
-
*
|
|
7
|
-
* ADR-0001 spec: kb_related(entity_type, entity_id, relation_types[], limit)
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { z } from 'zod'
|
|
11
|
-
import { nexusPost } from '../nexus-api.js'
|
|
12
|
-
|
|
13
|
-
export const getRelatedEntitiesSchema = {
|
|
14
|
-
entity_type: z
|
|
15
|
-
.enum([
|
|
16
|
-
'session',
|
|
17
|
-
'decision',
|
|
18
|
-
'letter',
|
|
19
|
-
'task',
|
|
20
|
-
'research_note',
|
|
21
|
-
'planning_item',
|
|
22
|
-
'ingest_item',
|
|
23
|
-
])
|
|
24
|
-
.describe('Type of the source entity'),
|
|
25
|
-
entity_id: z.string().uuid().describe('UUID of the source entity'),
|
|
26
|
-
relation_types: z
|
|
27
|
-
.array(z.string().max(50))
|
|
28
|
-
.optional()
|
|
29
|
-
.describe(
|
|
30
|
-
'Filter by specific relation types (e.g., "references", "created_in", "supersedes")',
|
|
31
|
-
),
|
|
32
|
-
limit: z
|
|
33
|
-
.number()
|
|
34
|
-
.int()
|
|
35
|
-
.min(1)
|
|
36
|
-
.max(50)
|
|
37
|
-
.default(20)
|
|
38
|
-
.describe('Maximum related entities to return'),
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
type GetRelatedEntitiesArgs = {
|
|
42
|
-
entity_type: string
|
|
43
|
-
entity_id: string
|
|
44
|
-
relation_types?: string[]
|
|
45
|
-
limit?: number
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export async function getRelatedEntities(args: GetRelatedEntitiesArgs) {
|
|
49
|
-
const result = await nexusPost('/api/mcp/related', {
|
|
50
|
-
entity_type: args.entity_type,
|
|
51
|
-
entity_id: args.entity_id,
|
|
52
|
-
relation_types: args.relation_types,
|
|
53
|
-
limit: args.limit ?? 20,
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
if (!result.ok) {
|
|
57
|
-
return {
|
|
58
|
-
content: [
|
|
59
|
-
{
|
|
60
|
-
type: 'text' as const,
|
|
61
|
-
text: JSON.stringify({ error: result.error }, null, 2),
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
isError: true,
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
content: [
|
|
70
|
-
{ type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
|
|
71
|
-
],
|
|
72
|
-
}
|
|
73
|
-
}
|
package/src/tools/governance.ts
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ADR Governance tools -- Layer 3
|
|
3
|
-
*
|
|
4
|
-
* Manages the ADR lifecycle:
|
|
5
|
-
* draft -> under_review -> accepted | rejected -> superseded -> archived
|
|
6
|
-
*
|
|
7
|
-
* Delegates to POST /api/mcp/governance.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { z } from 'zod'
|
|
11
|
-
import { nexusPost } from '../nexus-api.js'
|
|
12
|
-
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
// create_adr_draft -> adr_create
|
|
15
|
-
// ---------------------------------------------------------------------------
|
|
16
|
-
|
|
17
|
-
export const createAdrDraftSchema = {
|
|
18
|
-
project_id: z.string().uuid().describe('Project UUID'),
|
|
19
|
-
title: z.string().max(500).describe('ADR title'),
|
|
20
|
-
context: z
|
|
21
|
-
.string()
|
|
22
|
-
.max(100_000)
|
|
23
|
-
.describe('Context / motivation for the decision (markdown)'),
|
|
24
|
-
decision: z.string().max(100_000).describe('The decision content (markdown)'),
|
|
25
|
-
consequences: z
|
|
26
|
-
.string()
|
|
27
|
-
.max(100_000)
|
|
28
|
-
.optional()
|
|
29
|
-
.describe('Expected consequences of the decision (markdown)'),
|
|
30
|
-
supersedes: z
|
|
31
|
-
.string()
|
|
32
|
-
.uuid()
|
|
33
|
-
.optional()
|
|
34
|
-
.describe('UUID of the ADR this one supersedes'),
|
|
35
|
-
agent_id: z.string().max(200).optional().describe('Agent identifier if applicable'),
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
type CreateAdrDraftArgs = {
|
|
39
|
-
project_id: string
|
|
40
|
-
title: string
|
|
41
|
-
context: string
|
|
42
|
-
decision: string
|
|
43
|
-
consequences?: string
|
|
44
|
-
supersedes?: string
|
|
45
|
-
user_id: string
|
|
46
|
-
agent_id?: string
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export async function createAdrDraft(args: CreateAdrDraftArgs) {
|
|
50
|
-
const result = await nexusPost('/api/mcp/governance', {
|
|
51
|
-
action: 'adr_create',
|
|
52
|
-
project_id: args.project_id,
|
|
53
|
-
title: args.title,
|
|
54
|
-
context: args.context,
|
|
55
|
-
decision: args.decision,
|
|
56
|
-
consequences: args.consequences,
|
|
57
|
-
supersedes: args.supersedes,
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
if (!result.ok) {
|
|
61
|
-
return {
|
|
62
|
-
content: [
|
|
63
|
-
{
|
|
64
|
-
type: 'text' as const,
|
|
65
|
-
text: JSON.stringify({ error: result.error }, null, 2),
|
|
66
|
-
},
|
|
67
|
-
],
|
|
68
|
-
isError: true,
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return {
|
|
73
|
-
content: [
|
|
74
|
-
{ type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
|
|
75
|
-
],
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// ---------------------------------------------------------------------------
|
|
80
|
-
// submit_adr_review -> adr_submit
|
|
81
|
-
// ---------------------------------------------------------------------------
|
|
82
|
-
|
|
83
|
-
export const submitAdrReviewSchema = {
|
|
84
|
-
adr_id: z.string().uuid().describe('ADR UUID to submit for review'),
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
type SubmitAdrReviewArgs = {
|
|
88
|
-
adr_id: string
|
|
89
|
-
user_id: string
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export async function submitAdrReview(args: SubmitAdrReviewArgs) {
|
|
93
|
-
const result = await nexusPost('/api/mcp/governance', {
|
|
94
|
-
action: 'adr_submit',
|
|
95
|
-
adr_id: args.adr_id,
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
if (!result.ok) {
|
|
99
|
-
return {
|
|
100
|
-
content: [
|
|
101
|
-
{
|
|
102
|
-
type: 'text' as const,
|
|
103
|
-
text: JSON.stringify({ error: result.error }, null, 2),
|
|
104
|
-
},
|
|
105
|
-
],
|
|
106
|
-
isError: true,
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
content: [
|
|
112
|
-
{ type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
|
|
113
|
-
],
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// ---------------------------------------------------------------------------
|
|
118
|
-
// record_adr_decision -> adr_decide
|
|
119
|
-
// ---------------------------------------------------------------------------
|
|
120
|
-
|
|
121
|
-
export const recordAdrDecisionSchema = {
|
|
122
|
-
adr_id: z.string().uuid().describe('ADR UUID'),
|
|
123
|
-
decision: z
|
|
124
|
-
.enum(['accepted', 'rejected'])
|
|
125
|
-
.describe('Decision outcome: accept or reject'),
|
|
126
|
-
rationale: z
|
|
127
|
-
.string()
|
|
128
|
-
.max(10_000)
|
|
129
|
-
.optional()
|
|
130
|
-
.describe('Optional rationale for the decision'),
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
type RecordAdrDecisionArgs = {
|
|
134
|
-
adr_id: string
|
|
135
|
-
decision: string
|
|
136
|
-
rationale?: string
|
|
137
|
-
user_id: string
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export async function recordAdrDecision(args: RecordAdrDecisionArgs) {
|
|
141
|
-
const result = await nexusPost('/api/mcp/governance', {
|
|
142
|
-
action: 'adr_decide',
|
|
143
|
-
adr_id: args.adr_id,
|
|
144
|
-
decision: args.decision,
|
|
145
|
-
rationale: args.rationale,
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
if (!result.ok) {
|
|
149
|
-
return {
|
|
150
|
-
content: [
|
|
151
|
-
{
|
|
152
|
-
type: 'text' as const,
|
|
153
|
-
text: JSON.stringify({ error: result.error }, null, 2),
|
|
154
|
-
},
|
|
155
|
-
],
|
|
156
|
-
isError: true,
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return {
|
|
161
|
-
content: [
|
|
162
|
-
{ type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
|
|
163
|
-
],
|
|
164
|
-
}
|
|
165
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* doc_ingest -- Layer 2 Coordination
|
|
3
|
-
*
|
|
4
|
-
* Allows agents to push text/markdown content into a project's
|
|
5
|
-
* knowledge base via the ingest_items table.
|
|
6
|
-
* Delegates to POST /api/mcp/documents (action: doc_ingest).
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { z } from 'zod'
|
|
10
|
-
import { nexusPost } from '../nexus-api.js'
|
|
11
|
-
|
|
12
|
-
export const ingestDocumentSchema = {
|
|
13
|
-
project_id: z.string().uuid().describe('Project UUID'),
|
|
14
|
-
title: z.string().max(500).describe('Document title'),
|
|
15
|
-
body: z.string().max(100_000).describe('Document content (text or markdown)'),
|
|
16
|
-
source: z
|
|
17
|
-
.string()
|
|
18
|
-
.max(200)
|
|
19
|
-
.optional()
|
|
20
|
-
.describe(
|
|
21
|
-
'Source identifier (e.g. "mcp-agent", "research", "session-extract")',
|
|
22
|
-
),
|
|
23
|
-
source_url: z.string().url().optional().describe('Source URL if applicable'),
|
|
24
|
-
agent_id: z.string().max(200).optional().describe('Agent identifier if applicable'),
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
type IngestDocumentArgs = {
|
|
28
|
-
project_id: string
|
|
29
|
-
title: string
|
|
30
|
-
body: string
|
|
31
|
-
source?: string
|
|
32
|
-
source_url?: string
|
|
33
|
-
user_id: string
|
|
34
|
-
agent_id?: string
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function ingestDocument(args: IngestDocumentArgs) {
|
|
38
|
-
const result = await nexusPost('/api/mcp/documents', {
|
|
39
|
-
action: 'doc_ingest',
|
|
40
|
-
project_id: args.project_id,
|
|
41
|
-
title: args.title,
|
|
42
|
-
body: args.body,
|
|
43
|
-
source: args.source,
|
|
44
|
-
source_url: args.source_url,
|
|
45
|
-
agent_id: args.agent_id,
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
if (!result.ok) {
|
|
49
|
-
return {
|
|
50
|
-
content: [
|
|
51
|
-
{
|
|
52
|
-
type: 'text' as const,
|
|
53
|
-
text: JSON.stringify({ error: result.error }, null, 2),
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
isError: true,
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
content: [
|
|
62
|
-
{ type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
|
|
63
|
-
],
|
|
64
|
-
}
|
|
65
|
-
}
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vl_inbox + vl_outbox + vl_ack -- Layer 2 Coordination
|
|
3
|
-
*
|
|
4
|
-
* Inbox/outbox polling and acknowledgment for vault letters.
|
|
5
|
-
* Delegates to POST /api/mcp/letters (actions: vl_inbox, vl_outbox, vl_ack).
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { z } from 'zod'
|
|
9
|
-
import { nexusPost } from '../nexus-api.js'
|
|
10
|
-
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
// list_inbox
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
|
|
15
|
-
export const listInboxSchema = {
|
|
16
|
-
project_id: z.string().uuid().describe('Project UUID'),
|
|
17
|
-
status_filter: z
|
|
18
|
-
.array(z.string().max(50))
|
|
19
|
-
.optional()
|
|
20
|
-
.describe(
|
|
21
|
-
'Filter by letter status (default: new, acknowledged, in_progress, blocked, needs_review)',
|
|
22
|
-
),
|
|
23
|
-
limit: z
|
|
24
|
-
.number()
|
|
25
|
-
.min(1)
|
|
26
|
-
.max(50)
|
|
27
|
-
.default(20)
|
|
28
|
-
.describe('Max number of letters to return'),
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
type ListInboxArgs = {
|
|
32
|
-
project_id: string
|
|
33
|
-
status_filter?: string[]
|
|
34
|
-
limit?: number
|
|
35
|
-
user_id: string
|
|
36
|
-
agent_id?: string
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export async function listInbox(args: ListInboxArgs) {
|
|
40
|
-
const result = await nexusPost('/api/mcp/letters', {
|
|
41
|
-
action: 'vl_inbox',
|
|
42
|
-
project_id: args.project_id,
|
|
43
|
-
status_filter: args.status_filter,
|
|
44
|
-
limit: args.limit ?? 20,
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
if (!result.ok) {
|
|
48
|
-
return {
|
|
49
|
-
content: [
|
|
50
|
-
{
|
|
51
|
-
type: 'text' as const,
|
|
52
|
-
text: JSON.stringify({ error: result.error }, null, 2),
|
|
53
|
-
},
|
|
54
|
-
],
|
|
55
|
-
isError: true,
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
content: [
|
|
61
|
-
{ type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
|
|
62
|
-
],
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// ---------------------------------------------------------------------------
|
|
67
|
-
// list_outbox
|
|
68
|
-
// ---------------------------------------------------------------------------
|
|
69
|
-
|
|
70
|
-
export const listOutboxSchema = {
|
|
71
|
-
project_id: z.string().uuid().describe('Project UUID'),
|
|
72
|
-
status_filter: z
|
|
73
|
-
.array(z.string().max(50))
|
|
74
|
-
.optional()
|
|
75
|
-
.describe('Filter by letter status (default: all non-closed)'),
|
|
76
|
-
limit: z
|
|
77
|
-
.number()
|
|
78
|
-
.min(1)
|
|
79
|
-
.max(50)
|
|
80
|
-
.default(20)
|
|
81
|
-
.describe('Max number of letters to return'),
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
type ListOutboxArgs = {
|
|
85
|
-
project_id: string
|
|
86
|
-
status_filter?: string[]
|
|
87
|
-
limit?: number
|
|
88
|
-
user_id: string
|
|
89
|
-
agent_id?: string
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export async function listOutbox(args: ListOutboxArgs) {
|
|
93
|
-
const result = await nexusPost('/api/mcp/letters', {
|
|
94
|
-
action: 'vl_outbox',
|
|
95
|
-
project_id: args.project_id,
|
|
96
|
-
status_filter: args.status_filter,
|
|
97
|
-
limit: args.limit ?? 20,
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
if (!result.ok) {
|
|
101
|
-
return {
|
|
102
|
-
content: [
|
|
103
|
-
{
|
|
104
|
-
type: 'text' as const,
|
|
105
|
-
text: JSON.stringify({ error: result.error }, null, 2),
|
|
106
|
-
},
|
|
107
|
-
],
|
|
108
|
-
isError: true,
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
content: [
|
|
114
|
-
{ type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
|
|
115
|
-
],
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// ---------------------------------------------------------------------------
|
|
120
|
-
// acknowledge_letter
|
|
121
|
-
// ---------------------------------------------------------------------------
|
|
122
|
-
|
|
123
|
-
export const acknowledgeLetterSchema = {
|
|
124
|
-
letter_id: z.string().uuid().describe('Letter UUID to acknowledge'),
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
type AcknowledgeLetterArgs = {
|
|
128
|
-
letter_id: string
|
|
129
|
-
user_id: string
|
|
130
|
-
agent_id?: string
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export async function acknowledgeLetter(args: AcknowledgeLetterArgs) {
|
|
134
|
-
const result = await nexusPost('/api/mcp/letters', {
|
|
135
|
-
action: 'vl_ack',
|
|
136
|
-
letter_id: args.letter_id,
|
|
137
|
-
agent_id: args.agent_id,
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
if (!result.ok) {
|
|
141
|
-
return {
|
|
142
|
-
content: [
|
|
143
|
-
{
|
|
144
|
-
type: 'text' as const,
|
|
145
|
-
text: JSON.stringify({ error: result.error }, null, 2),
|
|
146
|
-
},
|
|
147
|
-
],
|
|
148
|
-
isError: true,
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return {
|
|
153
|
-
content: [
|
|
154
|
-
{ type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
|
|
155
|
-
],
|
|
156
|
-
}
|
|
157
|
-
}
|