@justmpm/task-request 1.0.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.
@@ -0,0 +1,14 @@
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
+ export {};
14
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG"}
package/dist/server.js ADDED
@@ -0,0 +1,256 @@
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
+ import cors from "cors";
17
+ import express from "express";
18
+ import fs from "node:fs/promises";
19
+ import fsSync from "node:fs";
20
+ import path from "node:path";
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
+ // =============================================================================
187
+ const app = express();
188
+ const PORT = process.env.PORT || 3001;
189
+ const defaultAllowedOrigins = [
190
+ "http://localhost:3000",
191
+ "http://127.0.0.1:3000",
192
+ "http://localhost:3001",
193
+ "http://127.0.0.1:3001",
194
+ "http://localhost:8080",
195
+ "http://127.0.0.1:8080",
196
+ ];
197
+ function getAllowedOrigins() {
198
+ const rawOrigins = process.env.MCP_ALLOWED_ORIGINS;
199
+ if (!rawOrigins || rawOrigins.trim() === "") {
200
+ return defaultAllowedOrigins;
201
+ }
202
+ return rawOrigins
203
+ .split(",")
204
+ .map((origin) => origin.trim())
205
+ .filter((origin) => origin.length > 0);
206
+ }
207
+ const allowedOrigins = new Set(getAllowedOrigins());
208
+ function isOriginAllowed(origin) {
209
+ if (!origin) {
210
+ return true;
211
+ }
212
+ if (allowedOrigins.has("*")) {
213
+ return true;
214
+ }
215
+ return allowedOrigins.has(origin);
216
+ }
217
+ app.use(cors({
218
+ origin(origin, callback) {
219
+ if (isOriginAllowed(origin)) {
220
+ callback(null, true);
221
+ return;
222
+ }
223
+ callback(new Error(`Origin não permitida para este MCP: ${origin ?? "desconhecida"}`));
224
+ },
225
+ }));
226
+ app.use(express.json({ limit: "1mb" }));
227
+ // Endpoint MCP
228
+ app.post("/mcp", async (req, res) => {
229
+ const transport = new StreamableHTTPServerTransport({
230
+ sessionIdGenerator: undefined,
231
+ enableJsonResponse: true,
232
+ });
233
+ res.on("close", () => transport.close());
234
+ await server.connect(transport);
235
+ await transport.handleRequest(req, res, req.body);
236
+ });
237
+ // Health check
238
+ app.get("/health", (_req, res) => {
239
+ res.json({
240
+ status: "ok",
241
+ name: "@justmpm/task-request",
242
+ version: PACKAGE_VERSION,
243
+ });
244
+ });
245
+ // Iniciar servidor
246
+ app.listen(PORT, () => {
247
+ console.error(`\n📋 Task Request MCP App Server v${PACKAGE_VERSION}`);
248
+ console.error(` Endpoint: http://localhost:${PORT}/mcp`);
249
+ console.error(` Health: http://localhost:${PORT}/health\n`);
250
+ console.error(` Allowed Origins: ${Array.from(allowedOrigins).join(", ") || "(sem CORS)"}`);
251
+ 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
+ });
256
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ export declare const TASK_TYPE_VALUES: readonly ["implement", "fix", "analyze", "refactor", "test", "document"];
3
+ export declare const TASK_PRIORITY_VALUES: readonly ["urgent", "normal", "low"];
4
+ export declare const MIN_TASK_TITLE_LENGTH = 1;
5
+ export declare const MIN_TASK_DESCRIPTION_LENGTH = 20;
6
+ export declare const taskInputShape: {
7
+ type: z.ZodEnum<["implement", "fix", "analyze", "refactor", "test", "document"]>;
8
+ priority: z.ZodEnum<["urgent", "normal", "low"]>;
9
+ title: z.ZodString;
10
+ description: z.ZodString;
11
+ context: z.ZodOptional<z.ZodString>;
12
+ restrictions: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
13
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
14
+ acceptanceCriteria: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
15
+ };
16
+ export declare const TaskInputSchema: z.ZodObject<{
17
+ type: z.ZodEnum<["implement", "fix", "analyze", "refactor", "test", "document"]>;
18
+ priority: z.ZodEnum<["urgent", "normal", "low"]>;
19
+ title: z.ZodString;
20
+ description: z.ZodString;
21
+ context: z.ZodOptional<z.ZodString>;
22
+ restrictions: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
23
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
24
+ acceptanceCriteria: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
25
+ }, "strip", z.ZodTypeAny, {
26
+ type: "implement" | "fix" | "analyze" | "refactor" | "test" | "document";
27
+ priority: "urgent" | "normal" | "low";
28
+ title: string;
29
+ description: string;
30
+ context?: string | undefined;
31
+ restrictions?: string[] | undefined;
32
+ files?: string[] | undefined;
33
+ acceptanceCriteria?: string[] | undefined;
34
+ }, {
35
+ type: "implement" | "fix" | "analyze" | "refactor" | "test" | "document";
36
+ priority: "urgent" | "normal" | "low";
37
+ title: string;
38
+ description: string;
39
+ context?: string | undefined;
40
+ restrictions?: string[] | undefined;
41
+ files?: string[] | undefined;
42
+ acceptanceCriteria?: string[] | undefined;
43
+ }>;
44
+ export type TaskInput = z.infer<typeof TaskInputSchema>;
45
+ //# sourceMappingURL=task-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-contract.d.ts","sourceRoot":"","sources":["../../src/shared/task-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB,0EAOnB,CAAC;AAEX,eAAO,MAAM,oBAAoB,sCAAuC,CAAC;AAEzE,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,eAAO,MAAM,cAAc;;;;;;;;;CAgBF,CAAC;AAE1B,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA2B,CAAC;AAExD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { z } from "zod";
2
+ export const TASK_TYPE_VALUES = [
3
+ "implement",
4
+ "fix",
5
+ "analyze",
6
+ "refactor",
7
+ "test",
8
+ "document",
9
+ ];
10
+ export const TASK_PRIORITY_VALUES = ["urgent", "normal", "low"];
11
+ export const MIN_TASK_TITLE_LENGTH = 1;
12
+ export const MIN_TASK_DESCRIPTION_LENGTH = 20;
13
+ export const taskInputShape = {
14
+ type: z.enum(TASK_TYPE_VALUES),
15
+ priority: z.enum(TASK_PRIORITY_VALUES),
16
+ title: z.string().trim().min(MIN_TASK_TITLE_LENGTH).describe("Titulo resumido da task"),
17
+ description: z
18
+ .string()
19
+ .trim()
20
+ .min(MIN_TASK_DESCRIPTION_LENGTH)
21
+ .describe("Descricao detalhada do que precisa ser feito"),
22
+ context: z.string().trim().optional().describe("Contexto adicional: arquivos, prints, URLs, codigo"),
23
+ restrictions: z.array(z.string().trim().min(1)).optional().describe("Lista de restricoes"),
24
+ files: z.array(z.string().trim().min(1)).optional().describe("Arquivos relacionados"),
25
+ acceptanceCriteria: z
26
+ .array(z.string().trim().min(1))
27
+ .optional()
28
+ .describe("Critérios de aceite"),
29
+ };
30
+ export const TaskInputSchema = z.object(taskInputShape);
31
+ //# sourceMappingURL=task-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-contract.js","sourceRoot":"","sources":["../../src/shared/task-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,WAAW;IACX,KAAK;IACL,SAAS;IACT,UAAU;IACV,MAAM;IACN,UAAU;CACF,CAAC;AAEX,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAU,CAAC;AAEzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AACvC,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAE9C,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC;IAC9B,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IACvF,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,IAAI,EAAE;SACN,GAAG,CAAC,2BAA2B,CAAC;SAChC,QAAQ,CAAC,8CAA8C,CAAC;IAC3D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;IACpG,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IAC1F,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;IACrF,kBAAkB,EAAE,CAAC;SAClB,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAC/B,QAAQ,EAAE;SACV,QAAQ,CAAC,qBAAqB,CAAC;CACX,CAAC;AAE1B,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@justmpm/task-request",
3
+ "version": "1.0.0",
4
+ "description": "MCP App - Task Request Builder com UI interativa para criar tasks estruturadas",
5
+ "type": "module",
6
+ "main": "dist/server.js",
7
+ "bin": {
8
+ "task-request-mcp": "dist/server.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "dev": "concurrently \"npm run dev:server\" \"npm run dev:ui:watch\"",
16
+ "dev:server": "tsx watch src/server.ts",
17
+ "dev:ui": "vite",
18
+ "dev:ui:watch": "vite build --watch",
19
+ "build": "npm run build:ui && npm run build:server",
20
+ "build:ui": "vite build",
21
+ "build:server": "tsc",
22
+ "start": "node dist/server.js",
23
+ "serve": "npm run build && npm run start",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "keywords": [
27
+ "mcp",
28
+ "mcp-app",
29
+ "task",
30
+ "request",
31
+ "builder",
32
+ "form"
33
+ ],
34
+ "author": "Koda AI Studio",
35
+ "license": "MIT",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/Just-mpm/task-request-mcp"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "dependencies": {
44
+ "@emotion/react": "^11.14.0",
45
+ "@emotion/styled": "^11.14.1",
46
+ "@modelcontextprotocol/ext-apps": "^1.2.2",
47
+ "@modelcontextprotocol/sdk": "^1.27.1",
48
+ "@mui/icons-material": "^7.0.2",
49
+ "@mui/material": "^7.0.2",
50
+ "cors": "^2.8.5",
51
+ "express": "^5.1.0",
52
+ "react": "^19.1.0",
53
+ "react-dom": "^19.1.0",
54
+ "zod": "^3.24.2"
55
+ },
56
+ "devDependencies": {
57
+ "@types/cors": "^2.8.17",
58
+ "@types/express": "^5.0.1",
59
+ "@types/node": "^22.14.0",
60
+ "@types/react": "^19.1.2",
61
+ "@types/react-dom": "^19.1.3",
62
+ "@vitejs/plugin-react": "^4.4.0",
63
+ "concurrently": "^9.1.2",
64
+ "tsx": "^4.19.3",
65
+ "typescript": "^5.8.3",
66
+ "vite": "^6.2.5",
67
+ "vite-plugin-singlefile": "^2.2.0"
68
+ },
69
+ "engines": {
70
+ "node": ">=22"
71
+ }
72
+ }