@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.
- package/README.md +204 -0
- package/dist/mcp-app.html +352 -0
- package/dist/server.d.ts +14 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +256 -0
- package/dist/server.js.map +1 -0
- package/dist/shared/task-contract.d.ts +45 -0
- package/dist/shared/task-contract.d.ts.map +1 -0
- package/dist/shared/task-contract.js +31 -0
- package/dist/shared/task-contract.js.map +1 -0
- package/package.json +72 -0
package/dist/server.d.ts
ADDED
|
@@ -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
|
+
}
|