@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.
Files changed (87) hide show
  1. package/README.md +66 -24
  2. package/dist/index.js +0 -0
  3. package/dist/tools/generic.d.ts +14 -0
  4. package/dist/tools/generic.d.ts.map +1 -0
  5. package/dist/tools/generic.js +238 -0
  6. package/dist/tools/generic.js.map +1 -0
  7. package/dist/tools/index.d.ts +8 -14
  8. package/dist/tools/index.d.ts.map +1 -1
  9. package/dist/tools/index.js +12 -36
  10. package/dist/tools/index.js.map +1 -1
  11. package/dist/tools/registry.d.ts +55 -0
  12. package/dist/tools/registry.d.ts.map +1 -0
  13. package/dist/tools/registry.js +340 -0
  14. package/dist/tools/registry.js.map +1 -0
  15. package/dist/tools/semantic/cadence.d.ts +7 -0
  16. package/dist/tools/semantic/cadence.d.ts.map +1 -0
  17. package/dist/tools/semantic/cadence.js +120 -0
  18. package/dist/tools/semantic/cadence.js.map +1 -0
  19. package/dist/tools/semantic/developer.d.ts +7 -0
  20. package/dist/tools/semantic/developer.d.ts.map +1 -0
  21. package/dist/tools/semantic/developer.js +145 -0
  22. package/dist/tools/semantic/developer.js.map +1 -0
  23. package/dist/tools/semantic/index.d.ts +7 -0
  24. package/dist/tools/semantic/index.d.ts.map +1 -0
  25. package/dist/tools/semantic/index.js +17 -0
  26. package/dist/tools/semantic/index.js.map +1 -0
  27. package/dist/tools/semantic/proposal-content.d.ts +9 -0
  28. package/dist/tools/semantic/proposal-content.d.ts.map +1 -0
  29. package/dist/tools/semantic/proposal-content.js +118 -0
  30. package/dist/tools/semantic/proposal-content.js.map +1 -0
  31. package/dist/tools/semantic/proposals.d.ts +7 -0
  32. package/dist/tools/semantic/proposals.d.ts.map +1 -0
  33. package/dist/tools/semantic/proposals.js +107 -0
  34. package/dist/tools/semantic/proposals.js.map +1 -0
  35. package/dist/tools/semantic/tasks.d.ts +7 -0
  36. package/dist/tools/semantic/tasks.d.ts.map +1 -0
  37. package/dist/tools/semantic/tasks.js +123 -0
  38. package/dist/tools/semantic/tasks.js.map +1 -0
  39. package/package.json +1 -1
  40. package/dist/tools/cadence.d.ts +0 -4
  41. package/dist/tools/cadence.d.ts.map +0 -1
  42. package/dist/tools/cadence.js +0 -245
  43. package/dist/tools/cadence.js.map +0 -1
  44. package/dist/tools/comments.d.ts +0 -3
  45. package/dist/tools/comments.d.ts.map +0 -1
  46. package/dist/tools/comments.js +0 -19
  47. package/dist/tools/comments.js.map +0 -1
  48. package/dist/tools/developer.d.ts +0 -3
  49. package/dist/tools/developer.d.ts.map +0 -1
  50. package/dist/tools/developer.js +0 -349
  51. package/dist/tools/developer.js.map +0 -1
  52. package/dist/tools/iam.d.ts +0 -3
  53. package/dist/tools/iam.d.ts.map +0 -1
  54. package/dist/tools/iam.js +0 -38
  55. package/dist/tools/iam.js.map +0 -1
  56. package/dist/tools/log-time-entry.d.ts +0 -3
  57. package/dist/tools/log-time-entry.d.ts.map +0 -1
  58. package/dist/tools/log-time-entry.js +0 -54
  59. package/dist/tools/log-time-entry.js.map +0 -1
  60. package/dist/tools/pr-review.d.ts +0 -3
  61. package/dist/tools/pr-review.d.ts.map +0 -1
  62. package/dist/tools/pr-review.js +0 -83
  63. package/dist/tools/pr-review.js.map +0 -1
  64. package/dist/tools/products.d.ts +0 -3
  65. package/dist/tools/products.d.ts.map +0 -1
  66. package/dist/tools/products.js +0 -37
  67. package/dist/tools/products.js.map +0 -1
  68. package/dist/tools/projects.d.ts +0 -3
  69. package/dist/tools/projects.d.ts.map +0 -1
  70. package/dist/tools/projects.js +0 -151
  71. package/dist/tools/projects.js.map +0 -1
  72. package/dist/tools/proposal-content.d.ts +0 -3
  73. package/dist/tools/proposal-content.d.ts.map +0 -1
  74. package/dist/tools/proposal-content.js +0 -136
  75. package/dist/tools/proposal-content.js.map +0 -1
  76. package/dist/tools/proposal-options.d.ts +0 -3
  77. package/dist/tools/proposal-options.d.ts.map +0 -1
  78. package/dist/tools/proposal-options.js +0 -132
  79. package/dist/tools/proposal-options.js.map +0 -1
  80. package/dist/tools/proposals.d.ts +0 -22
  81. package/dist/tools/proposals.d.ts.map +0 -1
  82. package/dist/tools/proposals.js +0 -179
  83. package/dist/tools/proposals.js.map +0 -1
  84. package/dist/tools/tasks.d.ts +0 -3
  85. package/dist/tools/tasks.d.ts.map +0 -1
  86. package/dist/tools/tasks.js +0 -255
  87. 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 57 tools:
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
- | Projects | `list_projects`, `get_project`, `create_project`, `update_project`, `archive_project` |
12
- | Milestones | `list_milestones`, `update_milestone` |
13
- | Tasks | `list_tasks`, `get_task`, `create_task`, `update_task`, `complete_task`, `archive_task`, `claim_next_task`, `report_task_progress`, `mark_blocked`, `request_unblock`, `regenerate_client_view` |
14
- | Comments | `add_task_comment` |
15
- | Products | `lookup_product_repos`, `summarise_product_tasks` |
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
- ## Instructions library (v0.6+)
104
+ ## Using the generic tools
101
105
 
102
- Three tools for on-demand access to the DainOS instructions library (skills, rules, agents, commands):
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
- - `list_instructions` — discover available instructions by category and project
105
- - `get_instruction` fetch a specific instruction by slug with resolved template variables
106
- - `search_instructions` keyword search across the library
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
- When called with a `project` parameter (e.g. `herbert`, `dain-os`), template variables like `{{orm}}` and `{{testing_framework}}` are resolved server-side using per-project config.
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` it returns the full catalogue (schema, minimal example, when-to-use hints, gotchas like the iframe host allowlist). Then use the granular content tools to add or change one block at a time.
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
- For wholesale rewrites or regeneration, use `replace_proposal_content`.
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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"}
@@ -1,19 +1,13 @@
1
1
  import type { ToolDefinition } from './types.js';
2
- import { projectTools } from './projects.js';
3
- import { taskTools } from './tasks.js';
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
- /** All tools exposed by the DainOS MCP server. */
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;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAI5C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,OAAO,EACL,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,YAAY,GACb,CAAC;AACF,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B,kDAAkD;AAClD,eAAO,MAAM,QAAQ,EAAE,cAAc,EAiBpC,CAAC;AAEF,0CAA0C;AAC1C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEhE"}
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"}
@@ -1,40 +1,16 @@
1
- import { projectTools } from './projects.js';
2
- import { taskTools } from './tasks.js';
3
- import { commentTools } from './comments.js';
4
- import { developerTools } from './developer.js';
5
- import { proposalTools } from './proposals.js';
6
- import { proposalOptionTools } from './proposal-options.js';
7
- import { proposalContentTools } from './proposal-content.js';
8
- import { prReviewTools } from './pr-review.js';
9
- import { iamTools } from './iam.js';
10
- import { productTools } from './products.js';
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
- ...projectTools,
23
- ...taskTools,
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) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,6BAA6B;AAC7B,8FAA8F;AAC9F,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,iCAAiC;AACjC,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,uCAAuC;AAEvC,OAAO,EACL,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,YAAY,GACb,CAAC;AAGF,kDAAkD;AAClD,MAAM,CAAC,MAAM,QAAQ,GAAqB;IACxC,GAAG,YAAY;IACf,GAAG,SAAS;IACZ,GAAG,YAAY;IACf,GAAG,cAAc;IACjB,GAAG,aAAa;IAChB,GAAG,mBAAmB;IACtB,GAAG,oBAAoB;IACvB,GAAG,aAAa;IAChB,GAAG,QAAQ;IACX,GAAG,YAAY;IACf,+BAA+B;IAC/B,GAAG,YAAY;IACf,mCAAmC;IACnC,qCAAqC;IACrC,GAAG,YAAY;IACf,yCAAyC;CAC1C,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"}
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"}