@dain-os/mcp-server 0.7.0 → 0.8.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.
- package/README.md +66 -24
- package/dist/index.js +0 -0
- package/dist/tools/generic.d.ts +14 -0
- package/dist/tools/generic.d.ts.map +1 -0
- package/dist/tools/generic.js +238 -0
- package/dist/tools/generic.js.map +1 -0
- package/dist/tools/index.d.ts +8 -14
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +12 -36
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/registry.d.ts +55 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +340 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/semantic/cadence.d.ts +7 -0
- package/dist/tools/semantic/cadence.d.ts.map +1 -0
- package/dist/tools/semantic/cadence.js +120 -0
- package/dist/tools/semantic/cadence.js.map +1 -0
- package/dist/tools/semantic/developer.d.ts +7 -0
- package/dist/tools/semantic/developer.d.ts.map +1 -0
- package/dist/tools/semantic/developer.js +145 -0
- package/dist/tools/semantic/developer.js.map +1 -0
- package/dist/tools/semantic/index.d.ts +7 -0
- package/dist/tools/semantic/index.d.ts.map +1 -0
- package/dist/tools/semantic/index.js +17 -0
- package/dist/tools/semantic/index.js.map +1 -0
- package/dist/tools/semantic/proposal-content.d.ts +9 -0
- package/dist/tools/semantic/proposal-content.d.ts.map +1 -0
- package/dist/tools/semantic/proposal-content.js +118 -0
- package/dist/tools/semantic/proposal-content.js.map +1 -0
- package/dist/tools/semantic/proposals.d.ts +7 -0
- package/dist/tools/semantic/proposals.d.ts.map +1 -0
- package/dist/tools/semantic/proposals.js +107 -0
- package/dist/tools/semantic/proposals.js.map +1 -0
- package/dist/tools/semantic/tasks.d.ts +7 -0
- package/dist/tools/semantic/tasks.d.ts.map +1 -0
- package/dist/tools/semantic/tasks.js +123 -0
- package/dist/tools/semantic/tasks.js.map +1 -0
- package/package.json +1 -1
- package/dist/tools/cadence.d.ts +0 -4
- package/dist/tools/cadence.d.ts.map +0 -1
- package/dist/tools/cadence.js +0 -245
- package/dist/tools/cadence.js.map +0 -1
- package/dist/tools/comments.d.ts +0 -3
- package/dist/tools/comments.d.ts.map +0 -1
- package/dist/tools/comments.js +0 -19
- package/dist/tools/comments.js.map +0 -1
- package/dist/tools/developer.d.ts +0 -3
- package/dist/tools/developer.d.ts.map +0 -1
- package/dist/tools/developer.js +0 -349
- package/dist/tools/developer.js.map +0 -1
- package/dist/tools/iam.d.ts +0 -3
- package/dist/tools/iam.d.ts.map +0 -1
- package/dist/tools/iam.js +0 -38
- package/dist/tools/iam.js.map +0 -1
- package/dist/tools/log-time-entry.d.ts +0 -3
- package/dist/tools/log-time-entry.d.ts.map +0 -1
- package/dist/tools/log-time-entry.js +0 -54
- package/dist/tools/log-time-entry.js.map +0 -1
- package/dist/tools/pr-review.d.ts +0 -3
- package/dist/tools/pr-review.d.ts.map +0 -1
- package/dist/tools/pr-review.js +0 -83
- package/dist/tools/pr-review.js.map +0 -1
- package/dist/tools/products.d.ts +0 -3
- package/dist/tools/products.d.ts.map +0 -1
- package/dist/tools/products.js +0 -37
- package/dist/tools/products.js.map +0 -1
- package/dist/tools/projects.d.ts +0 -3
- package/dist/tools/projects.d.ts.map +0 -1
- package/dist/tools/projects.js +0 -151
- package/dist/tools/projects.js.map +0 -1
- package/dist/tools/proposal-content.d.ts +0 -3
- package/dist/tools/proposal-content.d.ts.map +0 -1
- package/dist/tools/proposal-content.js +0 -136
- package/dist/tools/proposal-content.js.map +0 -1
- package/dist/tools/proposal-options.d.ts +0 -3
- package/dist/tools/proposal-options.d.ts.map +0 -1
- package/dist/tools/proposal-options.js +0 -132
- package/dist/tools/proposal-options.js.map +0 -1
- package/dist/tools/proposals.d.ts +0 -22
- package/dist/tools/proposals.d.ts.map +0 -1
- package/dist/tools/proposals.js +0 -179
- package/dist/tools/proposals.js.map +0 -1
- package/dist/tools/tasks.d.ts +0 -3
- package/dist/tools/tasks.d.ts.map +0 -1
- package/dist/tools/tasks.js +0 -255
- package/dist/tools/tasks.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,23 +4,27 @@ MCP server for DainOS. Lets Claude Code and other MCP clients manage projects, t
|
|
|
4
4
|
|
|
5
5
|
## What it does
|
|
6
6
|
|
|
7
|
-
Wraps the DainOS Express API behind
|
|
7
|
+
Wraps the DainOS Express API behind 20 tools: 3 generic tools that cover all standard CRUD operations across every resource, plus 17 semantic tools for operations with real business logic.
|
|
8
|
+
|
|
9
|
+
### Generic tools (v0.8+)
|
|
10
|
+
|
|
11
|
+
| Tool | What it does |
|
|
12
|
+
|---|---|
|
|
13
|
+
| `describe_schema` | Returns the schema of all queryable resources. Call once per session to learn what data is available. |
|
|
14
|
+
| `query` | Read any resource: list with filters, get by ID, or free-text search. Replaces 30+ individual list/get tools. |
|
|
15
|
+
| `mutate` | Create, update, or delete any resource. Replaces 9+ individual create/update/delete tools. |
|
|
16
|
+
|
|
17
|
+
Resources available through `query` and `mutate`: projects, milestones, tasks, task comments, proposals, proposal options, proposal content, session context, developer changelog, developer knowledge base, IAM users, instructions, product repos, product task summaries, PR review findings.
|
|
18
|
+
|
|
19
|
+
### Semantic tools
|
|
8
20
|
|
|
9
21
|
| Domain | Tools |
|
|
10
22
|
|---|---|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
| IAM | `list_tenant_users`, `get_user` |
|
|
17
|
-
| Developer KB | `log_changelog_entry`, `update_changelog_entry`, `list_changelog`, `log_session_context`, `update_session_context`, `list_recent_sessions`, `log_knowledge_base_entry`, `update_knowledge_base_entry`, `search_knowledge_base` |
|
|
18
|
-
| Time tracking (v0.7+) | `log_time_entry` |
|
|
19
|
-
| Proposals | `list_proposals`, `get_proposal`, `create_proposal`, `update_proposal`, `set_proposal_status`, `delete_proposal` |
|
|
20
|
-
| Proposal options | `list_proposal_options`, `create_proposal_option`, `update_proposal_option`, `set_recommended_option`, `delete_proposal_option` |
|
|
21
|
-
| Proposal content | `get_proposal_content`, `describe_proposal_block_types`, `upsert_proposal_section`, `delete_proposal_section`, `upsert_proposal_block`, `delete_proposal_block`, `reorder_proposal_blocks`, `replace_proposal_content` |
|
|
22
|
-
| PR review | `list_unscored_pr_findings`, `score_pr_finding` |
|
|
23
|
-
| Instructions library (v0.6+) | `list_instructions`, `get_instruction`, `search_instructions` |
|
|
23
|
+
| Tasks | `create_task` (fuzzy milestone resolution), `complete_task` (status state machine), `regenerate_client_view` (Anthropic-powered) |
|
|
24
|
+
| Cadence | `claim_next_task`, `report_task_progress`, `mark_blocked`, `request_unblock` |
|
|
25
|
+
| Proposals | `set_proposal_status`, `create_proposal_option`, `update_proposal_option`, `set_recommended_option` |
|
|
26
|
+
| Proposal content | `proposal_content` (6 ops: upsert/delete sections and blocks, reorder, replace all), `describe_proposal_block_types` |
|
|
27
|
+
| Developer | `log_changelog_entry`, `log_knowledge_base_entry`, `log_time_entry`, `score_pr_finding` |
|
|
24
28
|
|
|
25
29
|
## Setup
|
|
26
30
|
|
|
@@ -97,25 +101,37 @@ Claude Code picks up new MCP servers on restart.
|
|
|
97
101
|
| `DAINOS_API_TOKEN` | yes | n/a | Personal access token from `/settings/api-tokens` |
|
|
98
102
|
| `DAINOS_API_URL` | no | `https://api.dainos.app` | Override for local dev or staging |
|
|
99
103
|
|
|
100
|
-
##
|
|
104
|
+
## Using the generic tools
|
|
101
105
|
|
|
102
|
-
|
|
106
|
+
Start by calling `describe_schema` to discover available resources and their fields. Then use `query` and `mutate` for all standard reads and writes.
|
|
103
107
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
```
|
|
109
|
+
query({ resource: "projects", filters: { status: "active" } })
|
|
110
|
+
query({ resource: "tasks", id: "<uuid>" })
|
|
111
|
+
query({ resource: "milestones", parentId: "<project-uuid>" })
|
|
112
|
+
query({ resource: "instructions", id: "rule-core-rules" })
|
|
113
|
+
query({ resource: "developer_knowledge_base", filters: { project: "dain-os" }, search: "auth" })
|
|
114
|
+
|
|
115
|
+
mutate({ resource: "projects", operation: "create", data: { name: "New Project" } })
|
|
116
|
+
mutate({ resource: "tasks", operation: "update", id: "<uuid>", data: { status: "in_progress" } })
|
|
117
|
+
mutate({ resource: "session_context", operation: "create", data: { project: "dain-os", ... } })
|
|
118
|
+
```
|
|
107
119
|
|
|
108
|
-
|
|
120
|
+
For operations with business logic, use the dedicated semantic tools:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
create_task({ title: "Wire up sidebar", projectId: "<uuid>", milestoneName: "Phase 1" })
|
|
124
|
+
complete_task({ id: "<uuid>" })
|
|
125
|
+
proposal_content({ proposalId: "<uuid>", op: "upsert_block", sectionKey: "exec", block: { ... } })
|
|
126
|
+
```
|
|
109
127
|
|
|
110
128
|
## Drafting proposal content
|
|
111
129
|
|
|
112
130
|
Proposal content lives in a structured JSON shape: `{ version: 2, sections: [{ id, key, title, blocks: ContentBlock[] }] }`. Eight block types are supported: `text`, `cards`, `diagram`, `chart`, `table`, `image`, `gantt`, `iframe`.
|
|
113
131
|
|
|
114
|
-
Start a drafting session by calling `describe_proposal_block_types`
|
|
132
|
+
Start a drafting session by calling `describe_proposal_block_types` for the full catalogue. Then use `proposal_content` with the appropriate `op` to add or change one block at a time. Available ops: `upsert_section`, `delete_section`, `upsert_block`, `delete_block`, `reorder_blocks`, `replace_all`.
|
|
115
133
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
`get_proposal` includes a computed `shareUrl` field, populated as `https://dainos.app/proposals/view/<token>` once the proposal has been transitioned to `sent` (or later: `viewed`, `accepted`). Draft proposals return `shareUrl: null`.
|
|
134
|
+
`query({ resource: "proposals", id: "<uuid>" })` includes a computed `shareUrl` field, populated as `https://dainos.app/proposals/view/<token>` once the proposal has been transitioned to `sent`. Draft proposals return `shareUrl: null`.
|
|
119
135
|
|
|
120
136
|
## Usage examples
|
|
121
137
|
|
|
@@ -150,6 +166,32 @@ Restart Claude Code after adding the server. MCP servers are loaded once at star
|
|
|
150
166
|
|
|
151
167
|
Verify the endpoint is reachable: `curl https://mcp.dainos.app/mcp` should return a 405 JSON error (GET is not allowed; MCP uses POST). If you get an HTML page or SSL error, check your DNS and network.
|
|
152
168
|
|
|
169
|
+
## Migration from v0.7
|
|
170
|
+
|
|
171
|
+
v0.8 replaces 56 individual tools with 20 (3 generic + 17 semantic). If you have scripts or prompts that reference old tool names:
|
|
172
|
+
|
|
173
|
+
| Old tool | New equivalent |
|
|
174
|
+
|---|---|
|
|
175
|
+
| `list_projects`, `get_project` | `query({ resource: "projects", ... })` |
|
|
176
|
+
| `create_project`, `update_project`, `archive_project` | `mutate({ resource: "projects", ... })` |
|
|
177
|
+
| `list_tasks`, `get_task`, `update_task`, `archive_task` | `query` / `mutate` with `resource: "tasks"` |
|
|
178
|
+
| `list_milestones`, `update_milestone` | `query` / `mutate` with `resource: "milestones"` |
|
|
179
|
+
| `add_task_comment` | `mutate({ resource: "task_comments", operation: "create", parentId: taskId, ... })` |
|
|
180
|
+
| `list_proposals`, `get_proposal`, `create_proposal`, `update_proposal`, `delete_proposal` | `query` / `mutate` with `resource: "proposals"` |
|
|
181
|
+
| `list_proposal_options`, `delete_proposal_option` | `query` / `mutate` with `resource: "proposal_options"` |
|
|
182
|
+
| `get_proposal_content` | `query({ resource: "proposal_content", parentId: proposalId })` |
|
|
183
|
+
| `upsert_proposal_section`, `delete_proposal_section`, `upsert_proposal_block`, `delete_proposal_block`, `reorder_proposal_blocks`, `replace_proposal_content` | `proposal_content({ op: "...", ... })` |
|
|
184
|
+
| `list_recent_sessions`, `log_session_context`, `update_session_context` | `query` / `mutate` with `resource: "session_context"` |
|
|
185
|
+
| `list_changelog`, `update_changelog_entry` | `query` / `mutate` with `resource: "developer_changelog"` |
|
|
186
|
+
| `search_knowledge_base`, `update_knowledge_base_entry` | `query` / `mutate` with `resource: "developer_knowledge_base"` |
|
|
187
|
+
| `list_tenant_users`, `get_user` | `query({ resource: "iam_users", ... })` |
|
|
188
|
+
| `list_instructions`, `get_instruction`, `search_instructions` | `query({ resource: "instructions", ... })` |
|
|
189
|
+
| `lookup_product_repos` | `query({ resource: "product_repos", filters: { owner, repo } })` |
|
|
190
|
+
| `summarise_product_tasks` | `query({ resource: "product_task_summary", parentId: productId })` |
|
|
191
|
+
| `list_unscored_pr_findings` | `query({ resource: "pr_review_findings", filters: { repo, prNumber, scoredBy } })` |
|
|
192
|
+
|
|
193
|
+
Semantic tools that kept their names unchanged: `create_task`, `complete_task`, `regenerate_client_view`, `claim_next_task`, `report_task_progress`, `mark_blocked`, `request_unblock`, `set_proposal_status`, `create_proposal_option`, `update_proposal_option`, `set_recommended_option`, `describe_proposal_block_types`, `log_changelog_entry`, `log_knowledge_base_entry`, `log_time_entry`, `score_pr_finding`.
|
|
194
|
+
|
|
153
195
|
## Local development
|
|
154
196
|
|
|
155
197
|
```bash
|
package/dist/index.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic MCP tools: describe_schema, query, mutate.
|
|
3
|
+
*
|
|
4
|
+
* These three tools replace ~36 thin CRUD tools by operating on any
|
|
5
|
+
* resource defined in the registry. The LLM calls describe_schema once
|
|
6
|
+
* to learn what's available, then uses query/mutate for all reads and
|
|
7
|
+
* simple writes.
|
|
8
|
+
*/
|
|
9
|
+
import type { ToolDefinition } from './types.js';
|
|
10
|
+
export declare const describeSchema: ToolDefinition;
|
|
11
|
+
export declare const query: ToolDefinition;
|
|
12
|
+
export declare const mutate: ToolDefinition;
|
|
13
|
+
export declare const genericTools: ToolDefinition[];
|
|
14
|
+
//# sourceMappingURL=generic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../src/tools/generic.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOjD,eAAO,MAAM,cAAc,EAAE,cA0B5B,CAAC;AAIF,eAAO,MAAM,KAAK,EAAE,cAwHnB,CAAC;AAIF,eAAO,MAAM,MAAM,EAAE,cAoEpB,CAAC;AAkDF,eAAO,MAAM,YAAY,EAAE,cAAc,EAIxC,CAAC"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic MCP tools: describe_schema, query, mutate.
|
|
3
|
+
*
|
|
4
|
+
* These three tools replace ~36 thin CRUD tools by operating on any
|
|
5
|
+
* resource defined in the registry. The LLM calls describe_schema once
|
|
6
|
+
* to learn what's available, then uses query/mutate for all reads and
|
|
7
|
+
* simple writes.
|
|
8
|
+
*/
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import { RESOURCES, serializeRegistry } from './registry.js';
|
|
11
|
+
// ─── describe_schema ────────────────────────────────────────────────
|
|
12
|
+
export const describeSchema = {
|
|
13
|
+
name: 'describe_schema',
|
|
14
|
+
description: 'Returns the schema of all queryable resources in DainOS. ' +
|
|
15
|
+
'Call this once at the start of a session to understand what data is available. ' +
|
|
16
|
+
'Each resource lists its fields, types, filter options, supported operations, ' +
|
|
17
|
+
'and whether it supports text search or batch create.',
|
|
18
|
+
inputSchema: z.object({
|
|
19
|
+
resource: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe('Return schema for a single resource. Omit to get all resources.'),
|
|
23
|
+
}),
|
|
24
|
+
handler: async (_client, input) => {
|
|
25
|
+
if (input.resource) {
|
|
26
|
+
const def = RESOURCES[input.resource];
|
|
27
|
+
if (!def) {
|
|
28
|
+
throw new Error(`Unknown resource "${input.resource}". Available: ${Object.keys(RESOURCES).join(', ')}`);
|
|
29
|
+
}
|
|
30
|
+
const { afterFetch: _af, ...serializable } = def;
|
|
31
|
+
return { [input.resource]: serializable };
|
|
32
|
+
}
|
|
33
|
+
return serializeRegistry();
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
// ─── query ──────────────────────────────────────────────────────────
|
|
37
|
+
export const query = {
|
|
38
|
+
name: 'query',
|
|
39
|
+
description: 'Read data from any DainOS resource. ' +
|
|
40
|
+
'Use describe_schema first to discover available resources and their fields. ' +
|
|
41
|
+
'Pass `id` to fetch a single record, or `filters` to list/search. ' +
|
|
42
|
+
'For nested resources (e.g. milestones under projects), pass `parentId`. ' +
|
|
43
|
+
'Pass `search` for free-text search (only on resources with searchable: true).',
|
|
44
|
+
inputSchema: z.object({
|
|
45
|
+
resource: z
|
|
46
|
+
.string()
|
|
47
|
+
.describe('Resource name from describe_schema, e.g. "tasks", "projects"'),
|
|
48
|
+
id: z
|
|
49
|
+
.string()
|
|
50
|
+
.optional()
|
|
51
|
+
.describe('Fetch a single record by ID or slug. Omit to list/search.'),
|
|
52
|
+
parentId: z
|
|
53
|
+
.string()
|
|
54
|
+
.uuid()
|
|
55
|
+
.optional()
|
|
56
|
+
.describe('Parent resource ID for nested resources (e.g. projectId for milestones)'),
|
|
57
|
+
filters: z
|
|
58
|
+
.record(z.union([z.string(), z.number(), z.boolean()]))
|
|
59
|
+
.optional()
|
|
60
|
+
.describe('Key-value filters. Keys must be filterable fields from describe_schema.'),
|
|
61
|
+
search: z
|
|
62
|
+
.string()
|
|
63
|
+
.optional()
|
|
64
|
+
.describe('Free-text search. Only works on resources with searchable: true.'),
|
|
65
|
+
sort: z
|
|
66
|
+
.object({
|
|
67
|
+
field: z.string(),
|
|
68
|
+
direction: z.enum(['asc', 'desc']).default('desc'),
|
|
69
|
+
})
|
|
70
|
+
.optional()
|
|
71
|
+
.describe('Sort override. Defaults to the resource default sort.'),
|
|
72
|
+
limit: z.coerce
|
|
73
|
+
.number()
|
|
74
|
+
.int()
|
|
75
|
+
.min(1)
|
|
76
|
+
.max(200)
|
|
77
|
+
.optional()
|
|
78
|
+
.describe('Max records to return (default varies by resource, max 200)'),
|
|
79
|
+
offset: z.coerce
|
|
80
|
+
.number()
|
|
81
|
+
.int()
|
|
82
|
+
.min(0)
|
|
83
|
+
.optional()
|
|
84
|
+
.describe('Pagination offset'),
|
|
85
|
+
}),
|
|
86
|
+
handler: async (client, input) => {
|
|
87
|
+
const def = lookupResource(input.resource);
|
|
88
|
+
if (input.search && !def.searchable) {
|
|
89
|
+
const filterable = listFilterableFields(def);
|
|
90
|
+
throw new Error(`Resource "${input.resource}" does not support text search. ` +
|
|
91
|
+
`Use filters instead. Filterable fields: ${filterable.join(', ')}`);
|
|
92
|
+
}
|
|
93
|
+
const basePath = resolveBasePath(def, input.parentId);
|
|
94
|
+
// ── Singleton GET (e.g. proposal_content, product_task_summary) ──
|
|
95
|
+
if (def.singleton) {
|
|
96
|
+
if (!input.parentId) {
|
|
97
|
+
throw new Error(`Resource "${input.resource}" is a singleton nested resource. ` +
|
|
98
|
+
`Provide parentId (the ${def.parentIdParam}).`);
|
|
99
|
+
}
|
|
100
|
+
const raw = await client.get(basePath);
|
|
101
|
+
return def.afterFetch ? def.afterFetch(raw, {}) : raw;
|
|
102
|
+
}
|
|
103
|
+
// ── Single record by ID ──
|
|
104
|
+
if (input.id) {
|
|
105
|
+
const raw = await client.get(`${basePath}/${input.id}`);
|
|
106
|
+
return def.afterFetch ? def.afterFetch(raw, { id: input.id }) : raw;
|
|
107
|
+
}
|
|
108
|
+
// ── List with filters ──
|
|
109
|
+
const searchBase = def.searchable && input.search && def.searchPath
|
|
110
|
+
? def.searchPath
|
|
111
|
+
: basePath;
|
|
112
|
+
const params = new URLSearchParams();
|
|
113
|
+
if (input.filters) {
|
|
114
|
+
for (const [key, value] of Object.entries(input.filters)) {
|
|
115
|
+
const field = def.fields[key];
|
|
116
|
+
if (!field?.filterable) {
|
|
117
|
+
const filterable = listFilterableFields(def);
|
|
118
|
+
throw new Error(`Field "${key}" is not filterable on "${input.resource}". ` +
|
|
119
|
+
`Filterable fields: ${filterable.join(', ')}`);
|
|
120
|
+
}
|
|
121
|
+
params.set(key, String(value));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (input.search)
|
|
125
|
+
params.set(def.searchPath ? 'q' : 'search', input.search);
|
|
126
|
+
if (input.sort) {
|
|
127
|
+
params.set('sortBy', input.sort.field);
|
|
128
|
+
params.set('sortDir', input.sort.direction);
|
|
129
|
+
}
|
|
130
|
+
const limit = Math.min(input.limit ?? def.defaultLimit ?? 25, def.maxLimit ?? 200);
|
|
131
|
+
params.set('limit', String(limit));
|
|
132
|
+
if (input.offset)
|
|
133
|
+
params.set('offset', String(input.offset));
|
|
134
|
+
const qs = params.toString() ? `?${params.toString()}` : '';
|
|
135
|
+
const raw = await client.get(`${searchBase}${qs}`);
|
|
136
|
+
return def.afterFetch ? def.afterFetch(raw, {}) : raw;
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
// ─── mutate ─────────────────────────────────────────────────────────
|
|
140
|
+
export const mutate = {
|
|
141
|
+
name: 'mutate',
|
|
142
|
+
description: 'Create, update, or delete a record in any DainOS resource. ' +
|
|
143
|
+
'Use describe_schema first to discover writable fields and required fields. ' +
|
|
144
|
+
'For operations with business logic (complete_task, set_proposal_status, ' +
|
|
145
|
+
'create_proposal_option, proposal_content, etc.), use the dedicated named tool.',
|
|
146
|
+
inputSchema: z.object({
|
|
147
|
+
resource: z
|
|
148
|
+
.string()
|
|
149
|
+
.describe('Resource name from describe_schema'),
|
|
150
|
+
operation: z
|
|
151
|
+
.enum(['create', 'update', 'delete'])
|
|
152
|
+
.describe('The mutation type'),
|
|
153
|
+
id: z
|
|
154
|
+
.string()
|
|
155
|
+
.uuid()
|
|
156
|
+
.optional()
|
|
157
|
+
.describe('Record ID. Required for update and delete.'),
|
|
158
|
+
parentId: z
|
|
159
|
+
.string()
|
|
160
|
+
.uuid()
|
|
161
|
+
.optional()
|
|
162
|
+
.describe('Parent ID for nested resources'),
|
|
163
|
+
data: z
|
|
164
|
+
.record(z.unknown())
|
|
165
|
+
.optional()
|
|
166
|
+
.describe('Fields to set. Required for create/update. Ignored for delete.'),
|
|
167
|
+
}),
|
|
168
|
+
handler: async (client, input) => {
|
|
169
|
+
const def = lookupResource(input.resource);
|
|
170
|
+
if (def.operations && !def.operations.includes(input.operation)) {
|
|
171
|
+
throw new Error(`Operation "${input.operation}" is not supported on "${input.resource}". ` +
|
|
172
|
+
`Allowed: ${def.operations.join(', ')}`);
|
|
173
|
+
}
|
|
174
|
+
const basePath = resolveBasePath(def, input.parentId);
|
|
175
|
+
switch (input.operation) {
|
|
176
|
+
case 'create': {
|
|
177
|
+
if (!input.data)
|
|
178
|
+
throw new Error('data is required for create operations');
|
|
179
|
+
validateWritable(def, input.data, input.resource);
|
|
180
|
+
return client.post(basePath, input.data);
|
|
181
|
+
}
|
|
182
|
+
case 'update': {
|
|
183
|
+
if (!input.id)
|
|
184
|
+
throw new Error('id is required for update');
|
|
185
|
+
if (input.data)
|
|
186
|
+
validateWritable(def, input.data, input.resource);
|
|
187
|
+
const body = Object.fromEntries(Object.entries(input.data ?? {}).filter(([, v]) => v !== undefined));
|
|
188
|
+
const method = def.updateMethod ?? 'PUT';
|
|
189
|
+
return method === 'PATCH'
|
|
190
|
+
? client.patch(`${basePath}/${input.id}`, body)
|
|
191
|
+
: client.put(`${basePath}/${input.id}`, body);
|
|
192
|
+
}
|
|
193
|
+
case 'delete': {
|
|
194
|
+
if (!input.id)
|
|
195
|
+
throw new Error('id is required for delete');
|
|
196
|
+
return client.delete(`${basePath}/${input.id}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
// ─── Helpers ────────────────────────────────────────────────────────
|
|
202
|
+
function lookupResource(name) {
|
|
203
|
+
const def = RESOURCES[name];
|
|
204
|
+
if (!def) {
|
|
205
|
+
throw new Error(`Unknown resource "${name}". Available: ${Object.keys(RESOURCES).join(', ')}`);
|
|
206
|
+
}
|
|
207
|
+
return def;
|
|
208
|
+
}
|
|
209
|
+
function resolveBasePath(def, parentId) {
|
|
210
|
+
if (def.nestedBasePath && parentId) {
|
|
211
|
+
return def.nestedBasePath.replace('${parentId}', parentId);
|
|
212
|
+
}
|
|
213
|
+
if (def.parentIdParam && !parentId) {
|
|
214
|
+
throw new Error(`Resource requires parentId (${def.parentIdParam}). ` +
|
|
215
|
+
`Pass it to access this nested resource.`);
|
|
216
|
+
}
|
|
217
|
+
return def.basePath;
|
|
218
|
+
}
|
|
219
|
+
function listFilterableFields(def) {
|
|
220
|
+
return Object.entries(def.fields)
|
|
221
|
+
.filter(([, f]) => f.filterable)
|
|
222
|
+
.map(([k]) => k);
|
|
223
|
+
}
|
|
224
|
+
function validateWritable(def, data, resourceName) {
|
|
225
|
+
for (const key of Object.keys(data)) {
|
|
226
|
+
const field = def.fields[key];
|
|
227
|
+
if (field && field.writable === false) {
|
|
228
|
+
throw new Error(`Field "${key}" is read-only on resource "${resourceName}". Remove it from data.`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// ─── Export ─────────────────────────────────────────────────────────
|
|
233
|
+
export const genericTools = [
|
|
234
|
+
describeSchema,
|
|
235
|
+
query,
|
|
236
|
+
mutate,
|
|
237
|
+
];
|
|
238
|
+
//# sourceMappingURL=generic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/tools/generic.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import type { ToolDefinition } from './types.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { commentTools } from './comments.js';
|
|
5
|
-
import { developerTools } from './developer.js';
|
|
6
|
-
import { proposalTools } from './proposals.js';
|
|
7
|
-
import { proposalOptionTools } from './proposal-options.js';
|
|
8
|
-
import { proposalContentTools } from './proposal-content.js';
|
|
9
|
-
import { prReviewTools } from './pr-review.js';
|
|
10
|
-
import { iamTools } from './iam.js';
|
|
11
|
-
import { productTools } from './products.js';
|
|
12
|
-
import { cadenceTools } from './cadence.js';
|
|
13
|
-
import { libraryTools } from './library.js';
|
|
14
|
-
export { projectTools, taskTools, commentTools, developerTools, proposalTools, proposalOptionTools, proposalContentTools, prReviewTools, iamTools, productTools, cadenceTools, libraryTools, };
|
|
2
|
+
export { genericTools } from './generic.js';
|
|
3
|
+
export { semanticTools } from './semantic/index.js';
|
|
15
4
|
export type { ToolDefinition };
|
|
16
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* All tools exposed by the DainOS MCP server.
|
|
7
|
+
*
|
|
8
|
+
* 3 generic tools (describe_schema, query, mutate) replace ~36 thin CRUD tools.
|
|
9
|
+
* ~17 semantic tools carry real business logic and keep their named interfaces.
|
|
10
|
+
*/
|
|
17
11
|
export declare const allTools: ToolDefinition[];
|
|
18
12
|
/** Look up a tool by its exposed name. */
|
|
19
13
|
export declare function getTool(name: string): ToolDefinition | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,EAAE,cAAc,EAGpC,CAAC;AAEF,0CAA0C;AAC1C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEhE"}
|
package/dist/tools/index.js
CHANGED
|
@@ -1,40 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// @anchor:cadence:mcp-import
|
|
12
|
-
// Sprint + Cadence (R4): claim_next_task, report_task_progress, mark_blocked, request_unblock
|
|
13
|
-
import { cadenceTools } from './cadence.js';
|
|
14
|
-
// @anchor:cadence:mcp-import-end
|
|
15
|
-
// @anchor:cloud-mcp:library-import
|
|
16
|
-
// CLOUD MCP (PRD-086): list_instructions, get_instruction, search_instructions
|
|
17
|
-
import { libraryTools } from './library.js';
|
|
18
|
-
// @anchor:cloud-mcp:library-import-end
|
|
19
|
-
export { projectTools, taskTools, commentTools, developerTools, proposalTools, proposalOptionTools, proposalContentTools, prReviewTools, iamTools, productTools, cadenceTools, libraryTools, };
|
|
20
|
-
/** All tools exposed by the DainOS MCP server. */
|
|
1
|
+
import { genericTools } from './generic.js';
|
|
2
|
+
import { semanticTools } from './semantic/index.js';
|
|
3
|
+
export { genericTools } from './generic.js';
|
|
4
|
+
export { semanticTools } from './semantic/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* All tools exposed by the DainOS MCP server.
|
|
7
|
+
*
|
|
8
|
+
* 3 generic tools (describe_schema, query, mutate) replace ~36 thin CRUD tools.
|
|
9
|
+
* ~17 semantic tools carry real business logic and keep their named interfaces.
|
|
10
|
+
*/
|
|
21
11
|
export const allTools = [
|
|
22
|
-
...
|
|
23
|
-
...
|
|
24
|
-
...commentTools,
|
|
25
|
-
...developerTools,
|
|
26
|
-
...proposalTools,
|
|
27
|
-
...proposalOptionTools,
|
|
28
|
-
...proposalContentTools,
|
|
29
|
-
...prReviewTools,
|
|
30
|
-
...iamTools,
|
|
31
|
-
...productTools,
|
|
32
|
-
// @anchor:cadence:mcp-registry
|
|
33
|
-
...cadenceTools,
|
|
34
|
-
// @anchor:cadence:mcp-registry-end
|
|
35
|
-
// @anchor:cloud-mcp:library-registry
|
|
36
|
-
...libraryTools,
|
|
37
|
-
// @anchor:cloud-mcp:library-registry-end
|
|
12
|
+
...genericTools,
|
|
13
|
+
...semanticTools,
|
|
38
14
|
];
|
|
39
15
|
/** Look up a tool by its exposed name. */
|
|
40
16
|
export function getTool(name) {
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAqB;IACxC,GAAG,YAAY;IACf,GAAG,aAAa;CACjB,CAAC;AAEF,0CAA0C;AAC1C,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource registry — single source of truth for every API resource
|
|
3
|
+
* the generic query/mutate tools can operate on.
|
|
4
|
+
*
|
|
5
|
+
* Adding a new resource to the MCP = adding an entry here.
|
|
6
|
+
* No new tool handler needed.
|
|
7
|
+
*/
|
|
8
|
+
type FieldType = 'string' | 'uuid' | 'number' | 'boolean' | 'date' | 'json' | 'enum';
|
|
9
|
+
export interface FieldDef {
|
|
10
|
+
type: FieldType;
|
|
11
|
+
description: string;
|
|
12
|
+
enumValues?: string[];
|
|
13
|
+
filterable?: boolean;
|
|
14
|
+
writable?: boolean;
|
|
15
|
+
required?: boolean;
|
|
16
|
+
nullable?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface ResourceDef {
|
|
19
|
+
/** Base REST path, e.g. '/projects', '/crm/proposals' */
|
|
20
|
+
basePath: string;
|
|
21
|
+
description: string;
|
|
22
|
+
fields: Record<string, FieldDef>;
|
|
23
|
+
/** Supported operations. Omit = all standard CRUD */
|
|
24
|
+
operations?: Array<'list' | 'get' | 'create' | 'update' | 'delete'>;
|
|
25
|
+
/** For nested resources: which filter param is the parent ID */
|
|
26
|
+
parentIdParam?: string;
|
|
27
|
+
/** For nested resources: path template, e.g. '/projects/${parentId}/milestones' */
|
|
28
|
+
nestedBasePath?: string;
|
|
29
|
+
/** GET with parentId returns a single object (no :id needed) */
|
|
30
|
+
singleton?: boolean;
|
|
31
|
+
/** Whether free-text search via `search` param is supported */
|
|
32
|
+
searchable?: boolean;
|
|
33
|
+
/** Override search endpoint when it differs from basePath */
|
|
34
|
+
searchPath?: string;
|
|
35
|
+
/** HTTP method for update (default: PUT) */
|
|
36
|
+
updateMethod?: 'PUT' | 'PATCH';
|
|
37
|
+
defaultSort?: {
|
|
38
|
+
field: string;
|
|
39
|
+
direction: 'asc' | 'desc';
|
|
40
|
+
};
|
|
41
|
+
defaultLimit?: number;
|
|
42
|
+
maxLimit?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Stateless post-fetch transform. Runs after every GET response.
|
|
45
|
+
* If this needs extra API calls, extract a semantic tool instead.
|
|
46
|
+
*/
|
|
47
|
+
afterFetch?: (data: unknown, input: {
|
|
48
|
+
id?: string;
|
|
49
|
+
}) => unknown;
|
|
50
|
+
}
|
|
51
|
+
export declare const RESOURCES: Record<string, ResourceDef>;
|
|
52
|
+
/** Serialize registry for describe_schema output, stripping non-serializable hooks. */
|
|
53
|
+
export declare function serializeRegistry(resources?: Record<string, ResourceDef>): Record<string, unknown>;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,KAAK,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAErF,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjC,qDAAqD;IACrD,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAC;IACpE,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IAC/B,WAAW,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAC;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC;CACjE;AAKD,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAwVjD,CAAC;AAEF,uFAAuF;AACvF,wBAAgB,iBAAiB,CAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GACtC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB"}
|