@trace.market/types 0.1.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/.github/workflows/build-mcp.yml +36 -0
- package/.github/workflows/publish.yml +72 -0
- package/IMPLEMENTATION.md +199 -0
- package/QUICKSTART.md +238 -0
- package/README.md +144 -0
- package/mcp-config.example.json +13 -0
- package/mcp-server/.env.example +9 -0
- package/mcp-server/README.md +151 -0
- package/mcp-server/generate-token.js +61 -0
- package/mcp-server/package-lock.json +1206 -0
- package/mcp-server/package.json +26 -0
- package/mcp-server/src/index.ts +516 -0
- package/package.json +31 -0
- package/src/ENov +261 -0
- package/src/index.d.ts +187 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trace.market/types-mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for managing Trace Market type definitions",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"tm-types-mcp": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"start": "node dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
17
|
+
"zod": "^3.23.8",
|
|
18
|
+
"typescript": "^5.3.3",
|
|
19
|
+
"jsonwebtoken": "^9.0.2",
|
|
20
|
+
"dotenv": "^16.4.5"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^22.10.2",
|
|
24
|
+
"@types/jsonwebtoken": "^9.0.7"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import {
|
|
6
|
+
CallToolRequestSchema,
|
|
7
|
+
ListToolsRequestSchema,
|
|
8
|
+
Tool,
|
|
9
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
12
|
+
import { join, dirname } from "path";
|
|
13
|
+
import { fileURLToPath } from "url";
|
|
14
|
+
import jwt from "jsonwebtoken";
|
|
15
|
+
import * as dotenv from "dotenv";
|
|
16
|
+
|
|
17
|
+
dotenv.config();
|
|
18
|
+
|
|
19
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
20
|
+
const __dirname = dirname(__filename);
|
|
21
|
+
|
|
22
|
+
// Path to types definition file
|
|
23
|
+
const TYPES_PATH = join(__dirname, "../../../src/index.d.ts");
|
|
24
|
+
const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key-change-in-production";
|
|
25
|
+
|
|
26
|
+
interface AuthContext {
|
|
27
|
+
userId?: string;
|
|
28
|
+
role?: "admin" | "user" | "anonymous";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Authentication helper
|
|
32
|
+
function verifyAuth(token?: string): AuthContext {
|
|
33
|
+
if (!token) {
|
|
34
|
+
return { role: "anonymous" };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const decoded = jwt.verify(token, JWT_SECRET) as any;
|
|
39
|
+
return {
|
|
40
|
+
userId: decoded.userId,
|
|
41
|
+
role: decoded.role || "user",
|
|
42
|
+
};
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return { role: "anonymous" };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Read current types
|
|
49
|
+
function readTypes(): string {
|
|
50
|
+
if (!existsSync(TYPES_PATH)) {
|
|
51
|
+
throw new Error("Types file not found");
|
|
52
|
+
}
|
|
53
|
+
return readFileSync(TYPES_PATH, "utf-8");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Write types (only for authenticated users)
|
|
57
|
+
function writeTypes(content: string, auth: AuthContext): void {
|
|
58
|
+
if (auth.role === "anonymous") {
|
|
59
|
+
throw new Error("Authentication required to modify types");
|
|
60
|
+
}
|
|
61
|
+
writeFileSync(TYPES_PATH, content, "utf-8");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Parse type definition to extract metadata
|
|
65
|
+
function parseTypeDefinitions(content: string) {
|
|
66
|
+
const interfacePattern = /export\s+interface\s+(\w+)(?:\s+extends\s+(\w+))?\s*\{([^}]+)\}/g;
|
|
67
|
+
const typePattern = /export\s+type\s+(\w+)\s*=\s*([^;]+);/g;
|
|
68
|
+
|
|
69
|
+
const interfaces: any[] = [];
|
|
70
|
+
const types: any[] = [];
|
|
71
|
+
|
|
72
|
+
let match;
|
|
73
|
+
while ((match = interfacePattern.exec(content)) !== null) {
|
|
74
|
+
const [, name, extendsFrom, body] = match;
|
|
75
|
+
const fields = body
|
|
76
|
+
.split("\n")
|
|
77
|
+
.map((line) => line.trim())
|
|
78
|
+
.filter((line) => line && !line.startsWith("//") && !line.startsWith("/*"))
|
|
79
|
+
.map((line) => {
|
|
80
|
+
const fieldMatch = line.match(/(\w+)(\?)?:\s*([^;]+);?/);
|
|
81
|
+
if (fieldMatch) {
|
|
82
|
+
const [, fieldName, optional, fieldType] = fieldMatch;
|
|
83
|
+
return {
|
|
84
|
+
name: fieldName,
|
|
85
|
+
type: fieldType.trim(),
|
|
86
|
+
optional: !!optional,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
})
|
|
91
|
+
.filter(Boolean);
|
|
92
|
+
|
|
93
|
+
interfaces.push({
|
|
94
|
+
kind: "interface",
|
|
95
|
+
name,
|
|
96
|
+
extends: extendsFrom || null,
|
|
97
|
+
fields,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
while ((match = typePattern.exec(content)) !== null) {
|
|
102
|
+
const [, name, definition] = match;
|
|
103
|
+
types.push({
|
|
104
|
+
kind: "type",
|
|
105
|
+
name,
|
|
106
|
+
definition: definition.trim(),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return { interfaces, types };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Generate TypeScript type from natural language
|
|
114
|
+
async function generateTypeFromNL(description: string, existingTypes: string): Promise<string> {
|
|
115
|
+
// This is a simplified version - in production, you'd use an LLM API
|
|
116
|
+
// For now, we'll return a template that needs to be filled
|
|
117
|
+
const typeName = description
|
|
118
|
+
.split(" ")
|
|
119
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
120
|
+
.join("")
|
|
121
|
+
.replace(/[^a-zA-Z0-9]/g, "");
|
|
122
|
+
|
|
123
|
+
return `
|
|
124
|
+
// Generated from: ${description}
|
|
125
|
+
export interface ${typeName} {
|
|
126
|
+
// TODO: Fill in fields based on description
|
|
127
|
+
id: string;
|
|
128
|
+
createdAt: number;
|
|
129
|
+
}
|
|
130
|
+
`.trim();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Define MCP tools
|
|
134
|
+
const tools: Tool[] = [
|
|
135
|
+
{
|
|
136
|
+
name: "list_types",
|
|
137
|
+
description: "List all available type definitions (interfaces and types). No authentication required.",
|
|
138
|
+
inputSchema: {
|
|
139
|
+
type: "object",
|
|
140
|
+
properties: {
|
|
141
|
+
filter: {
|
|
142
|
+
type: "string",
|
|
143
|
+
description: "Optional filter to search type names",
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: "get_type_definition",
|
|
150
|
+
description: "Get detailed definition of a specific type. No authentication required.",
|
|
151
|
+
inputSchema: {
|
|
152
|
+
type: "object",
|
|
153
|
+
properties: {
|
|
154
|
+
typeName: {
|
|
155
|
+
type: "string",
|
|
156
|
+
description: "Name of the type to retrieve",
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
required: ["typeName"],
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: "validate_data",
|
|
164
|
+
description: "Validate data against a type definition. No authentication required.",
|
|
165
|
+
inputSchema: {
|
|
166
|
+
type: "object",
|
|
167
|
+
properties: {
|
|
168
|
+
typeName: {
|
|
169
|
+
type: "string",
|
|
170
|
+
description: "Name of the type to validate against",
|
|
171
|
+
},
|
|
172
|
+
data: {
|
|
173
|
+
type: "object",
|
|
174
|
+
description: "Data object to validate",
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
required: ["typeName", "data"],
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: "create_type_from_description",
|
|
182
|
+
description: "Create a new type definition from a natural language description. Requires authentication (admin or user role).",
|
|
183
|
+
inputSchema: {
|
|
184
|
+
type: "object",
|
|
185
|
+
properties: {
|
|
186
|
+
description: {
|
|
187
|
+
type: "string",
|
|
188
|
+
description: "Natural language description of the type to create",
|
|
189
|
+
},
|
|
190
|
+
authToken: {
|
|
191
|
+
type: "string",
|
|
192
|
+
description: "JWT authentication token",
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
required: ["description", "authToken"],
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: "add_type_definition",
|
|
200
|
+
description: "Add a new type definition (TypeScript code). Requires authentication (admin or user role).",
|
|
201
|
+
inputSchema: {
|
|
202
|
+
type: "object",
|
|
203
|
+
properties: {
|
|
204
|
+
typeDefinition: {
|
|
205
|
+
type: "string",
|
|
206
|
+
description: "TypeScript type definition to add",
|
|
207
|
+
},
|
|
208
|
+
authToken: {
|
|
209
|
+
type: "string",
|
|
210
|
+
description: "JWT authentication token",
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
required: ["typeDefinition", "authToken"],
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: "query_data",
|
|
218
|
+
description: "Query and filter data based on type structure. No authentication required.",
|
|
219
|
+
inputSchema: {
|
|
220
|
+
type: "object",
|
|
221
|
+
properties: {
|
|
222
|
+
typeName: {
|
|
223
|
+
type: "string",
|
|
224
|
+
description: "Type to query",
|
|
225
|
+
},
|
|
226
|
+
query: {
|
|
227
|
+
type: "object",
|
|
228
|
+
description: "Query filters (field: value pairs)",
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
required: ["typeName"],
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: "generate_report",
|
|
236
|
+
description: "Generate a custom report from type data. No authentication required.",
|
|
237
|
+
inputSchema: {
|
|
238
|
+
type: "object",
|
|
239
|
+
properties: {
|
|
240
|
+
reportType: {
|
|
241
|
+
type: "string",
|
|
242
|
+
description: "Type of report to generate (e.g., 'summary', 'detailed', 'impact')",
|
|
243
|
+
},
|
|
244
|
+
data: {
|
|
245
|
+
type: "object",
|
|
246
|
+
description: "Data to include in report",
|
|
247
|
+
},
|
|
248
|
+
format: {
|
|
249
|
+
type: "string",
|
|
250
|
+
enum: ["json", "markdown", "html"],
|
|
251
|
+
description: "Output format",
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
required: ["reportType", "data"],
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
];
|
|
258
|
+
|
|
259
|
+
// Create server instance
|
|
260
|
+
const server = new Server(
|
|
261
|
+
{
|
|
262
|
+
name: "tm-types-mcp-server",
|
|
263
|
+
version: "0.1.0",
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
capabilities: {
|
|
267
|
+
tools: {},
|
|
268
|
+
},
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
// List tools handler
|
|
273
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
274
|
+
return { tools };
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Call tool handler
|
|
278
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
279
|
+
const { name, arguments: args } = request.params;
|
|
280
|
+
|
|
281
|
+
try {
|
|
282
|
+
switch (name) {
|
|
283
|
+
case "list_types": {
|
|
284
|
+
const content = readTypes();
|
|
285
|
+
const { interfaces, types } = parseTypeDefinitions(content);
|
|
286
|
+
const filter = (args as any).filter?.toLowerCase();
|
|
287
|
+
|
|
288
|
+
const filteredInterfaces = filter
|
|
289
|
+
? interfaces.filter((i) => i.name.toLowerCase().includes(filter))
|
|
290
|
+
: interfaces;
|
|
291
|
+
const filteredTypes = filter
|
|
292
|
+
? types.filter((t) => t.name.toLowerCase().includes(filter))
|
|
293
|
+
: types;
|
|
294
|
+
|
|
295
|
+
return {
|
|
296
|
+
content: [
|
|
297
|
+
{
|
|
298
|
+
type: "text",
|
|
299
|
+
text: JSON.stringify(
|
|
300
|
+
{
|
|
301
|
+
interfaces: filteredInterfaces.map((i) => ({
|
|
302
|
+
name: i.name,
|
|
303
|
+
extends: i.extends,
|
|
304
|
+
fieldCount: i.fields.length,
|
|
305
|
+
})),
|
|
306
|
+
types: filteredTypes.map((t) => ({
|
|
307
|
+
name: t.name,
|
|
308
|
+
definition: t.definition,
|
|
309
|
+
})),
|
|
310
|
+
},
|
|
311
|
+
null,
|
|
312
|
+
2
|
|
313
|
+
),
|
|
314
|
+
},
|
|
315
|
+
],
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
case "get_type_definition": {
|
|
320
|
+
const { typeName } = args as any;
|
|
321
|
+
const content = readTypes();
|
|
322
|
+
const { interfaces, types } = parseTypeDefinitions(content);
|
|
323
|
+
|
|
324
|
+
const interfaceDef = interfaces.find((i) => i.name === typeName);
|
|
325
|
+
const typeDef = types.find((t) => t.name === typeName);
|
|
326
|
+
|
|
327
|
+
if (!interfaceDef && !typeDef) {
|
|
328
|
+
return {
|
|
329
|
+
content: [
|
|
330
|
+
{
|
|
331
|
+
type: "text",
|
|
332
|
+
text: JSON.stringify({ error: `Type '${typeName}' not found` }),
|
|
333
|
+
},
|
|
334
|
+
],
|
|
335
|
+
isError: true,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return {
|
|
340
|
+
content: [
|
|
341
|
+
{
|
|
342
|
+
type: "text",
|
|
343
|
+
text: JSON.stringify(interfaceDef || typeDef, null, 2),
|
|
344
|
+
},
|
|
345
|
+
],
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
case "validate_data": {
|
|
350
|
+
const { typeName, data } = args as any;
|
|
351
|
+
const content = readTypes();
|
|
352
|
+
const { interfaces } = parseTypeDefinitions(content);
|
|
353
|
+
|
|
354
|
+
const typeDef = interfaces.find((i) => i.name === typeName);
|
|
355
|
+
if (!typeDef) {
|
|
356
|
+
return {
|
|
357
|
+
content: [
|
|
358
|
+
{
|
|
359
|
+
type: "text",
|
|
360
|
+
text: JSON.stringify({ error: `Type '${typeName}' not found` }),
|
|
361
|
+
},
|
|
362
|
+
],
|
|
363
|
+
isError: true,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Simple validation - check required fields
|
|
368
|
+
const errors: string[] = [];
|
|
369
|
+
for (const field of typeDef.fields) {
|
|
370
|
+
if (!field.optional && !(field.name in data)) {
|
|
371
|
+
errors.push(`Missing required field: ${field.name}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return {
|
|
376
|
+
content: [
|
|
377
|
+
{
|
|
378
|
+
type: "text",
|
|
379
|
+
text: JSON.stringify({
|
|
380
|
+
valid: errors.length === 0,
|
|
381
|
+
errors,
|
|
382
|
+
typeName,
|
|
383
|
+
}, null, 2),
|
|
384
|
+
},
|
|
385
|
+
],
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
case "create_type_from_description": {
|
|
390
|
+
const { description, authToken } = args as any;
|
|
391
|
+
const auth = verifyAuth(authToken);
|
|
392
|
+
|
|
393
|
+
if (auth.role === "anonymous") {
|
|
394
|
+
return {
|
|
395
|
+
content: [
|
|
396
|
+
{
|
|
397
|
+
type: "text",
|
|
398
|
+
text: JSON.stringify({ error: "Authentication required" }),
|
|
399
|
+
},
|
|
400
|
+
],
|
|
401
|
+
isError: true,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const content = readTypes();
|
|
406
|
+
const newType = await generateTypeFromNL(description, content);
|
|
407
|
+
|
|
408
|
+
return {
|
|
409
|
+
content: [
|
|
410
|
+
{
|
|
411
|
+
type: "text",
|
|
412
|
+
text: JSON.stringify({
|
|
413
|
+
message: "Type generated successfully. Review and use 'add_type_definition' to add it.",
|
|
414
|
+
generatedType: newType,
|
|
415
|
+
}, null, 2),
|
|
416
|
+
},
|
|
417
|
+
],
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
case "add_type_definition": {
|
|
422
|
+
const { typeDefinition, authToken } = args as any;
|
|
423
|
+
const auth = verifyAuth(authToken);
|
|
424
|
+
|
|
425
|
+
const content = readTypes();
|
|
426
|
+
const newContent = `${content}\n\n${typeDefinition}\n`;
|
|
427
|
+
writeTypes(newContent, auth);
|
|
428
|
+
|
|
429
|
+
return {
|
|
430
|
+
content: [
|
|
431
|
+
{
|
|
432
|
+
type: "text",
|
|
433
|
+
text: JSON.stringify({
|
|
434
|
+
message: "Type definition added successfully",
|
|
435
|
+
userId: auth.userId,
|
|
436
|
+
}),
|
|
437
|
+
},
|
|
438
|
+
],
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
case "query_data": {
|
|
443
|
+
const { typeName, query } = args as any;
|
|
444
|
+
// This would integrate with your actual data storage
|
|
445
|
+
return {
|
|
446
|
+
content: [
|
|
447
|
+
{
|
|
448
|
+
type: "text",
|
|
449
|
+
text: JSON.stringify({
|
|
450
|
+
message: "Query functionality - integrate with your data store",
|
|
451
|
+
typeName,
|
|
452
|
+
query,
|
|
453
|
+
}, null, 2),
|
|
454
|
+
},
|
|
455
|
+
],
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
case "generate_report": {
|
|
460
|
+
const { reportType, data, format = "json" } = args as any;
|
|
461
|
+
|
|
462
|
+
// Simple report generation
|
|
463
|
+
let report: string;
|
|
464
|
+
if (format === "markdown") {
|
|
465
|
+
report = `# ${reportType.toUpperCase()} Report\n\n${JSON.stringify(data, null, 2)}`;
|
|
466
|
+
} else if (format === "html") {
|
|
467
|
+
report = `<html><body><h1>${reportType} Report</h1><pre>${JSON.stringify(data, null, 2)}</pre></body></html>`;
|
|
468
|
+
} else {
|
|
469
|
+
report = JSON.stringify({ reportType, data }, null, 2);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
return {
|
|
473
|
+
content: [
|
|
474
|
+
{
|
|
475
|
+
type: "text",
|
|
476
|
+
text: report,
|
|
477
|
+
},
|
|
478
|
+
],
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
default:
|
|
483
|
+
return {
|
|
484
|
+
content: [
|
|
485
|
+
{
|
|
486
|
+
type: "text",
|
|
487
|
+
text: JSON.stringify({ error: `Unknown tool: ${name}` }),
|
|
488
|
+
},
|
|
489
|
+
],
|
|
490
|
+
isError: true,
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
} catch (error: any) {
|
|
494
|
+
return {
|
|
495
|
+
content: [
|
|
496
|
+
{
|
|
497
|
+
type: "text",
|
|
498
|
+
text: JSON.stringify({ error: error.message }),
|
|
499
|
+
},
|
|
500
|
+
],
|
|
501
|
+
isError: true,
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
// Start server
|
|
507
|
+
async function main() {
|
|
508
|
+
const transport = new StdioServerTransport();
|
|
509
|
+
await server.connect(transport);
|
|
510
|
+
console.error("Trace Market Types MCP Server running on stdio");
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
main().catch((error) => {
|
|
514
|
+
console.error("Fatal error:", error);
|
|
515
|
+
process.exit(1);
|
|
516
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trace.market/types",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript type definitions for Trace Market food supply chain data",
|
|
5
|
+
"author": "Trace Market Team",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"types": "src/index.d.ts",
|
|
8
|
+
"main": "src/index.d.ts",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/entin-hun/tm-types.git"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"typescript",
|
|
15
|
+
"types",
|
|
16
|
+
"food",
|
|
17
|
+
"supply-chain",
|
|
18
|
+
"traceability",
|
|
19
|
+
"blockchain"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"prepublishOnly": "npm run validate",
|
|
23
|
+
"validate": "tsc --noEmit",
|
|
24
|
+
"version": "git add -A",
|
|
25
|
+
"postversion": "git push && git push --tags"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/geojson": "^7946.0.11",
|
|
29
|
+
"typescript": "^5.3.3"
|
|
30
|
+
}
|
|
31
|
+
}
|