@dain-os/mcp-server 0.5.0 → 0.6.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/dist/http.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * DainOS MCP server — HTTP entry point for Vercel deployment.
3
+ *
4
+ * Direct JSON-RPC handler that bypasses the MCP SDK's transport layer.
5
+ * The SDK transports (StreamableHTTP, WebStandard) use SSE streaming which
6
+ * hangs on Vercel serverless. Since our server is stateless (no sessions,
7
+ * no resumability), plain JSON request-response is correct and sufficient.
8
+ *
9
+ * Implements the MCP Streamable HTTP protocol subset needed for stateless
10
+ * tool servers: initialize, notifications/initialized, tools/list, tools/call.
11
+ */
12
+ import type { IncomingMessage, ServerResponse } from 'node:http';
13
+ interface VercelRequest extends IncomingMessage {
14
+ body?: unknown;
15
+ }
16
+ export default function handler(req: VercelRequest, res: ServerResponse): Promise<void>;
17
+ export {};
18
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAejE,UAAU,aAAc,SAAQ,eAAe;IAC7C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAwFD,wBAA8B,OAAO,CACnC,GAAG,EAAE,aAAa,EAClB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC,CAiEf"}
package/dist/http.js ADDED
@@ -0,0 +1,144 @@
1
+ /**
2
+ * DainOS MCP server — HTTP entry point for Vercel deployment.
3
+ *
4
+ * Direct JSON-RPC handler that bypasses the MCP SDK's transport layer.
5
+ * The SDK transports (StreamableHTTP, WebStandard) use SSE streaming which
6
+ * hangs on Vercel serverless. Since our server is stateless (no sessions,
7
+ * no resumability), plain JSON request-response is correct and sufficient.
8
+ *
9
+ * Implements the MCP Streamable HTTP protocol subset needed for stateless
10
+ * tool servers: initialize, notifications/initialized, tools/list, tools/call.
11
+ */
12
+ import { DainOsClient, DainOsApiError } from './client.js';
13
+ import { allTools, getTool } from './tools/index.js';
14
+ import { toJsonSchema } from './tools/types.js';
15
+ const PACKAGE_NAME = 'dainos';
16
+ const PACKAGE_VERSION = '0.6.0';
17
+ const PROTOCOL_VERSION = '2025-03-26';
18
+ const CORS_HEADERS = {
19
+ 'Access-Control-Allow-Origin': '*',
20
+ 'Access-Control-Allow-Methods': 'POST, GET, DELETE, OPTIONS',
21
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Mcp-Session-Id',
22
+ };
23
+ function sendJson(res, status, body) {
24
+ for (const [k, v] of Object.entries(CORS_HEADERS))
25
+ res.setHeader(k, v);
26
+ res.setHeader('Content-Type', 'application/json');
27
+ res.writeHead(status);
28
+ res.end(JSON.stringify(body));
29
+ }
30
+ function jsonRpcResult(id, result) {
31
+ return { jsonrpc: '2.0', result, id: id ?? null };
32
+ }
33
+ function jsonRpcError(id, code, message) {
34
+ return { jsonrpc: '2.0', error: { code, message }, id: id ?? null };
35
+ }
36
+ function handleInitialize(req) {
37
+ return jsonRpcResult(req.id, {
38
+ protocolVersion: PROTOCOL_VERSION,
39
+ capabilities: { tools: { listChanged: false } },
40
+ serverInfo: { name: PACKAGE_NAME, version: PACKAGE_VERSION },
41
+ });
42
+ }
43
+ function handleToolsList(req) {
44
+ const tools = allTools.map((tool) => ({
45
+ name: tool.name,
46
+ description: tool.description,
47
+ inputSchema: toJsonSchema(tool.inputSchema),
48
+ }));
49
+ return jsonRpcResult(req.id, { tools });
50
+ }
51
+ async function handleToolsCall(req, client) {
52
+ const params = req.params;
53
+ const toolName = params?.name;
54
+ if (!toolName) {
55
+ return jsonRpcError(req.id, -32602, 'Missing tool name in params.name');
56
+ }
57
+ const tool = getTool(toolName);
58
+ if (!tool) {
59
+ return jsonRpcError(req.id, -32602, `Unknown tool: ${toolName}`);
60
+ }
61
+ const parsed = tool.inputSchema.safeParse(params?.arguments ?? {});
62
+ if (!parsed.success) {
63
+ return jsonRpcError(req.id, -32602, `Invalid input for ${toolName}: ${parsed.error.message}`);
64
+ }
65
+ try {
66
+ const result = await tool.handler(client, parsed.data);
67
+ const text = result === undefined
68
+ ? JSON.stringify({ ok: true }, null, 2)
69
+ : JSON.stringify(result, null, 2);
70
+ return jsonRpcResult(req.id, {
71
+ content: [{ type: 'text', text }],
72
+ });
73
+ }
74
+ catch (error) {
75
+ const message = error instanceof DainOsApiError
76
+ ? error.message
77
+ : error instanceof Error
78
+ ? error.message
79
+ : String(error);
80
+ return jsonRpcResult(req.id, {
81
+ content: [{ type: 'text', text: message }],
82
+ isError: true,
83
+ });
84
+ }
85
+ }
86
+ export default async function handler(req, res) {
87
+ if (req.method === 'OPTIONS') {
88
+ for (const [k, v] of Object.entries(CORS_HEADERS))
89
+ res.setHeader(k, v);
90
+ res.writeHead(200);
91
+ res.end();
92
+ return;
93
+ }
94
+ if (req.method === 'GET' || req.method === 'DELETE') {
95
+ sendJson(res, 405, jsonRpcError(null, -32000, 'Method not allowed. Use POST for MCP requests.'));
96
+ return;
97
+ }
98
+ const authHeader = req.headers['authorization'];
99
+ const token = typeof authHeader === 'string' && authHeader.startsWith('Bearer ')
100
+ ? authHeader.slice(7)
101
+ : null;
102
+ if (!token || !token.startsWith('dain_pat_')) {
103
+ sendJson(res, 401, jsonRpcError(null, -32001, 'Missing or invalid DAINOS_API_TOKEN. Include Bearer dain_pat_... in Authorization header.'));
104
+ return;
105
+ }
106
+ const body = req.body;
107
+ if (!body) {
108
+ sendJson(res, 400, jsonRpcError(null, -32700, 'Parse error: empty body'));
109
+ return;
110
+ }
111
+ const apiUrl = process.env['DAINOS_API_URL'];
112
+ const client = new DainOsClient(apiUrl, token);
113
+ // Handle batch requests (array) and single requests
114
+ const requests = Array.isArray(body) ? body : [body];
115
+ const responses = [];
116
+ for (const rpcReq of requests) {
117
+ if (rpcReq.method === 'initialize') {
118
+ responses.push(handleInitialize(rpcReq));
119
+ }
120
+ else if (rpcReq.method === 'notifications/initialized') {
121
+ // Notification — no response per JSON-RPC spec
122
+ continue;
123
+ }
124
+ else if (rpcReq.method === 'tools/list') {
125
+ responses.push(handleToolsList(rpcReq));
126
+ }
127
+ else if (rpcReq.method === 'tools/call') {
128
+ responses.push(await handleToolsCall(rpcReq, client));
129
+ }
130
+ else if (rpcReq.method === 'ping') {
131
+ responses.push(jsonRpcResult(rpcReq.id, {}));
132
+ }
133
+ else {
134
+ responses.push(jsonRpcError(rpcReq.id, -32601, `Method not found: ${rpcReq.method}`));
135
+ }
136
+ }
137
+ if (responses.length === 0) {
138
+ // All requests were notifications
139
+ sendJson(res, 202, {});
140
+ return;
141
+ }
142
+ sendJson(res, 200, Array.isArray(body) ? responses : responses[0]);
143
+ }
144
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,8 +3,11 @@
3
3
  * DainOS MCP server entry point.
4
4
  *
5
5
  * Stdio transport. Reads DAINOS_API_TOKEN (required) and DAINOS_API_URL (optional,
6
- * defaults to https://api.dainos.app) from the environment, then exposes the 12
6
+ * defaults to https://api.dainos.app) from the environment, then exposes the
7
7
  * project/task/comment tools to any MCP client (Claude Code, etc).
8
+ *
9
+ * Tool registration is shared with the HTTP entry point (src/http.ts) via
10
+ * src/server-setup.ts.
8
11
  */
9
12
  export {};
10
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;GAMG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
package/dist/index.js CHANGED
@@ -3,17 +3,19 @@
3
3
  * DainOS MCP server entry point.
4
4
  *
5
5
  * Stdio transport. Reads DAINOS_API_TOKEN (required) and DAINOS_API_URL (optional,
6
- * defaults to https://api.dainos.app) from the environment, then exposes the 12
6
+ * defaults to https://api.dainos.app) from the environment, then exposes the
7
7
  * project/task/comment tools to any MCP client (Claude Code, etc).
8
+ *
9
+ * Tool registration is shared with the HTTP entry point (src/http.ts) via
10
+ * src/server-setup.ts.
8
11
  */
9
12
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
10
13
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
11
- import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
12
- import { DainOsClient, DainOsApiError } from './client.js';
13
- import { allTools, getTool } from './tools/index.js';
14
- import { toJsonSchema } from './tools/types.js';
14
+ import { DainOsClient } from './client.js';
15
+ import { allTools } from './tools/index.js';
16
+ import { registerToolHandlers } from './server-setup.js';
15
17
  const PACKAGE_NAME = 'dainos';
16
- const PACKAGE_VERSION = '0.2.1';
18
+ const PACKAGE_VERSION = '0.6.0';
17
19
  function fail(message) {
18
20
  process.stderr.write(`[dainos-mcp] ${message}\n`);
19
21
  process.exit(1);
@@ -29,60 +31,7 @@ async function main() {
29
31
  const baseUrl = process.env.DAINOS_API_URL;
30
32
  const client = new DainOsClient(baseUrl, token);
31
33
  const server = new Server({ name: PACKAGE_NAME, version: PACKAGE_VERSION }, { capabilities: { tools: {} } });
32
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
33
- tools: allTools.map((tool) => ({
34
- name: tool.name,
35
- description: tool.description,
36
- inputSchema: toJsonSchema(tool.inputSchema),
37
- })),
38
- }));
39
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
40
- const tool = getTool(request.params.name);
41
- if (!tool) {
42
- return {
43
- content: [
44
- { type: 'text', text: `Unknown tool: ${request.params.name}` },
45
- ],
46
- isError: true,
47
- };
48
- }
49
- const parsed = tool.inputSchema.safeParse(request.params.arguments ?? {});
50
- if (!parsed.success) {
51
- return {
52
- content: [
53
- {
54
- type: 'text',
55
- text: `Invalid input for ${tool.name}: ${parsed.error.message}`,
56
- },
57
- ],
58
- isError: true,
59
- };
60
- }
61
- try {
62
- const result = await tool.handler(client, parsed.data);
63
- // Some endpoints (e.g. archive_project hits DELETE → 204) resolve to
64
- // undefined. JSON.stringify(undefined) yields undefined, which fails the
65
- // MCP SDK's content[0].text string validation. Emit a confirmation
66
- // envelope instead so 204-style mutations don't crash the response.
67
- const text = result === undefined
68
- ? JSON.stringify({ ok: true }, null, 2)
69
- : JSON.stringify(result, null, 2);
70
- return {
71
- content: [{ type: 'text', text }],
72
- };
73
- }
74
- catch (error) {
75
- const message = error instanceof DainOsApiError
76
- ? error.message
77
- : error instanceof Error
78
- ? error.message
79
- : String(error);
80
- return {
81
- content: [{ type: 'text', text: message }],
82
- isError: true,
83
- };
84
- }
85
- });
34
+ registerToolHandlers(server, client);
86
35
  const transport = new StdioServerTransport();
87
36
  await server.connect(transport);
88
37
  process.stderr.write(`[dainos-mcp] connected (${allTools.length} tools, api=${client.baseUrl})\n`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,YAAY,GAAG,QAAQ,CAAC;AAC9B,MAAM,eAAe,GAAG,OAAO,CAAC;AAEhC,SAAS,IAAI,CAAC,OAAe;IAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,OAAO,IAAI,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,CACF,0IAA0I,CAC3I,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACnC,IAAI,CACF,8FAA8F,CAC/F,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAEhD,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,EAChD,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAChC,CAAC;IAEF,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAErC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2BAA2B,QAAQ,CAAC,MAAM,eAAe,MAAM,CAAC,OAAO,KAAK,CAC7E,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,IAAI,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;AAC5B,CAAC,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Shared MCP tool registration — used by both the stdio and HTTP entry points.
3
+ *
4
+ * Extracts the ListTools + CallTool handler setup from the original inline code
5
+ * in src/index.ts so neither entry point needs to duplicate it.
6
+ */
7
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8
+ import { DainOsClient } from './client.js';
9
+ /**
10
+ * Register the ListTools and CallTool request handlers on `server`.
11
+ *
12
+ * Identical to the inline handler setup that was previously in src/index.ts.
13
+ * Both the stdio entry point and the HTTP entry point call this function after
14
+ * creating their respective Server instances.
15
+ */
16
+ export declare function registerToolHandlers(server: Server, client: DainOsClient): void;
17
+ //# sourceMappingURL=server-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-setup.d.ts","sourceRoot":"","sources":["../src/server-setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAMnE,OAAO,EAAE,YAAY,EAAkB,MAAM,aAAa,CAAC;AAI3D;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA2D/E"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Shared MCP tool registration — used by both the stdio and HTTP entry points.
3
+ *
4
+ * Extracts the ListTools + CallTool handler setup from the original inline code
5
+ * in src/index.ts so neither entry point needs to duplicate it.
6
+ */
7
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
8
+ import { DainOsApiError } from './client.js';
9
+ import { allTools, getTool } from './tools/index.js';
10
+ import { toJsonSchema } from './tools/types.js';
11
+ /**
12
+ * Register the ListTools and CallTool request handlers on `server`.
13
+ *
14
+ * Identical to the inline handler setup that was previously in src/index.ts.
15
+ * Both the stdio entry point and the HTTP entry point call this function after
16
+ * creating their respective Server instances.
17
+ */
18
+ export function registerToolHandlers(server, client) {
19
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
20
+ tools: allTools.map((tool) => ({
21
+ name: tool.name,
22
+ description: tool.description,
23
+ inputSchema: toJsonSchema(tool.inputSchema),
24
+ })),
25
+ }));
26
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
27
+ const tool = getTool(request.params.name);
28
+ if (!tool) {
29
+ return {
30
+ content: [
31
+ { type: 'text', text: `Unknown tool: ${request.params.name}` },
32
+ ],
33
+ isError: true,
34
+ };
35
+ }
36
+ const parsed = tool.inputSchema.safeParse(request.params.arguments ?? {});
37
+ if (!parsed.success) {
38
+ return {
39
+ content: [
40
+ {
41
+ type: 'text',
42
+ text: `Invalid input for ${tool.name}: ${parsed.error.message}`,
43
+ },
44
+ ],
45
+ isError: true,
46
+ };
47
+ }
48
+ try {
49
+ const result = await tool.handler(client, parsed.data);
50
+ // Some endpoints (e.g. archive_project hits DELETE → 204) resolve to
51
+ // undefined. JSON.stringify(undefined) yields undefined, which fails the
52
+ // MCP SDK's content[0].text string validation. Emit a confirmation
53
+ // envelope instead so 204-style mutations don't crash the response.
54
+ const text = result === undefined
55
+ ? JSON.stringify({ ok: true }, null, 2)
56
+ : JSON.stringify(result, null, 2);
57
+ return {
58
+ content: [{ type: 'text', text }],
59
+ };
60
+ }
61
+ catch (error) {
62
+ const message = error instanceof DainOsApiError
63
+ ? error.message
64
+ : error instanceof Error
65
+ ? error.message
66
+ : String(error);
67
+ return {
68
+ content: [{ type: 'text', text: message }],
69
+ isError: true,
70
+ };
71
+ }
72
+ });
73
+ }
74
+ //# sourceMappingURL=server-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-setup.js","sourceRoot":"","sources":["../src/server-setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAgB,cAAc,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,MAAoB;IACvE,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;SAC5C,CAAC,CAAC;KACJ,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,iBAAiB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE;iBACxE;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,qBAAqB,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;qBAChE;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YACvD,qEAAqE;YACrE,yEAAyE;YACzE,mEAAmE;YACnE,oEAAoE;YACpE,MAAM,IAAI,GACR,MAAM,KAAK,SAAS;gBAClB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACtC,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;aAC3C,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GACX,KAAK,YAAY,cAAc;gBAC7B,CAAC,CAAC,KAAK,CAAC,OAAO;gBACf,CAAC,CAAC,KAAK,YAAY,KAAK;oBACtB,CAAC,CAAC,KAAK,CAAC,OAAO;oBACf,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gBACnD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ToolDefinition } from './types.js';
2
+ /** All four Cadence MCP tools. */
3
+ export declare const cadenceTools: ToolDefinition[];
4
+ //# sourceMappingURL=cadence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cadence.d.ts","sourceRoot":"","sources":["../../src/tools/cadence.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAoRjD,kCAAkC;AAClC,eAAO,MAAM,YAAY,EAAE,cAAc,EAKxC,CAAC"}
@@ -0,0 +1,245 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Cadence MCP tools: AI agent feed for the Sprint + Cadence feature.
4
+ *
5
+ * Four tools for agents (Claude Code, Otto) to interact with the sprint plan:
6
+ * claim_next_task — fetch the highest-ranked open task from the sprint
7
+ * report_task_progress — append a one-liner progress note with agent identity
8
+ * mark_blocked — flag a task as blocked with a reason
9
+ * request_unblock — signal that a task needs human attention to unblock
10
+ *
11
+ * Audit trail: all writes carry metadata.via='mcp' and metadata.client so the
12
+ * cadence_actions record shows "Claude Code" rather than "system". The API
13
+ * side uses this to attribute agent activity in the sprint timeline.
14
+ *
15
+ * @builder ship-api-builder (Round 4, R4-T1)
16
+ */
17
+ // ---------------------------------------------------------------------------
18
+ // claim_next_task
19
+ // ---------------------------------------------------------------------------
20
+ const claimNextTask = {
21
+ name: 'claim_next_task',
22
+ description: 'Fetch the highest-ranked open task from the Cadence sprint feed. ' +
23
+ 'Returns the task object with its Cadence ranking rationale and score. ' +
24
+ 'Call this at the start of an autonomous work session to find what to work on next. ' +
25
+ 'Filters by sprintId, projectId, or assigneeId when provided.',
26
+ inputSchema: z.object({
27
+ sprintId: z
28
+ .string()
29
+ .uuid()
30
+ .optional()
31
+ .describe('Restrict to tasks in a specific sprint.'),
32
+ projectId: z
33
+ .string()
34
+ .uuid()
35
+ .optional()
36
+ .describe('Restrict to tasks in a specific project.'),
37
+ assigneeId: z
38
+ .string()
39
+ .uuid()
40
+ .optional()
41
+ .describe('Restrict to tasks assigned to a specific IAM user.'),
42
+ client: z
43
+ .string()
44
+ .max(100)
45
+ .optional()
46
+ .describe('Caller identity for the audit trail (e.g. "claude-code", "otto"). ' +
47
+ 'Logged as metadata.client on the resulting cadence_actions row.'),
48
+ }),
49
+ handler: async (client, input) => {
50
+ const params = new URLSearchParams();
51
+ if (input.sprintId)
52
+ params.set('sprintId', input.sprintId);
53
+ if (input.projectId)
54
+ params.set('projectId', input.projectId);
55
+ if (input.assigneeId)
56
+ params.set('assigneeId', input.assigneeId);
57
+ const query = params.toString() ? `?${params.toString()}` : '';
58
+ // GET /api/v1/cadence/feed/next-task returns { task: RankedTask | null }
59
+ // The ranked task includes rationale and ranking score from CadenceRankerService.
60
+ return client.get(`/cadence/feed/next-task${query}`);
61
+ },
62
+ };
63
+ // ---------------------------------------------------------------------------
64
+ // report_task_progress
65
+ // ---------------------------------------------------------------------------
66
+ const reportTaskProgress = {
67
+ name: 'report_task_progress',
68
+ description: 'Append a one-line progress note to a task and record it in the Cadence audit trail. ' +
69
+ 'Use this after completing a meaningful unit of work on a task (e.g. "Implemented ' +
70
+ 'the migration file and ran npx prisma generate"). ' +
71
+ 'The note is written to the task\'s AI progress log section and creates a ' +
72
+ 'cadence_actions row with action_type=progress_note for the sprint timeline. ' +
73
+ 'Provide your client identity so the audit trail reads "Claude Code" not "system".',
74
+ inputSchema: z.object({
75
+ taskId: z
76
+ .string()
77
+ .uuid()
78
+ .describe('The task to update.'),
79
+ note: z
80
+ .string()
81
+ .min(1)
82
+ .max(500)
83
+ .describe('One-line progress note in plain English. ' +
84
+ 'Will be appended inside the AI-progress-log sentinel block in the task description. ' +
85
+ 'Example: "Added Zod schema and controller handler for POST /cadence/draft."'),
86
+ client: z
87
+ .string()
88
+ .max(100)
89
+ .optional()
90
+ .describe('Caller identity for the audit trail (e.g. "claude-code"). ' +
91
+ 'Logged as metadata.client on the cadence_actions row.'),
92
+ }),
93
+ handler: async (client, input) => {
94
+ // Step 1: fetch the current task description so we can append to the AI progress block.
95
+ const task = await client.get(`/tasks/${input.taskId}`);
96
+ const now = new Date().toISOString();
97
+ const clientLabel = input.client ?? 'mcp-agent';
98
+ const newLine = `[${now}] (${clientLabel}) ${input.note}`;
99
+ const BEGIN_MARKER = '<!-- BEGIN AI-PROGRESS-LOG -->';
100
+ const END_MARKER = '<!-- END AI-PROGRESS-LOG -->';
101
+ const existing = task.description ?? '';
102
+ let updatedDescription;
103
+ if (existing.includes(BEGIN_MARKER) && existing.includes(END_MARKER)) {
104
+ // Append before the closing marker.
105
+ updatedDescription = existing.replace(END_MARKER, `${newLine}\n${END_MARKER}`);
106
+ }
107
+ else {
108
+ // No sentinel block yet — append one at the end.
109
+ updatedDescription =
110
+ existing.trimEnd() +
111
+ `\n\n${BEGIN_MARKER}\n${newLine}\n${END_MARKER}`;
112
+ }
113
+ // Step 2: update the task description.
114
+ await client.put(`/tasks/${input.taskId}`, { description: updatedDescription });
115
+ // Step 3: write a cadence_actions row for the sprint timeline.
116
+ // action_type='progress_note', target_type='task', payload carries the note + client identity.
117
+ await client.post('/cadence/actions', {
118
+ actionType: 'progress_note',
119
+ targetType: 'task',
120
+ targetId: input.taskId,
121
+ rationale: input.note,
122
+ payload: {
123
+ via: 'mcp',
124
+ client: clientLabel,
125
+ timestamp: now,
126
+ },
127
+ });
128
+ return { success: true, taskId: input.taskId, note: input.note };
129
+ },
130
+ };
131
+ // ---------------------------------------------------------------------------
132
+ // mark_blocked
133
+ // ---------------------------------------------------------------------------
134
+ const markBlocked = {
135
+ name: 'mark_blocked',
136
+ description: 'Mark a task as blocked and record the reason in the Cadence audit trail. ' +
137
+ 'Use when you hit a genuine blocker while working on a task autonomously ' +
138
+ '(e.g. missing API key, conflicting schema, waiting on another task). ' +
139
+ 'The task status changes to "blocked" and a cadence_actions row is created ' +
140
+ 'so the sprint timeline shows the block and the human can address it. ' +
141
+ 'The reason must be specific enough for a human to act on without asking you.',
142
+ inputSchema: z.object({
143
+ taskId: z
144
+ .string()
145
+ .uuid()
146
+ .describe('The task to mark blocked.'),
147
+ reason: z
148
+ .string()
149
+ .min(1)
150
+ .max(500)
151
+ .describe('Plain English description of the blocker. Be specific: ' +
152
+ '"Waiting on OPENAI_API_KEY in the api .env" is actionable. ' +
153
+ '"It\'s blocked" is not. Minimum 1 character, maximum 500.'),
154
+ client: z
155
+ .string()
156
+ .max(100)
157
+ .optional()
158
+ .describe('Caller identity for the audit trail (e.g. "claude-code").'),
159
+ }),
160
+ handler: async (client, input) => {
161
+ const clientLabel = input.client ?? 'mcp-agent';
162
+ const now = new Date().toISOString();
163
+ // Step 1: update task status to blocked.
164
+ await client.put(`/tasks/${input.taskId}`, { status: 'blocked' });
165
+ // Step 2: create a cadence_actions row for the audit trail.
166
+ await client.post('/cadence/actions', {
167
+ actionType: 'mark_blocked',
168
+ targetType: 'task',
169
+ targetId: input.taskId,
170
+ rationale: input.reason,
171
+ payload: {
172
+ via: 'mcp',
173
+ client: clientLabel,
174
+ timestamp: now,
175
+ reason: input.reason,
176
+ },
177
+ });
178
+ return { success: true, taskId: input.taskId, reason: input.reason };
179
+ },
180
+ };
181
+ // ---------------------------------------------------------------------------
182
+ // request_unblock
183
+ // ---------------------------------------------------------------------------
184
+ const requestUnblock = {
185
+ name: 'request_unblock',
186
+ description: 'Signal that a blocked task needs human attention to unblock. ' +
187
+ 'Use after mark_blocked if you want to escalate urgency or add additional context ' +
188
+ 'beyond the original block reason. ' +
189
+ 'Creates a cadence_actions row with action_type=request_unblock which surfaces ' +
190
+ 'in the next Cadence daily scan and CadenceSidebarPanel stale items list. ' +
191
+ 'Does not change task status (task stays blocked until a human acts).',
192
+ inputSchema: z.object({
193
+ taskId: z
194
+ .string()
195
+ .uuid()
196
+ .describe('The blocked task that needs human attention.'),
197
+ context: z
198
+ .string()
199
+ .min(1)
200
+ .max(500)
201
+ .optional()
202
+ .describe('Additional context for the human — e.g. what you tried, what you need to proceed. ' +
203
+ 'Optional but strongly recommended for actionability.'),
204
+ client: z
205
+ .string()
206
+ .max(100)
207
+ .optional()
208
+ .describe('Caller identity for the audit trail (e.g. "claude-code").'),
209
+ }),
210
+ handler: async (client, input) => {
211
+ const clientLabel = input.client ?? 'mcp-agent';
212
+ const now = new Date().toISOString();
213
+ // Write a cadence_actions row with action_type='request_unblock'.
214
+ // The next daily scan will pick this up and surface it in the stale items list.
215
+ await client.post('/cadence/actions', {
216
+ actionType: 'request_unblock',
217
+ targetType: 'task',
218
+ targetId: input.taskId,
219
+ rationale: input.context ?? 'Agent requested human unblock.',
220
+ payload: {
221
+ via: 'mcp',
222
+ client: clientLabel,
223
+ timestamp: now,
224
+ context: input.context ?? null,
225
+ },
226
+ });
227
+ return {
228
+ success: true,
229
+ taskId: input.taskId,
230
+ message: 'Unblock request recorded. The next Cadence daily scan will surface this task ' +
231
+ 'in the sprint sidebar for human review.',
232
+ };
233
+ },
234
+ };
235
+ // ---------------------------------------------------------------------------
236
+ // Export
237
+ // ---------------------------------------------------------------------------
238
+ /** All four Cadence MCP tools. */
239
+ export const cadenceTools = [
240
+ claimNextTask,
241
+ reportTaskProgress,
242
+ markBlocked,
243
+ requestUnblock,
244
+ ];
245
+ //# sourceMappingURL=cadence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cadence.js","sourceRoot":"","sources":["../../src/tools/cadence.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,9 @@ import { proposalContentTools } from './proposal-content.js';
9
9
  import { prReviewTools } from './pr-review.js';
10
10
  import { iamTools } from './iam.js';
11
11
  import { productTools } from './products.js';
12
- export { projectTools, taskTools, commentTools, developerTools, proposalTools, proposalOptionTools, proposalContentTools, prReviewTools, iamTools, productTools, };
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, };
13
15
  export type { ToolDefinition };
14
16
  /** All tools exposed by the DainOS MCP server. */
15
17
  export declare const allTools: ToolDefinition[];
@@ -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;AAE7C,OAAO,EACL,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,QAAQ,EACR,YAAY,GACb,CAAC;AACF,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B,kDAAkD;AAClD,eAAO,MAAM,QAAQ,EAAE,cAAc,EAWpC,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;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"}
@@ -8,7 +8,15 @@ import { proposalContentTools } from './proposal-content.js';
8
8
  import { prReviewTools } from './pr-review.js';
9
9
  import { iamTools } from './iam.js';
10
10
  import { productTools } from './products.js';
11
- export { projectTools, taskTools, commentTools, developerTools, proposalTools, proposalOptionTools, proposalContentTools, prReviewTools, iamTools, productTools, };
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, };
12
20
  /** All tools exposed by the DainOS MCP server. */
13
21
  export const allTools = [
14
22
  ...projectTools,
@@ -21,6 +29,12 @@ export const allTools = [
21
29
  ...prReviewTools,
22
30
  ...iamTools,
23
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
24
38
  ];
25
39
  /** Look up a tool by its exposed name. */
26
40
  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;AAE7C,OAAO,EACL,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,QAAQ,EACR,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;CAChB,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,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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from './types.js';
2
+ export declare const libraryTools: ToolDefinition[];
3
+ //# sourceMappingURL=library.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../../src/tools/library.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA0FjD,eAAO,MAAM,YAAY,EAAE,cAAc,EAIxC,CAAC"}
@@ -0,0 +1,94 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Library tools for the DainOS instruction library (PRD-086).
4
+ *
5
+ * Three tools expose the GET /api/v1/instructions endpoints:
6
+ * - list_instructions: browse by category / project / tags
7
+ * - get_instruction: fetch one entry by slug with template variable resolution
8
+ * - search_instructions: keyword search against title/slug/description
9
+ *
10
+ * search_instructions and list_instructions both hit GET /api/v1/instructions.
11
+ * The difference is in the tool descriptions (browsing vs searching) and
12
+ * required vs optional fields. This keeps the API surface minimal while giving
13
+ * the model two conceptually distinct operations.
14
+ */
15
+ const categoryEnum = z.enum([
16
+ 'rule',
17
+ 'skill',
18
+ 'agent',
19
+ 'command',
20
+ 'prompt',
21
+ 'template',
22
+ 'claude_md',
23
+ ]);
24
+ const listInstructions = {
25
+ name: 'list_instructions',
26
+ description: 'List available instructions from the DainOS library. Returns slug, title, description, and category for each entry. Use category to filter by type (rule, skill, agent, command). Use project to filter by compatibility.',
27
+ inputSchema: z.object({
28
+ category: categoryEnum
29
+ .optional()
30
+ .describe('Filter by instruction type: rule, skill, agent, command, prompt, template, claude_md.'),
31
+ project: z
32
+ .string()
33
+ .optional()
34
+ .describe('Project slug (e.g. "herbert", "dain-os"). Filters to entries compatible with this project.'),
35
+ tags: z.string().optional().describe('Comma-separated tag filter.'),
36
+ q: z.string().optional().describe('Free-text search.'),
37
+ }),
38
+ handler: async (client, input) => {
39
+ const params = new URLSearchParams();
40
+ if (input.category)
41
+ params.set('category', input.category);
42
+ if (input.project)
43
+ params.set('project', input.project);
44
+ if (input.tags)
45
+ params.set('tags', input.tags);
46
+ if (input.q)
47
+ params.set('q', input.q);
48
+ return client.get(`/instructions?${params.toString()}`);
49
+ },
50
+ };
51
+ const getInstruction = {
52
+ name: 'get_instruction',
53
+ description: 'Fetch a specific instruction by slug with fully resolved template variables. The returned markdown_content is ready to use as a skill, rule, agent, or command body. Any unresolved template variables are listed in unresolved_variables.',
54
+ inputSchema: z.object({
55
+ slug: z
56
+ .string()
57
+ .describe('Instruction slug (e.g. "rule-core-rules", "skill-ship-architect").'),
58
+ project: z
59
+ .string()
60
+ .optional()
61
+ .describe('Project slug for template variable resolution.'),
62
+ }),
63
+ handler: async (client, input) => {
64
+ const params = new URLSearchParams();
65
+ if (input.project)
66
+ params.set('project', input.project);
67
+ const qs = params.toString();
68
+ return client.get(`/instructions/${input.slug}${qs ? `?${qs}` : ''}`);
69
+ },
70
+ };
71
+ const searchInstructions = {
72
+ name: 'search_instructions',
73
+ description: 'Search the instruction library by keyword. Returns ranked results with slug and description. Use this when you know what capability you need but not the exact slug.',
74
+ inputSchema: z.object({
75
+ q: z.string().describe('Search query. Matches against title, slug, and description.'),
76
+ category: categoryEnum.optional(),
77
+ project: z.string().optional().describe('Project slug to filter by compatibility.'),
78
+ }),
79
+ handler: async (client, input) => {
80
+ const params = new URLSearchParams();
81
+ params.set('q', input.q);
82
+ if (input.category)
83
+ params.set('category', input.category);
84
+ if (input.project)
85
+ params.set('project', input.project);
86
+ return client.get(`/instructions?${params.toString()}`);
87
+ },
88
+ };
89
+ export const libraryTools = [
90
+ listInstructions,
91
+ getInstruction,
92
+ searchInstructions,
93
+ ];
94
+ //# sourceMappingURL=library.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"library.js","sourceRoot":"","sources":["../../src/tools/library.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dain-os/mcp-server",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "MCP server for DainOS — manage projects, tasks, proposals, and proposal content from Claude Code and other MCP clients",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,6 +9,10 @@
9
9
  },
10
10
  "main": "./dist/index.js",
11
11
  "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": "./dist/index.js",
14
+ "./http": "./dist/http.js"
15
+ },
12
16
  "files": [
13
17
  "dist",
14
18
  "README.md"
@@ -21,7 +25,7 @@
21
25
  "check-types": "tsc --noEmit"
22
26
  },
23
27
  "dependencies": {
24
- "@modelcontextprotocol/sdk": "^1.0.4",
28
+ "@modelcontextprotocol/sdk": "^1.12.1",
25
29
  "zod": "^3.23.8"
26
30
  },
27
31
  "devDependencies": {