@justmpm/task-request 1.0.0 → 1.0.2
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 +52 -14
- package/dist/mcp-app.d.ts +4 -0
- package/dist/mcp-app.d.ts.map +1 -0
- package/dist/mcp-app.html +60 -52
- package/dist/mcp-app.js +164 -0
- package/dist/mcp-app.js.map +1 -0
- package/dist/server.d.ts +0 -11
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +7 -190
- package/dist/server.js.map +1 -1
- package/dist/stdio.d.ts +3 -0
- package/dist/stdio.d.ts.map +1 -0
- package/dist/stdio.js +14 -0
- package/dist/stdio.js.map +1 -0
- package/package.json +5 -3
package/dist/mcp-app.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE, } from "@modelcontextprotocol/ext-apps/server";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import fsSync from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { TaskInputSchema, taskInputShape } from "./shared/task-contract.js";
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
11
|
+
const resourceUri = "ui://create-task/mcp-app.html";
|
|
12
|
+
const uiMeta = {
|
|
13
|
+
csp: {
|
|
14
|
+
connectDomains: [],
|
|
15
|
+
resourceDomains: [],
|
|
16
|
+
},
|
|
17
|
+
prefersBorder: true,
|
|
18
|
+
};
|
|
19
|
+
function getPackageVersion() {
|
|
20
|
+
try {
|
|
21
|
+
const packagePath = path.join(__dirname, "..", "package.json");
|
|
22
|
+
const packageJson = JSON.parse(fsSync.readFileSync(packagePath, "utf-8"));
|
|
23
|
+
return packageJson.version ?? "1.0.0";
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return "1.0.0";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export const PACKAGE_VERSION = getPackageVersion();
|
|
30
|
+
function buildTaskPrompt(args) {
|
|
31
|
+
const typeLabels = {
|
|
32
|
+
implement: "Implementar",
|
|
33
|
+
fix: "Corrigir",
|
|
34
|
+
analyze: "Analisar",
|
|
35
|
+
refactor: "Refatorar",
|
|
36
|
+
test: "Testar",
|
|
37
|
+
document: "Documentar",
|
|
38
|
+
};
|
|
39
|
+
const priorityEmoji = {
|
|
40
|
+
urgent: "🔴",
|
|
41
|
+
normal: "🟡",
|
|
42
|
+
low: "🟢",
|
|
43
|
+
};
|
|
44
|
+
let prompt = `## 📋 TASK: ${args.title}\n\n`;
|
|
45
|
+
prompt += `**Tipo:** ${typeLabels[args.type]}\n`;
|
|
46
|
+
prompt += `**Prioridade:** ${priorityEmoji[args.priority]} ${args.priority.charAt(0).toUpperCase() + args.priority.slice(1)}\n\n`;
|
|
47
|
+
prompt += `---\n\n`;
|
|
48
|
+
prompt += `### 🎯 O que preciso\n\n${args.description}\n\n`;
|
|
49
|
+
if (args.context) {
|
|
50
|
+
prompt += `### 📎 Contexto Adicional\n\n${args.context}\n\n`;
|
|
51
|
+
}
|
|
52
|
+
if (args.files && args.files.length > 0) {
|
|
53
|
+
prompt += "### 📁 Arquivos Relacionados\n\n";
|
|
54
|
+
args.files.forEach((file) => {
|
|
55
|
+
prompt += `- \`${file}\`\n`;
|
|
56
|
+
});
|
|
57
|
+
prompt += "\n";
|
|
58
|
+
}
|
|
59
|
+
if (args.restrictions && args.restrictions.length > 0) {
|
|
60
|
+
prompt += "### ⛔ Restrições\n\n";
|
|
61
|
+
prompt += "**O que NÃO fazer:**\n\n";
|
|
62
|
+
args.restrictions.forEach((restriction) => {
|
|
63
|
+
prompt += `- ${restriction}\n`;
|
|
64
|
+
});
|
|
65
|
+
prompt += "\n";
|
|
66
|
+
}
|
|
67
|
+
if (args.acceptanceCriteria && args.acceptanceCriteria.length > 0) {
|
|
68
|
+
prompt += "### ✅ Critérios de Aceite\n\n";
|
|
69
|
+
args.acceptanceCriteria.forEach((criteria, index) => {
|
|
70
|
+
prompt += `${index + 1}. ${criteria}\n`;
|
|
71
|
+
});
|
|
72
|
+
prompt += "\n";
|
|
73
|
+
}
|
|
74
|
+
prompt += "---\n\n";
|
|
75
|
+
prompt += "> Task criada via Task Request Builder MCP App";
|
|
76
|
+
return prompt;
|
|
77
|
+
}
|
|
78
|
+
async function loadUiHtml() {
|
|
79
|
+
const possiblePaths = [
|
|
80
|
+
path.join(__dirname, "..", "dist", "mcp-app.html"),
|
|
81
|
+
path.join(process.cwd(), "dist", "mcp-app.html"),
|
|
82
|
+
];
|
|
83
|
+
for (const filePath of possiblePaths) {
|
|
84
|
+
try {
|
|
85
|
+
return await fs.readFile(filePath, "utf-8");
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return `
|
|
92
|
+
<!DOCTYPE html>
|
|
93
|
+
<html>
|
|
94
|
+
<head><title>Erro</title></head>
|
|
95
|
+
<body style="font-family: sans-serif; padding: 20px;">
|
|
96
|
+
<h1>⚠️ UI não encontrada</h1>
|
|
97
|
+
<p>Execute <code>npm run build:ui</code> para gerar a interface.</p>
|
|
98
|
+
</body>
|
|
99
|
+
</html>
|
|
100
|
+
`;
|
|
101
|
+
}
|
|
102
|
+
export function createTaskRequestServer() {
|
|
103
|
+
const server = new McpServer({
|
|
104
|
+
name: "@justmpm/task-request",
|
|
105
|
+
version: PACKAGE_VERSION,
|
|
106
|
+
});
|
|
107
|
+
registerAppTool(server, "create_task", {
|
|
108
|
+
title: "Create Task",
|
|
109
|
+
description: "Abre um formulário interativo para criar uma task estruturada. " +
|
|
110
|
+
"Útil quando você quer organizar uma solicitação de forma completa com tipo, prioridade, " +
|
|
111
|
+
"contexto e restrições. Gera um prompt estruturado pronto para usar.",
|
|
112
|
+
inputSchema: z.object({}),
|
|
113
|
+
_meta: {
|
|
114
|
+
ui: {
|
|
115
|
+
resourceUri,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
}, async () => ({
|
|
119
|
+
content: [
|
|
120
|
+
{
|
|
121
|
+
type: "text",
|
|
122
|
+
text: "📋 Formulário de Task aberto. Preencha os campos e clique em 'Enviar Task'.",
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
}));
|
|
126
|
+
server.tool("submit_task", "Recebe os dados do formulário de task e retorna um prompt estruturado formatado", taskInputShape, async (args) => {
|
|
127
|
+
const normalizedTask = TaskInputSchema.parse(args);
|
|
128
|
+
const prompt = buildTaskPrompt(normalizedTask);
|
|
129
|
+
return {
|
|
130
|
+
structuredContent: {
|
|
131
|
+
task: normalizedTask,
|
|
132
|
+
prompt,
|
|
133
|
+
},
|
|
134
|
+
content: [
|
|
135
|
+
{
|
|
136
|
+
type: "text",
|
|
137
|
+
text: prompt,
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
registerAppResource(server, resourceUri, resourceUri, {
|
|
143
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
144
|
+
_meta: {
|
|
145
|
+
ui: uiMeta,
|
|
146
|
+
},
|
|
147
|
+
}, async () => {
|
|
148
|
+
const html = await loadUiHtml();
|
|
149
|
+
return {
|
|
150
|
+
contents: [
|
|
151
|
+
{
|
|
152
|
+
uri: resourceUri,
|
|
153
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
154
|
+
text: html,
|
|
155
|
+
_meta: {
|
|
156
|
+
ui: uiMeta,
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
};
|
|
161
|
+
});
|
|
162
|
+
return server;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=mcp-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-app.js","sourceRoot":"","sources":["../src/mcp-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,kBAAkB,GACnB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE5E,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAC3C,MAAM,WAAW,GAAG,+BAA+B,CAAC;AACpD,MAAM,MAAM,GAAG;IACb,GAAG,EAAE;QACH,cAAc,EAAE,EAAE;QAClB,eAAe,EAAE,EAAE;KACpB;IACD,aAAa,EAAE,IAAI;CACpB,CAAC;AAEF,SAAS,iBAAiB;IACxB,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAEvE,CAAC;QACF,OAAO,WAAW,CAAC,OAAO,IAAI,OAAO,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,EAAE,CAAC;AAEnD,SAAS,eAAe,CAAC,IAAqC;IAC5D,MAAM,UAAU,GAA2B;QACzC,SAAS,EAAE,aAAa;QACxB,GAAG,EAAE,UAAU;QACf,OAAO,EAAE,UAAU;QACnB,QAAQ,EAAE,WAAW;QACrB,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,YAAY;KACvB,CAAC;IAEF,MAAM,aAAa,GAA2B;QAC5C,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,IAAI;QACZ,GAAG,EAAE,IAAI;KACV,CAAC;IAEF,IAAI,MAAM,GAAG,eAAe,IAAI,CAAC,KAAK,MAAM,CAAC;IAC7C,MAAM,IAAI,aAAa,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACjD,MAAM,IAAI,mBAAmB,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAClI,MAAM,IAAI,SAAS,CAAC;IACpB,MAAM,IAAI,2BAA2B,IAAI,CAAC,WAAW,MAAM,CAAC;IAE5D,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,IAAI,gCAAgC,IAAI,CAAC,OAAO,MAAM,CAAC;IAC/D,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,kCAAkC,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC1B,MAAM,IAAI,OAAO,IAAI,MAAM,CAAC;QAC9B,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,IAAI,CAAC;IACjB,CAAC;IAED,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,sBAAsB,CAAC;QACjC,MAAM,IAAI,0BAA0B,CAAC;QACrC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;YACxC,MAAM,IAAI,KAAK,WAAW,IAAI,CAAC;QACjC,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,IAAI,CAAC;IACjB,CAAC;IAED,IAAI,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,+BAA+B,CAAC;QAC1C,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;YAClD,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC;QAC1C,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,IAAI,CAAC;IACjB,CAAC;IAED,MAAM,IAAI,SAAS,CAAC;IACpB,MAAM,IAAI,gDAAgD,CAAC;IAC3D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,UAAU;IACvB,MAAM,aAAa,GAAG;QACpB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC;QAClD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,cAAc,CAAC;KACjD,CAAC;IAEF,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAED,OAAO;;;;;;;;;GASN,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,eAAe;KACzB,CAAC,CAAC;IAEH,eAAe,CACb,MAAM,EACN,aAAa,EACb;QACE,KAAK,EAAE,aAAa;QACpB,WAAW,EACT,iEAAiE;YACjE,0FAA0F;YAC1F,qEAAqE;QACvE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,KAAK,EAAE;YACL,EAAE,EAAE;gBACF,WAAW;aACZ;SACF;KACF,EACD,KAAK,IAAI,EAAE,CAAC,CAAC;QACX,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,6EAA6E;aACpF;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,aAAa,EACb,iFAAiF,EACjF,cAAc,EACd,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,cAAc,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;QAE/C,OAAO;YACL,iBAAiB,EAAE;gBACjB,IAAI,EAAE,cAAc;gBACpB,MAAM;aACP;YACD,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,MAAM;iBACb;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,mBAAmB,CACjB,MAAM,EACN,WAAW,EACX,WAAW,EACX;QACE,QAAQ,EAAE,kBAAkB;QAC5B,KAAK,EAAE;YACL,EAAE,EAAE,MAAM;SACX;KACF,EACD,KAAK,IAAI,EAAE;QACT,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;QAEhC,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,WAAW;oBAChB,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI;oBACV,KAAK,EAAE;wBACL,EAAE,EAAE,MAAM;qBACX;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* @justmpm/task-request - MCP App Server
|
|
4
|
-
*
|
|
5
|
-
* Servidor MCP que expõe tools com UI interativa para criar tasks estruturadas.
|
|
6
|
-
* Usa HTTP transport (não stdio) para suportar MCP Apps.
|
|
7
|
-
*
|
|
8
|
-
* Tools disponíveis:
|
|
9
|
-
* - create_task: Abre formulário interativo para criar task estruturada
|
|
10
|
-
*
|
|
11
|
-
* @see https://modelcontextprotocol.io/
|
|
12
|
-
*/
|
|
13
2
|
export {};
|
|
14
3
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
|
package/dist/server.js
CHANGED
|
@@ -1,189 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* @justmpm/task-request - MCP App Server
|
|
4
|
-
*
|
|
5
|
-
* Servidor MCP que expõe tools com UI interativa para criar tasks estruturadas.
|
|
6
|
-
* Usa HTTP transport (não stdio) para suportar MCP Apps.
|
|
7
|
-
*
|
|
8
|
-
* Tools disponíveis:
|
|
9
|
-
* - create_task: Abre formulário interativo para criar task estruturada
|
|
10
|
-
*
|
|
11
|
-
* @see https://modelcontextprotocol.io/
|
|
12
|
-
*/
|
|
13
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
14
|
-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
15
|
-
import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE, } from "@modelcontextprotocol/ext-apps/server";
|
|
16
2
|
import cors from "cors";
|
|
17
3
|
import express from "express";
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import { fileURLToPath } from "node:url";
|
|
22
|
-
import { z } from "zod";
|
|
23
|
-
import { MIN_TASK_DESCRIPTION_LENGTH, TaskInputSchema, taskInputShape } from "./shared/task-contract.js";
|
|
24
|
-
// =============================================================================
|
|
25
|
-
// VERSÃO E PATHS
|
|
26
|
-
// =============================================================================
|
|
27
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
28
|
-
const __dirname = path.dirname(__filename);
|
|
29
|
-
function getPackageVersion() {
|
|
30
|
-
try {
|
|
31
|
-
const packagePath = path.join(__dirname, "..", "package.json");
|
|
32
|
-
const packageJson = JSON.parse(fsSync.readFileSync(packagePath, "utf-8"));
|
|
33
|
-
return packageJson.version || "1.0.0";
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
return "1.0.0";
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
const PACKAGE_VERSION = getPackageVersion();
|
|
40
|
-
// =============================================================================
|
|
41
|
-
// SERVIDOR MCP
|
|
42
|
-
// =============================================================================
|
|
43
|
-
const server = new McpServer({
|
|
44
|
-
name: "@justmpm/task-request",
|
|
45
|
-
version: PACKAGE_VERSION,
|
|
46
|
-
});
|
|
47
|
-
// URI do recurso da UI
|
|
48
|
-
const resourceUri = "ui://create-task/mcp-app.html";
|
|
49
|
-
// =============================================================================
|
|
50
|
-
// TOOL: create_task (com UI)
|
|
51
|
-
// =============================================================================
|
|
52
|
-
registerAppTool(server, "create_task", {
|
|
53
|
-
title: "Create Task",
|
|
54
|
-
description: "Abre um formulário interativo para criar uma task estruturada. " +
|
|
55
|
-
"Útil quando você quer organizar uma solicitação de forma completa com tipo, prioridade, " +
|
|
56
|
-
"contexto e restrições. Gera um prompt estruturado pronto para usar.",
|
|
57
|
-
inputSchema: z.object({}),
|
|
58
|
-
_meta: {
|
|
59
|
-
ui: {
|
|
60
|
-
resourceUri,
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
}, async () => {
|
|
64
|
-
// Tool inicial - apenas indica que o formulário foi aberto
|
|
65
|
-
return {
|
|
66
|
-
content: [
|
|
67
|
-
{
|
|
68
|
-
type: "text",
|
|
69
|
-
text: "📋 Formulário de Task aberto. Preencha os campos e clique em 'Enviar Task'.",
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
};
|
|
73
|
-
});
|
|
74
|
-
// =============================================================================
|
|
75
|
-
// TOOL: submit_task (chamada pelo app UI)
|
|
76
|
-
// =============================================================================
|
|
77
|
-
server.tool("submit_task", "Recebe os dados do formulário de task e retorna um prompt estruturado formatado", taskInputShape, async (args) => {
|
|
78
|
-
const normalizedTask = TaskInputSchema.parse(args);
|
|
79
|
-
// Mapear tipo para português
|
|
80
|
-
const typeLabels = {
|
|
81
|
-
implement: "Implementar",
|
|
82
|
-
fix: "Corrigir",
|
|
83
|
-
analyze: "Analisar",
|
|
84
|
-
refactor: "Refatorar",
|
|
85
|
-
test: "Testar",
|
|
86
|
-
document: "Documentar",
|
|
87
|
-
};
|
|
88
|
-
// Mapear prioridade para emoji
|
|
89
|
-
const priorityEmoji = {
|
|
90
|
-
urgent: "🔴",
|
|
91
|
-
normal: "🟡",
|
|
92
|
-
low: "🟢",
|
|
93
|
-
};
|
|
94
|
-
// Gerar prompt estruturado
|
|
95
|
-
let prompt = `## 📋 TASK: ${normalizedTask.title}\n\n`;
|
|
96
|
-
prompt += `**Tipo:** ${typeLabels[normalizedTask.type]}\n`;
|
|
97
|
-
prompt += `**Prioridade:** ${priorityEmoji[normalizedTask.priority]} ${normalizedTask.priority.charAt(0).toUpperCase() + normalizedTask.priority.slice(1)}\n\n`;
|
|
98
|
-
prompt += `---\n\n`;
|
|
99
|
-
prompt += `### 🎯 O que preciso\n\n${normalizedTask.description}\n\n`;
|
|
100
|
-
if (normalizedTask.context) {
|
|
101
|
-
prompt += `### 📎 Contexto Adicional\n\n${normalizedTask.context}\n\n`;
|
|
102
|
-
}
|
|
103
|
-
if (normalizedTask.files && normalizedTask.files.length > 0) {
|
|
104
|
-
prompt += `### 📁 Arquivos Relacionados\n\n`;
|
|
105
|
-
normalizedTask.files.forEach((file) => {
|
|
106
|
-
prompt += `- \`${file}\`\n`;
|
|
107
|
-
});
|
|
108
|
-
prompt += `\n`;
|
|
109
|
-
}
|
|
110
|
-
if (normalizedTask.restrictions && normalizedTask.restrictions.length > 0) {
|
|
111
|
-
prompt += `### ⛔ Restrições\n\n`;
|
|
112
|
-
prompt += `**O que NÃO fazer:**\n\n`;
|
|
113
|
-
normalizedTask.restrictions.forEach((restriction) => {
|
|
114
|
-
prompt += `- ${restriction}\n`;
|
|
115
|
-
});
|
|
116
|
-
prompt += `\n`;
|
|
117
|
-
}
|
|
118
|
-
if (normalizedTask.acceptanceCriteria && normalizedTask.acceptanceCriteria.length > 0) {
|
|
119
|
-
prompt += `### ✅ Critérios de Aceite\n\n`;
|
|
120
|
-
normalizedTask.acceptanceCriteria.forEach((criteria, index) => {
|
|
121
|
-
prompt += `${index + 1}. ${criteria}\n`;
|
|
122
|
-
});
|
|
123
|
-
prompt += `\n`;
|
|
124
|
-
}
|
|
125
|
-
prompt += `---\n\n`;
|
|
126
|
-
prompt += `> Task criada via Task Request Builder MCP App`;
|
|
127
|
-
return {
|
|
128
|
-
structuredContent: {
|
|
129
|
-
task: normalizedTask,
|
|
130
|
-
prompt,
|
|
131
|
-
},
|
|
132
|
-
content: [
|
|
133
|
-
{
|
|
134
|
-
type: "text",
|
|
135
|
-
text: prompt,
|
|
136
|
-
},
|
|
137
|
-
],
|
|
138
|
-
};
|
|
139
|
-
});
|
|
140
|
-
// =============================================================================
|
|
141
|
-
// RECURSO: UI HTML
|
|
142
|
-
// =============================================================================
|
|
143
|
-
registerAppResource(server, resourceUri, resourceUri, { mimeType: RESOURCE_MIME_TYPE }, async () => {
|
|
144
|
-
// Em desenvolvimento, o arquivo pode estar em lugares diferentes
|
|
145
|
-
const possiblePaths = [
|
|
146
|
-
path.join(__dirname, "..", "dist", "mcp-app.html"),
|
|
147
|
-
path.join(process.cwd(), "dist", "mcp-app.html"),
|
|
148
|
-
];
|
|
149
|
-
let html = null;
|
|
150
|
-
for (const filePath of possiblePaths) {
|
|
151
|
-
try {
|
|
152
|
-
html = await fs.readFile(filePath, "utf-8");
|
|
153
|
-
console.error(`✅ UI carregada de: ${filePath}`);
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
catch {
|
|
157
|
-
continue;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
if (!html) {
|
|
161
|
-
console.error("❌ Erro: mcp-app.html não encontrado");
|
|
162
|
-
console.error(" Execute 'npm run build:ui' primeiro");
|
|
163
|
-
html = `
|
|
164
|
-
<!DOCTYPE html>
|
|
165
|
-
<html>
|
|
166
|
-
<head><title>Erro</title></head>
|
|
167
|
-
<body style="font-family: sans-serif; padding: 20px;">
|
|
168
|
-
<h1>⚠️ UI não encontrada</h1>
|
|
169
|
-
<p>Execute <code>npm run build:ui</code> para gerar a interface.</p>
|
|
170
|
-
</body>
|
|
171
|
-
</html>
|
|
172
|
-
`;
|
|
173
|
-
}
|
|
174
|
-
return {
|
|
175
|
-
contents: [
|
|
176
|
-
{
|
|
177
|
-
uri: resourceUri,
|
|
178
|
-
mimeType: RESOURCE_MIME_TYPE,
|
|
179
|
-
text: html,
|
|
180
|
-
},
|
|
181
|
-
],
|
|
182
|
-
};
|
|
183
|
-
});
|
|
184
|
-
// =============================================================================
|
|
185
|
-
// SERVIDOR EXPRESS
|
|
186
|
-
// =============================================================================
|
|
4
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
5
|
+
import { MIN_TASK_DESCRIPTION_LENGTH } from "./shared/task-contract.js";
|
|
6
|
+
import { createTaskRequestServer, PACKAGE_VERSION } from "./mcp-app.js";
|
|
187
7
|
const app = express();
|
|
188
8
|
const PORT = process.env.PORT || 3001;
|
|
189
9
|
const defaultAllowedOrigins = [
|
|
@@ -224,17 +44,18 @@ app.use(cors({
|
|
|
224
44
|
},
|
|
225
45
|
}));
|
|
226
46
|
app.use(express.json({ limit: "1mb" }));
|
|
227
|
-
// Endpoint MCP
|
|
228
47
|
app.post("/mcp", async (req, res) => {
|
|
48
|
+
const server = createTaskRequestServer();
|
|
229
49
|
const transport = new StreamableHTTPServerTransport({
|
|
230
50
|
sessionIdGenerator: undefined,
|
|
231
51
|
enableJsonResponse: true,
|
|
232
52
|
});
|
|
233
|
-
res.on("close", () =>
|
|
53
|
+
res.on("close", () => {
|
|
54
|
+
void transport.close();
|
|
55
|
+
});
|
|
234
56
|
await server.connect(transport);
|
|
235
57
|
await transport.handleRequest(req, res, req.body);
|
|
236
58
|
});
|
|
237
|
-
// Health check
|
|
238
59
|
app.get("/health", (_req, res) => {
|
|
239
60
|
res.json({
|
|
240
61
|
status: "ok",
|
|
@@ -242,15 +63,11 @@ app.get("/health", (_req, res) => {
|
|
|
242
63
|
version: PACKAGE_VERSION,
|
|
243
64
|
});
|
|
244
65
|
});
|
|
245
|
-
// Iniciar servidor
|
|
246
66
|
app.listen(PORT, () => {
|
|
247
67
|
console.error(`\n📋 Task Request MCP App Server v${PACKAGE_VERSION}`);
|
|
248
68
|
console.error(` Endpoint: http://localhost:${PORT}/mcp`);
|
|
249
69
|
console.error(` Health: http://localhost:${PORT}/health\n`);
|
|
250
70
|
console.error(` Allowed Origins: ${Array.from(allowedOrigins).join(", ") || "(sem CORS)"}`);
|
|
251
71
|
console.error(` Min description: ${MIN_TASK_DESCRIPTION_LENGTH} caracteres\n`);
|
|
252
|
-
console.error(`Para testar com Claude:`);
|
|
253
|
-
console.error(` 1. Execute: npx cloudflared tunnel --url http://localhost:${PORT}`);
|
|
254
|
-
console.error(` 2. Adicione a URL gerada como Custom Connector no Claude\n`);
|
|
255
72
|
});
|
|
256
73
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/stdio.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":""}
|
package/dist/stdio.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { createTaskRequestServer, PACKAGE_VERSION } from "./mcp-app.js";
|
|
4
|
+
async function main() {
|
|
5
|
+
const server = createTaskRequestServer();
|
|
6
|
+
const transport = new StdioServerTransport();
|
|
7
|
+
await server.connect(transport);
|
|
8
|
+
}
|
|
9
|
+
void main().catch((error) => {
|
|
10
|
+
const message = error instanceof Error ? error.stack ?? error.message : String(error);
|
|
11
|
+
console.error(`Task Request MCP stdio failed to start (v${PACKAGE_VERSION}): ${message}`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=stdio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAExE,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,uBAAuB,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IACnC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtF,OAAO,CAAC,KAAK,CAAC,4CAA4C,eAAe,MAAM,OAAO,EAAE,CAAC,CAAC;IAC1F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justmpm/task-request",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "MCP App - Task Request Builder com UI interativa para criar tasks estruturadas",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "dist/
|
|
6
|
+
"main": "dist/stdio.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"task-request-mcp": "dist/
|
|
8
|
+
"task-request-mcp": "dist/stdio.js",
|
|
9
|
+
"task-request-mcp-http": "dist/server.js"
|
|
9
10
|
},
|
|
10
11
|
"files": [
|
|
11
12
|
"dist",
|
|
@@ -20,6 +21,7 @@
|
|
|
20
21
|
"build:ui": "vite build",
|
|
21
22
|
"build:server": "tsc",
|
|
22
23
|
"start": "node dist/server.js",
|
|
24
|
+
"start:stdio": "node dist/stdio.js",
|
|
23
25
|
"serve": "npm run build && npm run start",
|
|
24
26
|
"prepublishOnly": "npm run build"
|
|
25
27
|
},
|