@dain-os/mcp-server 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -29
- 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 +318 -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 -347
- 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/library.d.ts +0 -3
- package/dist/tools/library.d.ts.map +0 -1
- package/dist/tools/library.js +0 -94
- package/dist/tools/library.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
|
@@ -1,32 +1,30 @@
|
|
|
1
1
|
# @dain-os/mcp-server
|
|
2
2
|
|
|
3
|
-
MCP server for DainOS. Lets Claude Code and other MCP clients manage
|
|
3
|
+
MCP server for DainOS. Lets Claude Code and other MCP clients manage projects, tasks, proposals (including content drafting), PR reviews, instructions library, and developer knowledge (changelog, sessions, KB).
|
|
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
8
|
|
|
9
|
-
|
|
10
|
-
|---|---|
|
|
11
|
-
| Projects | `list_projects`, `get_project`, `create_project`, `update_project`, `archive_project` |
|
|
12
|
-
| Tasks | `list_tasks`, `get_task`, `create_task`, `update_task`, `complete_task`, `archive_task` |
|
|
13
|
-
| Comments | `add_task_comment` |
|
|
14
|
-
| Developer KB (v0.2+) | `log_changelog_entry`, `log_session_context`, `log_knowledge_base_entry`, `list_recent_sessions`, `search_knowledge_base` |
|
|
15
|
-
| Proposals (v0.3+) | `list_proposals`, `get_proposal`, `create_proposal`, `update_proposal`, `set_proposal_status`, `delete_proposal` |
|
|
16
|
-
| Proposal options (v0.3+) | `list_proposal_options`, `create_proposal_option`, `update_proposal_option`, `set_recommended_option`, `delete_proposal_option` |
|
|
17
|
-
| Proposal content (v0.3+) | `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` |
|
|
18
|
-
|
|
19
|
-
Project / task / comment / proposal tools run as the user who minted the token, with tenant scoping enforced server-side. Developer KB tools are intentionally cross-tenant: they accept `project` as a required parameter and store entries in a shared developer schema (used by `/wrapup`, `/recap`, `/dev-kb`).
|
|
20
|
-
|
|
21
|
-
### Drafting proposal content
|
|
9
|
+
### Generic tools (v0.8+)
|
|
22
10
|
|
|
23
|
-
|
|
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. |
|
|
24
16
|
|
|
25
|
-
|
|
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.
|
|
26
18
|
|
|
27
|
-
|
|
19
|
+
### Semantic tools
|
|
28
20
|
|
|
29
|
-
|
|
21
|
+
| Domain | Tools |
|
|
22
|
+
|---|---|
|
|
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` |
|
|
30
28
|
|
|
31
29
|
## Setup
|
|
32
30
|
|
|
@@ -38,19 +36,45 @@ Tokens look like `dain_pat_<43 base64url chars>`.
|
|
|
38
36
|
|
|
39
37
|
### 2. Add the server to your MCP client
|
|
40
38
|
|
|
41
|
-
####
|
|
39
|
+
#### Option A: Cloud HTTP (recommended)
|
|
40
|
+
|
|
41
|
+
The MCP server is hosted at `mcp.dainos.app`. This is the recommended setup: it works with Claude Code subagents (which cannot access local stdio servers), requires no local install, and is always up to date.
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"mcpServers": {
|
|
46
|
+
"dainos": {
|
|
47
|
+
"type": "http",
|
|
48
|
+
"url": "https://mcp.dainos.app/mcp",
|
|
49
|
+
"headers": {
|
|
50
|
+
"Authorization": "Bearer ${DAINOS_API_TOKEN}"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Set the token in your environment:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
export DAINOS_API_TOKEN=dain_pat_<your token>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### Option B: Local stdio
|
|
64
|
+
|
|
65
|
+
For offline development or if you prefer a local process:
|
|
42
66
|
|
|
43
67
|
```bash
|
|
44
68
|
claude mcp add dainos -- npx -y @dain-os/mcp-server
|
|
45
69
|
```
|
|
46
70
|
|
|
47
|
-
Then set the token
|
|
71
|
+
Then set the token:
|
|
48
72
|
|
|
49
73
|
```bash
|
|
50
74
|
export DAINOS_API_TOKEN=dain_pat_<your token>
|
|
51
75
|
```
|
|
52
76
|
|
|
53
|
-
Or
|
|
77
|
+
Or add it to your Claude Code config directly:
|
|
54
78
|
|
|
55
79
|
```json
|
|
56
80
|
{
|
|
@@ -77,6 +101,38 @@ Claude Code picks up new MCP servers on restart.
|
|
|
77
101
|
| `DAINOS_API_TOKEN` | yes | n/a | Personal access token from `/settings/api-tokens` |
|
|
78
102
|
| `DAINOS_API_URL` | no | `https://api.dainos.app` | Override for local dev or staging |
|
|
79
103
|
|
|
104
|
+
## Using the generic tools
|
|
105
|
+
|
|
106
|
+
Start by calling `describe_schema` to discover available resources and their fields. Then use `query` and `mutate` for all standard reads and writes.
|
|
107
|
+
|
|
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
|
+
```
|
|
119
|
+
|
|
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
|
+
```
|
|
127
|
+
|
|
128
|
+
## Drafting proposal content
|
|
129
|
+
|
|
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`.
|
|
131
|
+
|
|
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`.
|
|
133
|
+
|
|
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`.
|
|
135
|
+
|
|
80
136
|
## Usage examples
|
|
81
137
|
|
|
82
138
|
Once connected, ask Claude Code things like:
|
|
@@ -85,8 +141,8 @@ Once connected, ask Claude Code things like:
|
|
|
85
141
|
- "What tasks are assigned to me?"
|
|
86
142
|
- "Create a task on the Portunus project called 'wire up the new sidebar' due Friday."
|
|
87
143
|
- "Mark that task complete and add a comment that the PR is #312."
|
|
88
|
-
|
|
89
|
-
|
|
144
|
+
- "List all active rules for the herbert project."
|
|
145
|
+
- "Fetch the core-rules instruction with template variables resolved for dain-os."
|
|
90
146
|
|
|
91
147
|
## Troubleshooting
|
|
92
148
|
|
|
@@ -104,7 +160,37 @@ The token is valid but your account does not have permission for the operation (
|
|
|
104
160
|
|
|
105
161
|
### Tool is not visible to Claude Code
|
|
106
162
|
|
|
107
|
-
Restart Claude Code after
|
|
163
|
+
Restart Claude Code after adding the server. MCP servers are loaded once at startup.
|
|
164
|
+
|
|
165
|
+
### MCP shows "still connecting" (HTTP mode)
|
|
166
|
+
|
|
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.
|
|
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`.
|
|
108
194
|
|
|
109
195
|
## Local development
|
|
110
196
|
|
|
@@ -132,10 +218,6 @@ Then point your MCP client at the local build:
|
|
|
132
218
|
}
|
|
133
219
|
```
|
|
134
220
|
|
|
135
|
-
## Why a small tool surface
|
|
136
|
-
|
|
137
|
-
The Notion MCP works well because it exposes a focused, opinionated set of operations rather than a one-to-one mirror of every API endpoint. The DainOS MCP server follows the same principle: project and task work covers the bulk of the day-to-day "keep things updated" use case, and the model picks the right verb every time. Tools for time entries, deals, proposals, and attachments are tracked for follow-up versions.
|
|
138
|
-
|
|
139
221
|
## Licence
|
|
140
222
|
|
|
141
223
|
Proprietary. Internal use by Dain only.
|
|
@@ -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,CAiUjD,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"}
|