@tekton-ui/mcp-server 0.3.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/LICENSE +21 -0
- package/README.md +980 -0
- package/dist/auth/cache.d.ts +28 -0
- package/dist/auth/cache.d.ts.map +1 -0
- package/dist/auth/cache.js +48 -0
- package/dist/auth/cache.js.map +1 -0
- package/dist/auth/guard.d.ts +13 -0
- package/dist/auth/guard.d.ts.map +1 -0
- package/dist/auth/guard.js +21 -0
- package/dist/auth/guard.js.map +1 -0
- package/dist/auth/state.d.ts +32 -0
- package/dist/auth/state.d.ts.map +1 -0
- package/dist/auth/state.js +72 -0
- package/dist/auth/state.js.map +1 -0
- package/dist/auth/theme-access.d.ts +10 -0
- package/dist/auth/theme-access.d.ts.map +1 -0
- package/dist/auth/theme-access.js +24 -0
- package/dist/auth/theme-access.js.map +1 -0
- package/dist/auth/verify.d.ts +44 -0
- package/dist/auth/verify.d.ts.map +1 -0
- package/dist/auth/verify.js +77 -0
- package/dist/auth/verify.js.map +1 -0
- package/dist/cli/credentials.d.ts +29 -0
- package/dist/cli/credentials.d.ts.map +1 -0
- package/dist/cli/credentials.js +66 -0
- package/dist/cli/credentials.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +36 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/login.d.ts +9 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/login.js +120 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/logout.d.ts +9 -0
- package/dist/cli/logout.d.ts.map +1 -0
- package/dist/cli/logout.js +18 -0
- package/dist/cli/logout.js.map +1 -0
- package/dist/cli/status.d.ts +9 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +31 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/data/component-registry.d.ts +30 -0
- package/dist/data/component-registry.d.ts.map +1 -0
- package/dist/data/component-registry.js +320 -0
- package/dist/data/component-registry.js.map +1 -0
- package/dist/data/examples/screen-examples.d.ts +38 -0
- package/dist/data/examples/screen-examples.d.ts.map +1 -0
- package/dist/data/examples/screen-examples.js +500 -0
- package/dist/data/examples/screen-examples.js.map +1 -0
- package/dist/data/hint-generator.d.ts +16 -0
- package/dist/data/hint-generator.d.ts.map +1 -0
- package/dist/data/hint-generator.js +298 -0
- package/dist/data/hint-generator.js.map +1 -0
- package/dist/data/recipe-resolver.d.ts +48 -0
- package/dist/data/recipe-resolver.d.ts.map +1 -0
- package/dist/data/recipe-resolver.js +226 -0
- package/dist/data/recipe-resolver.js.map +1 -0
- package/dist/data/template-matcher.d.ts +50 -0
- package/dist/data/template-matcher.d.ts.map +1 -0
- package/dist/data/template-matcher.js +240 -0
- package/dist/data/template-matcher.js.map +1 -0
- package/dist/generators/core-resolver.d.ts +56 -0
- package/dist/generators/core-resolver.d.ts.map +1 -0
- package/dist/generators/core-resolver.js +490 -0
- package/dist/generators/core-resolver.js.map +1 -0
- package/dist/generators/css-generator.d.ts +49 -0
- package/dist/generators/css-generator.d.ts.map +1 -0
- package/dist/generators/css-generator.js +294 -0
- package/dist/generators/css-generator.js.map +1 -0
- package/dist/generators/index.d.ts +13 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +16 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/llm-generator.d.ts +96 -0
- package/dist/generators/llm-generator.d.ts.map +1 -0
- package/dist/generators/llm-generator.js +296 -0
- package/dist/generators/llm-generator.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +818 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/mcp-schemas.d.ts +4132 -0
- package/dist/schemas/mcp-schemas.d.ts.map +1 -0
- package/dist/schemas/mcp-schemas.js +946 -0
- package/dist/schemas/mcp-schemas.js.map +1 -0
- package/dist/storage/blueprint-storage.d.ts +68 -0
- package/dist/storage/blueprint-storage.d.ts.map +1 -0
- package/dist/storage/blueprint-storage.js +135 -0
- package/dist/storage/blueprint-storage.js.map +1 -0
- package/dist/storage/timestamp-manager.d.ts +32 -0
- package/dist/storage/timestamp-manager.d.ts.map +1 -0
- package/dist/storage/timestamp-manager.js +59 -0
- package/dist/storage/timestamp-manager.js.map +1 -0
- package/dist/tools/export-screen.d.ts +34 -0
- package/dist/tools/export-screen.d.ts.map +1 -0
- package/dist/tools/export-screen.js +344 -0
- package/dist/tools/export-screen.js.map +1 -0
- package/dist/tools/generate-blueprint.d.ts +15 -0
- package/dist/tools/generate-blueprint.d.ts.map +1 -0
- package/dist/tools/generate-blueprint.js +165 -0
- package/dist/tools/generate-blueprint.js.map +1 -0
- package/dist/tools/generate-screen.d.ts +13 -0
- package/dist/tools/generate-screen.d.ts.map +1 -0
- package/dist/tools/generate-screen.js +82 -0
- package/dist/tools/generate-screen.js.map +1 -0
- package/dist/tools/get-screen-generation-context.d.ts +11 -0
- package/dist/tools/get-screen-generation-context.d.ts.map +1 -0
- package/dist/tools/get-screen-generation-context.js +316 -0
- package/dist/tools/get-screen-generation-context.js.map +1 -0
- package/dist/tools/list-components.d.ts +15 -0
- package/dist/tools/list-components.d.ts.map +1 -0
- package/dist/tools/list-components.js +46 -0
- package/dist/tools/list-components.js.map +1 -0
- package/dist/tools/list-icon-libraries.d.ts +12 -0
- package/dist/tools/list-icon-libraries.d.ts.map +1 -0
- package/dist/tools/list-icon-libraries.js +48 -0
- package/dist/tools/list-icon-libraries.js.map +1 -0
- package/dist/tools/list-screen-templates.d.ts +15 -0
- package/dist/tools/list-screen-templates.d.ts.map +1 -0
- package/dist/tools/list-screen-templates.js +63 -0
- package/dist/tools/list-screen-templates.js.map +1 -0
- package/dist/tools/list-themes.d.ts +13 -0
- package/dist/tools/list-themes.d.ts.map +1 -0
- package/dist/tools/list-themes.js +42 -0
- package/dist/tools/list-themes.js.map +1 -0
- package/dist/tools/list-tokens.d.ts +13 -0
- package/dist/tools/list-tokens.d.ts.map +1 -0
- package/dist/tools/list-tokens.js +92 -0
- package/dist/tools/list-tokens.js.map +1 -0
- package/dist/tools/preview-component.d.ts +18 -0
- package/dist/tools/preview-component.d.ts.map +1 -0
- package/dist/tools/preview-component.js +178 -0
- package/dist/tools/preview-component.js.map +1 -0
- package/dist/tools/preview-icon-library.d.ts +13 -0
- package/dist/tools/preview-icon-library.d.ts.map +1 -0
- package/dist/tools/preview-icon-library.js +63 -0
- package/dist/tools/preview-icon-library.js.map +1 -0
- package/dist/tools/preview-screen-template.d.ts +18 -0
- package/dist/tools/preview-screen-template.d.ts.map +1 -0
- package/dist/tools/preview-screen-template.js +101 -0
- package/dist/tools/preview-screen-template.js.map +1 -0
- package/dist/tools/preview-theme.d.ts +15 -0
- package/dist/tools/preview-theme.d.ts.map +1 -0
- package/dist/tools/preview-theme.js +71 -0
- package/dist/tools/preview-theme.js.map +1 -0
- package/dist/tools/validate-environment.d.ts +37 -0
- package/dist/tools/validate-environment.d.ts.map +1 -0
- package/dist/tools/validate-environment.js +153 -0
- package/dist/tools/validate-environment.js.map +1 -0
- package/dist/tools/validate-screen-definition.d.ts +10 -0
- package/dist/tools/validate-screen-definition.d.ts.map +1 -0
- package/dist/tools/validate-screen-definition.js +463 -0
- package/dist/tools/validate-screen-definition.js.map +1 -0
- package/dist/tools/validate-screen.d.ts +13 -0
- package/dist/tools/validate-screen.d.ts.map +1 -0
- package/dist/tools/validate-screen.js +106 -0
- package/dist/tools/validate-screen.js.map +1 -0
- package/dist/utils/dependency-extractor.d.ts +13 -0
- package/dist/utils/dependency-extractor.d.ts.map +1 -0
- package/dist/utils/dependency-extractor.js +232 -0
- package/dist/utils/dependency-extractor.js.map +1 -0
- package/dist/utils/error-handler.d.ts +29 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +48 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +14 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/package-json-reader.d.ts +37 -0
- package/dist/utils/package-json-reader.d.ts.map +1 -0
- package/dist/utils/package-json-reader.js +108 -0
- package/dist/utils/package-json-reader.js.map +1 -0
- package/dist/utils/tailwind-config-reader.d.ts +23 -0
- package/dist/utils/tailwind-config-reader.d.ts.map +1 -0
- package/dist/utils/tailwind-config-reader.js +81 -0
- package/dist/utils/tailwind-config-reader.js.map +1 -0
- package/package.json +72 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,818 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { info, error as logError } from './utils/logger.js';
|
|
6
|
+
import { verifyApiKey } from './auth/verify.js';
|
|
7
|
+
import { setAuthData } from './auth/state.js';
|
|
8
|
+
import { AuthRequiredError, requireAuth } from './auth/guard.js';
|
|
9
|
+
import { loadCredentials } from './cli/credentials.js';
|
|
10
|
+
import { generateBlueprintTool } from './tools/generate-blueprint.js';
|
|
11
|
+
import { previewThemeTool } from './tools/preview-theme.js';
|
|
12
|
+
import { listThemesTool } from './tools/list-themes.js';
|
|
13
|
+
import { exportScreenTool } from './tools/export-screen.js';
|
|
14
|
+
import { generateScreenTool } from './tools/generate-screen.js';
|
|
15
|
+
import { validateScreenTool } from './tools/validate-screen.js';
|
|
16
|
+
import { listTokensTool } from './tools/list-tokens.js';
|
|
17
|
+
import { listIconLibrariesTool } from './tools/list-icon-libraries.js';
|
|
18
|
+
import { previewIconLibraryTool } from './tools/preview-icon-library.js';
|
|
19
|
+
import { listComponentsTool } from './tools/list-components.js';
|
|
20
|
+
import { previewComponentTool } from './tools/preview-component.js';
|
|
21
|
+
import { listScreenTemplatesTool } from './tools/list-screen-templates.js';
|
|
22
|
+
import { previewScreenTemplateTool } from './tools/preview-screen-template.js';
|
|
23
|
+
import { getScreenGenerationContextTool } from './tools/get-screen-generation-context.js';
|
|
24
|
+
import { validateScreenDefinitionTool } from './tools/validate-screen-definition.js';
|
|
25
|
+
import { validateEnvironmentTool } from './tools/validate-environment.js';
|
|
26
|
+
import { GenerateBlueprintInputSchema, PreviewThemeInputSchema, ListThemesInputSchema, ExportScreenInputSchema, GenerateScreenInputSchema, ValidateScreenInputSchema, ListTokensInputSchema, ListIconLibrariesInputSchema, PreviewIconLibraryInputSchema, ListComponentsInputSchema, PreviewComponentInputSchema, ListScreenTemplatesInputSchema, PreviewScreenTemplateInputSchema, GetScreenGenerationContextInputSchema, ValidateScreenDefinitionInputSchema, ValidateEnvironmentInputSchema, } from './schemas/mcp-schemas.js';
|
|
27
|
+
const server = new Server({
|
|
28
|
+
name: 'tekton-mcp-server',
|
|
29
|
+
version: '2.1.0',
|
|
30
|
+
}, {
|
|
31
|
+
capabilities: {
|
|
32
|
+
tools: {},
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// Task #9: ListToolsRequestSchema Handler
|
|
37
|
+
// ============================================================================
|
|
38
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
39
|
+
info('ListTools request received');
|
|
40
|
+
return {
|
|
41
|
+
tools: [
|
|
42
|
+
{
|
|
43
|
+
name: 'generate-blueprint',
|
|
44
|
+
description: 'Generate a UI blueprint from natural language description.\n\n' +
|
|
45
|
+
'WHEN TO CALL:\n' +
|
|
46
|
+
'- For rapid prototyping and design exploration\n' +
|
|
47
|
+
'- When user wants a quick visual structure without full Screen Definition\n' +
|
|
48
|
+
'- As an alternative lightweight workflow to get-screen-generation-context\n\n' +
|
|
49
|
+
'NOTE: For production-ready code generation, use the main workflow:\n' +
|
|
50
|
+
'get-screen-generation-context → validate-screen-definition → generate_screen\n\n' +
|
|
51
|
+
'RETURNS: Simplified blueprint object with layout structure and component suggestions',
|
|
52
|
+
inputSchema: {
|
|
53
|
+
type: 'object',
|
|
54
|
+
properties: {
|
|
55
|
+
description: {
|
|
56
|
+
type: 'string',
|
|
57
|
+
description: 'Natural language description of the screen (10-500 characters)',
|
|
58
|
+
minLength: 10,
|
|
59
|
+
maxLength: 500,
|
|
60
|
+
},
|
|
61
|
+
layout: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
description: 'Layout type for the screen',
|
|
64
|
+
enum: [
|
|
65
|
+
'single-column',
|
|
66
|
+
'two-column',
|
|
67
|
+
'sidebar-left',
|
|
68
|
+
'sidebar-right',
|
|
69
|
+
'dashboard',
|
|
70
|
+
'landing',
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
themeId: {
|
|
74
|
+
type: 'string',
|
|
75
|
+
description: 'Theme ID (lowercase alphanumeric with hyphens)',
|
|
76
|
+
pattern: '^[a-z0-9-]+$',
|
|
77
|
+
},
|
|
78
|
+
componentHints: {
|
|
79
|
+
type: 'array',
|
|
80
|
+
description: 'Optional component type hints',
|
|
81
|
+
items: { type: 'string' },
|
|
82
|
+
},
|
|
83
|
+
iconLibrary: {
|
|
84
|
+
type: 'string',
|
|
85
|
+
description: 'Icon library ID (e.g., lucide, heroicons, feather)',
|
|
86
|
+
pattern: '^[a-z0-9-]+$',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
required: ['description', 'layout', 'themeId'],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'list-icon-libraries',
|
|
94
|
+
description: 'List all available icon libraries from .moai/icon-libraries/generated/\n\n' +
|
|
95
|
+
'WHEN TO CALL:\n' +
|
|
96
|
+
'- When user asks which icon libraries are available\n' +
|
|
97
|
+
'- Before calling preview-icon-library to select a library\n' +
|
|
98
|
+
'- When deciding which iconLibrary parameter to use in generate-blueprint\n\n' +
|
|
99
|
+
'RETURNS: Array of icon library IDs (e.g., lucide, heroicons, feather) with metadata',
|
|
100
|
+
inputSchema: {
|
|
101
|
+
type: 'object',
|
|
102
|
+
properties: {},
|
|
103
|
+
required: [],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'preview-icon-library',
|
|
108
|
+
description: 'Preview an icon library and retrieve its configuration including package names and icon samples.\n\n' +
|
|
109
|
+
'WHEN TO CALL:\n' +
|
|
110
|
+
'- After list-icon-libraries to inspect a specific library\n' +
|
|
111
|
+
'- When user wants to know available icons in a library\n' +
|
|
112
|
+
'- To get the NPM package name for an icon library\n' +
|
|
113
|
+
'- Before using icons in a Screen Definition\n\n' +
|
|
114
|
+
'RETURNS: Library configuration, package name, icon samples, and usage instructions',
|
|
115
|
+
inputSchema: {
|
|
116
|
+
type: 'object',
|
|
117
|
+
properties: {
|
|
118
|
+
libraryId: {
|
|
119
|
+
type: 'string',
|
|
120
|
+
description: 'Icon library ID to preview (e.g., lucide, heroicons, feather)',
|
|
121
|
+
pattern: '^[a-z0-9-]+$',
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
required: ['libraryId'],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'list-themes',
|
|
129
|
+
description: 'List all available themes from .moai/themes/generated/\n\n' +
|
|
130
|
+
'WHEN TO CALL:\n' +
|
|
131
|
+
'- When user asks which themes are available\n' +
|
|
132
|
+
'- Before calling preview-theme to select a theme\n' +
|
|
133
|
+
'- When deciding which themeId parameter to use in generate-blueprint or get-screen-generation-context\n\n' +
|
|
134
|
+
'RETURNS: Array of theme IDs with names and descriptions',
|
|
135
|
+
inputSchema: {
|
|
136
|
+
type: 'object',
|
|
137
|
+
properties: {},
|
|
138
|
+
required: [],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'preview-theme',
|
|
143
|
+
description: 'Preview a theme and retrieve its full v2.1 theme data including design tokens.\n\n' +
|
|
144
|
+
'WHEN TO CALL:\n' +
|
|
145
|
+
'- After list-themes to inspect a specific theme\n' +
|
|
146
|
+
'- When user wants to see color palettes, typography, or spacing tokens\n' +
|
|
147
|
+
'- To understand theme structure before using in generate-blueprint or get-screen-generation-context\n' +
|
|
148
|
+
'- When user asks about theme customization options\n\n' +
|
|
149
|
+
'RETURNS: Complete theme data including colors, typography, spacing, and component tokens',
|
|
150
|
+
inputSchema: {
|
|
151
|
+
type: 'object',
|
|
152
|
+
properties: {
|
|
153
|
+
themeId: {
|
|
154
|
+
type: 'string',
|
|
155
|
+
description: 'Theme ID to preview (lowercase alphanumeric with hyphens)',
|
|
156
|
+
pattern: '^[a-z0-9-]+$',
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
required: ['themeId'],
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: 'export-screen',
|
|
164
|
+
description: 'Export a blueprint to JSX, TSX, or Vue code.\n\n' +
|
|
165
|
+
'WHEN TO CALL:\n' +
|
|
166
|
+
'- After generate-blueprint to convert blueprint to code\n' +
|
|
167
|
+
'- When user wants code in JSX/TSX/Vue format\n' +
|
|
168
|
+
'- For lightweight prototyping without full Screen Definition workflow\n\n' +
|
|
169
|
+
'NOTE: For production-ready code with full validation, use:\n' +
|
|
170
|
+
'get-screen-generation-context → validate-screen-definition → generate_screen\n\n' +
|
|
171
|
+
'RETURNS: Exported code in requested format',
|
|
172
|
+
inputSchema: {
|
|
173
|
+
type: 'object',
|
|
174
|
+
properties: {
|
|
175
|
+
blueprint: {
|
|
176
|
+
type: 'object',
|
|
177
|
+
description: 'Blueprint object to export',
|
|
178
|
+
},
|
|
179
|
+
format: {
|
|
180
|
+
type: 'string',
|
|
181
|
+
description: 'Export format',
|
|
182
|
+
enum: ['jsx', 'tsx', 'vue'],
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
required: ['blueprint', 'format'],
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: 'generate_screen',
|
|
190
|
+
description: '[WORKFLOW STEP 3/4] Generate production-ready React code from validated Screen Definition.\n\n' +
|
|
191
|
+
'REQUIRED WORKFLOW:\n' +
|
|
192
|
+
'1. Call get-screen-generation-context (Step 1/4)\n' +
|
|
193
|
+
'2. Generate/validate Screen Definition (Step 2/4)\n' +
|
|
194
|
+
'3. Call THIS TOOL (Step 3/4)\n' +
|
|
195
|
+
'4. Call validate-environment if path known (Step 4/4)\n\n' +
|
|
196
|
+
'AFTER RECEIVING RESPONSE:\n' +
|
|
197
|
+
'- ALWAYS check the "dependencies" field in the response\n' +
|
|
198
|
+
'- If dependencies.external is non-empty:\n' +
|
|
199
|
+
' * User provided package.json path? → Call validate-environment (Step 4/4)\n' +
|
|
200
|
+
' * Path unknown? → Show dependencies.installCommands to user\n' +
|
|
201
|
+
'- Display the list of required packages to user before delivering code\n' +
|
|
202
|
+
'- validate-environment also checks Tailwind CSS config — ensures @tekton-ui/ui\n' +
|
|
203
|
+
' content paths and tailwindcss-animate plugin are configured correctly\n\n' +
|
|
204
|
+
'CRITICAL:\n' +
|
|
205
|
+
'- This workflow prevents "Module not found" errors at runtime\n' +
|
|
206
|
+
'- Tailwind validation prevents invisible/unstyled @tekton-ui/ui components\n' +
|
|
207
|
+
'- Never deliver code without informing user about dependencies',
|
|
208
|
+
inputSchema: {
|
|
209
|
+
type: 'object',
|
|
210
|
+
properties: {
|
|
211
|
+
screenDefinition: {
|
|
212
|
+
type: 'object',
|
|
213
|
+
description: 'JSON screen definition with id, shell, page, sections',
|
|
214
|
+
},
|
|
215
|
+
outputFormat: {
|
|
216
|
+
type: 'string',
|
|
217
|
+
description: 'Code output format',
|
|
218
|
+
enum: ['css-in-js', 'tailwind', 'react'],
|
|
219
|
+
},
|
|
220
|
+
options: {
|
|
221
|
+
type: 'object',
|
|
222
|
+
description: 'Optional generation options',
|
|
223
|
+
properties: {
|
|
224
|
+
cssFramework: {
|
|
225
|
+
type: 'string',
|
|
226
|
+
enum: ['styled-components', 'emotion'],
|
|
227
|
+
},
|
|
228
|
+
typescript: { type: 'boolean' },
|
|
229
|
+
prettier: { type: 'boolean' },
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
required: ['screenDefinition', 'outputFormat'],
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
name: 'validate_screen',
|
|
238
|
+
description: 'Validate JSON screen definition with helpful feedback.\n\n' +
|
|
239
|
+
'WHEN TO CALL:\n' +
|
|
240
|
+
'- To validate a screen definition structure\n' +
|
|
241
|
+
'- Before passing definition to generate_screen\n\n' +
|
|
242
|
+
'NOTE: For the recommended workflow, use validate-screen-definition (Step 2/4) instead,\n' +
|
|
243
|
+
'which provides more detailed validation, suggestions, and improvement recommendations.\n\n' +
|
|
244
|
+
'RETURNS: Validation result with errors and warnings',
|
|
245
|
+
inputSchema: {
|
|
246
|
+
type: 'object',
|
|
247
|
+
properties: {
|
|
248
|
+
screenDefinition: {
|
|
249
|
+
type: 'object',
|
|
250
|
+
description: 'JSON screen definition to validate',
|
|
251
|
+
},
|
|
252
|
+
strictMode: {
|
|
253
|
+
type: 'boolean',
|
|
254
|
+
description: 'Enable strict validation (default: false)',
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
required: ['screenDefinition'],
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: 'list_tokens',
|
|
262
|
+
description: 'List available layout tokens from SPEC-LAYOUT-001.\n\n' +
|
|
263
|
+
'WHEN TO CALL:\n' +
|
|
264
|
+
'- When user asks about available shell, page, or section tokens\n' +
|
|
265
|
+
'- Before creating a Screen Definition to see valid token options\n' +
|
|
266
|
+
'- When validation errors mention unknown tokens\n' +
|
|
267
|
+
'- To explore layout options for different screen types\n\n' +
|
|
268
|
+
'RETURNS: Array of layout tokens with descriptions and usage contexts',
|
|
269
|
+
inputSchema: {
|
|
270
|
+
type: 'object',
|
|
271
|
+
properties: {
|
|
272
|
+
tokenType: {
|
|
273
|
+
type: 'string',
|
|
274
|
+
description: 'Filter by token type',
|
|
275
|
+
enum: ['shell', 'page', 'section', 'all'],
|
|
276
|
+
},
|
|
277
|
+
filter: {
|
|
278
|
+
type: 'string',
|
|
279
|
+
description: 'Optional pattern filter (case-insensitive substring match)',
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
name: 'list-components',
|
|
286
|
+
description: 'List all available UI components from @tekton-ui/ui with metadata.\n\n' +
|
|
287
|
+
'WHEN TO CALL:\n' +
|
|
288
|
+
'- When user asks which components are available\n' +
|
|
289
|
+
'- Before calling preview-component to select a component\n' +
|
|
290
|
+
'- To discover components for a specific category (core, complex, advanced)\n' +
|
|
291
|
+
'- When planning a Screen Definition structure\n\n' +
|
|
292
|
+
'RETURNS: Array of component IDs with categories, descriptions, and metadata',
|
|
293
|
+
inputSchema: {
|
|
294
|
+
type: 'object',
|
|
295
|
+
properties: {
|
|
296
|
+
category: {
|
|
297
|
+
type: 'string',
|
|
298
|
+
description: 'Filter by component category',
|
|
299
|
+
enum: ['core', 'complex', 'advanced', 'all'],
|
|
300
|
+
},
|
|
301
|
+
search: {
|
|
302
|
+
type: 'string',
|
|
303
|
+
description: 'Search components by keyword',
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
name: 'preview-component',
|
|
310
|
+
description: 'Preview a component with detailed props, variants, and usage examples.\n\n' +
|
|
311
|
+
'WHEN TO CALL:\n' +
|
|
312
|
+
'- After list-components to inspect a specific component\n' +
|
|
313
|
+
'- When user wants to know component props, variants, or usage\n' +
|
|
314
|
+
'- Before using a component in a Screen Definition\n' +
|
|
315
|
+
'- To understand component dependencies and requirements\n\n' +
|
|
316
|
+
'RETURNS: Component details including props, variants, usage examples, and dependencies',
|
|
317
|
+
inputSchema: {
|
|
318
|
+
type: 'object',
|
|
319
|
+
properties: {
|
|
320
|
+
componentId: {
|
|
321
|
+
type: 'string',
|
|
322
|
+
description: 'Component ID to preview (e.g., button, card, dialog)',
|
|
323
|
+
pattern: '^[a-z-]+$',
|
|
324
|
+
},
|
|
325
|
+
includeExamples: {
|
|
326
|
+
type: 'boolean',
|
|
327
|
+
description: 'Include usage examples (default: true)',
|
|
328
|
+
},
|
|
329
|
+
includeDependencies: {
|
|
330
|
+
type: 'boolean',
|
|
331
|
+
description: 'Include dependency information (default: true)',
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
required: ['componentId'],
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
name: 'list-screen-templates',
|
|
339
|
+
description: 'List all available screen templates from Template Registry.\n\n' +
|
|
340
|
+
'WHEN TO CALL:\n' +
|
|
341
|
+
'- When user asks about available screen templates\n' +
|
|
342
|
+
'- Before calling preview-screen-template to select a template\n' +
|
|
343
|
+
'- To discover templates for specific categories (auth, dashboard, form, marketing, feedback)\n' +
|
|
344
|
+
'- When user wants to start from a template instead of building from scratch\n\n' +
|
|
345
|
+
'RETURNS: Array of template IDs with categories, descriptions, and preview information',
|
|
346
|
+
inputSchema: {
|
|
347
|
+
type: 'object',
|
|
348
|
+
properties: {
|
|
349
|
+
category: {
|
|
350
|
+
type: 'string',
|
|
351
|
+
description: 'Filter by template category',
|
|
352
|
+
enum: ['auth', 'dashboard', 'form', 'marketing', 'feedback', 'all'],
|
|
353
|
+
},
|
|
354
|
+
search: {
|
|
355
|
+
type: 'string',
|
|
356
|
+
description: 'Search templates by keyword',
|
|
357
|
+
},
|
|
358
|
+
},
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
name: 'preview-screen-template',
|
|
363
|
+
description: 'Preview a screen template with skeleton, layout, and customization boundaries.\n\n' +
|
|
364
|
+
'WHEN TO CALL:\n' +
|
|
365
|
+
'- After list-screen-templates to inspect a specific template\n' +
|
|
366
|
+
'- When user wants to see template structure and customization options\n' +
|
|
367
|
+
'- Before using a template as base for a Screen Definition\n' +
|
|
368
|
+
'- To understand template layout tokens and component structure\n\n' +
|
|
369
|
+
'RETURNS: Template details including skeleton, layout tokens, customization boundaries, and usage guide',
|
|
370
|
+
inputSchema: {
|
|
371
|
+
type: 'object',
|
|
372
|
+
properties: {
|
|
373
|
+
templateId: {
|
|
374
|
+
type: 'string',
|
|
375
|
+
description: 'Template ID to preview (format: category.name, e.g., auth.login)',
|
|
376
|
+
pattern: '^[a-z]+\\.[a-z-]+$',
|
|
377
|
+
},
|
|
378
|
+
includeLayoutTokens: {
|
|
379
|
+
type: 'boolean',
|
|
380
|
+
description: 'Include responsive layout tokens (default: true)',
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
required: ['templateId'],
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
name: 'get-screen-generation-context',
|
|
388
|
+
description: '[WORKFLOW STEP 1/4] Get complete context for AI agents to generate screen definitions from natural language.\n\n' +
|
|
389
|
+
'THIS IS THE FIRST STEP in the screen generation workflow:\n' +
|
|
390
|
+
"1. Call THIS TOOL with user's description (Step 1/4)\n" +
|
|
391
|
+
'2. Use returned context to generate/validate Screen Definition (Step 2/4)\n' +
|
|
392
|
+
'3. Call generate_screen with the definition (Step 3/4)\n' +
|
|
393
|
+
'4. Call validate-environment if path known (Step 4/4 - Phase 2)\n\n' +
|
|
394
|
+
'WHEN TO CALL:\n' +
|
|
395
|
+
'- When user requests a new screen/page/component\n' +
|
|
396
|
+
'- Before attempting to generate a Screen Definition JSON\n' +
|
|
397
|
+
'- When you need to know available components, templates, or layout tokens\n\n' +
|
|
398
|
+
'RETURNS:\n' +
|
|
399
|
+
'- Template matches based on description\n' +
|
|
400
|
+
'- Available components with usage examples\n' +
|
|
401
|
+
'- JSON schema for Screen Definition\n' +
|
|
402
|
+
'- Example definitions for reference\n' +
|
|
403
|
+
'- Theme recipes and contextual hints',
|
|
404
|
+
inputSchema: {
|
|
405
|
+
type: 'object',
|
|
406
|
+
properties: {
|
|
407
|
+
description: {
|
|
408
|
+
type: 'string',
|
|
409
|
+
description: 'Natural language description of the screen to generate (5-1000 characters)',
|
|
410
|
+
minLength: 5,
|
|
411
|
+
maxLength: 1000,
|
|
412
|
+
},
|
|
413
|
+
themeId: {
|
|
414
|
+
type: 'string',
|
|
415
|
+
description: 'Optional theme ID for recipe information',
|
|
416
|
+
pattern: '^[a-z0-9-]+$',
|
|
417
|
+
},
|
|
418
|
+
includeExamples: {
|
|
419
|
+
type: 'boolean',
|
|
420
|
+
description: 'Include example screen definitions (default: true)',
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
required: ['description'],
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
name: 'validate-screen-definition',
|
|
428
|
+
description: '[WORKFLOW STEP 2/4] Validate a screen definition JSON with detailed error messages, suggestions, and improvement recommendations.\n\n' +
|
|
429
|
+
'WHEN TO CALL:\n' +
|
|
430
|
+
'- After creating a Screen Definition JSON (from Step 1 context)\n' +
|
|
431
|
+
'- Before calling generate_screen (Step 3)\n' +
|
|
432
|
+
'- When user reports validation errors in generated code\n' +
|
|
433
|
+
'- To get improvement suggestions for an existing definition\n\n' +
|
|
434
|
+
'RETURNS:\n' +
|
|
435
|
+
'- valid: boolean indicating if definition is valid\n' +
|
|
436
|
+
'- errors: Array of validation errors with suggestions\n' +
|
|
437
|
+
'- warnings: Array of potential issues\n' +
|
|
438
|
+
'- suggestions: Improvement recommendations\n\n' +
|
|
439
|
+
'NEXT STEP:\n' +
|
|
440
|
+
'- If valid: true, proceed to generate_screen (Step 3/4)\n' +
|
|
441
|
+
'- If valid: false, fix errors in definition and re-validate',
|
|
442
|
+
inputSchema: {
|
|
443
|
+
type: 'object',
|
|
444
|
+
properties: {
|
|
445
|
+
definition: {
|
|
446
|
+
type: 'object',
|
|
447
|
+
description: 'Screen definition object to validate',
|
|
448
|
+
},
|
|
449
|
+
strict: {
|
|
450
|
+
type: 'boolean',
|
|
451
|
+
description: 'Enable strict validation (default: true). In strict mode, unknown tokens/components are errors; otherwise they are warnings.',
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
required: ['definition'],
|
|
455
|
+
},
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
name: 'validate-environment',
|
|
459
|
+
description: 'Validate user environment: NPM packages + Tailwind CSS configuration for @tekton-ui/ui.\n\n' +
|
|
460
|
+
'WHEN TO CALL:\n' +
|
|
461
|
+
'- After generate_screen returns dependencies.missing array\n' +
|
|
462
|
+
'- When user wants to check if their project has required packages\n' +
|
|
463
|
+
'- Before running generated code to ensure all dependencies are available\n' +
|
|
464
|
+
'- To verify Tailwind CSS is configured correctly for @tekton-ui/ui components\n\n' +
|
|
465
|
+
'RETURNS:\n' +
|
|
466
|
+
'- installed: Packages already in package.json with versions\n' +
|
|
467
|
+
'- missing: Packages that need to be installed\n' +
|
|
468
|
+
'- installCommands: Ready-to-use install commands for npm/yarn/pnpm/bun\n' +
|
|
469
|
+
'- tailwind: Tailwind CSS config validation (content paths, animate plugin)\n\n' +
|
|
470
|
+
'TAILWIND VALIDATION (checkTailwind=true by default):\n' +
|
|
471
|
+
'- Checks if tailwind.config.{ts,js,mjs,cjs} exists\n' +
|
|
472
|
+
'- Verifies @tekton-ui/ui content paths are included (prevents missing styles)\n' +
|
|
473
|
+
'- Verifies tailwindcss-animate plugin is configured (required for Dialog, Popover animations)\n' +
|
|
474
|
+
'- Returns actionable issues[] and fixes[] for each problem found\n\n' +
|
|
475
|
+
'EXAMPLE WORKFLOW:\n' +
|
|
476
|
+
'1. Call generate_screen → get dependencies.external\n' +
|
|
477
|
+
'2. Call validate-environment with projectPath + requiredPackages\n' +
|
|
478
|
+
'3. Show user missing packages, install commands, AND any Tailwind config issues',
|
|
479
|
+
inputSchema: {
|
|
480
|
+
type: 'object',
|
|
481
|
+
properties: {
|
|
482
|
+
projectPath: {
|
|
483
|
+
type: 'string',
|
|
484
|
+
description: 'Path to package.json or project root directory',
|
|
485
|
+
},
|
|
486
|
+
requiredPackages: {
|
|
487
|
+
type: 'array',
|
|
488
|
+
description: 'Array of package names to validate (e.g., ["framer-motion", "@radix-ui/react-slot"])',
|
|
489
|
+
items: { type: 'string' },
|
|
490
|
+
},
|
|
491
|
+
checkTailwind: {
|
|
492
|
+
type: 'boolean',
|
|
493
|
+
description: 'Also validate Tailwind CSS configuration for @tekton-ui/ui compatibility (default: true)',
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
required: ['projectPath', 'requiredPackages'],
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
],
|
|
500
|
+
};
|
|
501
|
+
});
|
|
502
|
+
// ============================================================================
|
|
503
|
+
// Task #10: CallToolRequestSchema Handler
|
|
504
|
+
// ============================================================================
|
|
505
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
506
|
+
const { name, arguments: args } = request.params;
|
|
507
|
+
info(`CallTool request: ${name}`);
|
|
508
|
+
// 모든 도구 호출 전에 인증 가드 실행
|
|
509
|
+
try {
|
|
510
|
+
requireAuth();
|
|
511
|
+
}
|
|
512
|
+
catch (e) {
|
|
513
|
+
if (e instanceof AuthRequiredError) {
|
|
514
|
+
return {
|
|
515
|
+
content: [
|
|
516
|
+
{
|
|
517
|
+
type: 'text',
|
|
518
|
+
text: JSON.stringify({
|
|
519
|
+
success: false,
|
|
520
|
+
error: 'Authentication required.',
|
|
521
|
+
hint: 'Run `tekton-mcp login` to authenticate, or set TEKTON_API_KEY environment variable.',
|
|
522
|
+
}),
|
|
523
|
+
},
|
|
524
|
+
],
|
|
525
|
+
isError: true,
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
try {
|
|
530
|
+
switch (name) {
|
|
531
|
+
case 'generate-blueprint': {
|
|
532
|
+
// Validate input
|
|
533
|
+
const validatedInput = GenerateBlueprintInputSchema.parse(args);
|
|
534
|
+
const result = await generateBlueprintTool(validatedInput);
|
|
535
|
+
return {
|
|
536
|
+
content: [
|
|
537
|
+
{
|
|
538
|
+
type: 'text',
|
|
539
|
+
text: JSON.stringify(result, null, 2),
|
|
540
|
+
},
|
|
541
|
+
],
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
case 'list-icon-libraries': {
|
|
545
|
+
// Validate input (no required fields)
|
|
546
|
+
ListIconLibrariesInputSchema.parse(args);
|
|
547
|
+
const result = await listIconLibrariesTool();
|
|
548
|
+
return {
|
|
549
|
+
content: [
|
|
550
|
+
{
|
|
551
|
+
type: 'text',
|
|
552
|
+
text: JSON.stringify(result, null, 2),
|
|
553
|
+
},
|
|
554
|
+
],
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
case 'preview-icon-library': {
|
|
558
|
+
// Validate input
|
|
559
|
+
const validatedInput = PreviewIconLibraryInputSchema.parse(args);
|
|
560
|
+
const result = await previewIconLibraryTool(validatedInput);
|
|
561
|
+
return {
|
|
562
|
+
content: [
|
|
563
|
+
{
|
|
564
|
+
type: 'text',
|
|
565
|
+
text: JSON.stringify(result, null, 2),
|
|
566
|
+
},
|
|
567
|
+
],
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
case 'list-themes': {
|
|
571
|
+
// Validate input (no required fields)
|
|
572
|
+
ListThemesInputSchema.parse(args);
|
|
573
|
+
const result = await listThemesTool();
|
|
574
|
+
return {
|
|
575
|
+
content: [
|
|
576
|
+
{
|
|
577
|
+
type: 'text',
|
|
578
|
+
text: JSON.stringify(result, null, 2),
|
|
579
|
+
},
|
|
580
|
+
],
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
case 'preview-theme': {
|
|
584
|
+
// Validate input
|
|
585
|
+
const validatedInput = PreviewThemeInputSchema.parse(args);
|
|
586
|
+
const result = await previewThemeTool(validatedInput);
|
|
587
|
+
return {
|
|
588
|
+
content: [
|
|
589
|
+
{
|
|
590
|
+
type: 'text',
|
|
591
|
+
text: JSON.stringify(result, null, 2),
|
|
592
|
+
},
|
|
593
|
+
],
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
case 'export-screen': {
|
|
597
|
+
// Validate input
|
|
598
|
+
const validatedInput = ExportScreenInputSchema.parse(args);
|
|
599
|
+
const result = await exportScreenTool(validatedInput);
|
|
600
|
+
return {
|
|
601
|
+
content: [
|
|
602
|
+
{
|
|
603
|
+
type: 'text',
|
|
604
|
+
text: JSON.stringify(result, null, 2),
|
|
605
|
+
},
|
|
606
|
+
],
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
case 'generate_screen': {
|
|
610
|
+
// Validate input
|
|
611
|
+
const validatedInput = GenerateScreenInputSchema.parse(args);
|
|
612
|
+
const result = await generateScreenTool(validatedInput);
|
|
613
|
+
return {
|
|
614
|
+
content: [
|
|
615
|
+
{
|
|
616
|
+
type: 'text',
|
|
617
|
+
text: JSON.stringify(result, null, 2),
|
|
618
|
+
},
|
|
619
|
+
],
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
case 'validate_screen': {
|
|
623
|
+
// Validate input
|
|
624
|
+
const validatedInput = ValidateScreenInputSchema.parse(args);
|
|
625
|
+
const result = await validateScreenTool(validatedInput);
|
|
626
|
+
return {
|
|
627
|
+
content: [
|
|
628
|
+
{
|
|
629
|
+
type: 'text',
|
|
630
|
+
text: JSON.stringify(result, null, 2),
|
|
631
|
+
},
|
|
632
|
+
],
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
case 'list_tokens': {
|
|
636
|
+
// Validate input
|
|
637
|
+
const validatedInput = ListTokensInputSchema.parse(args);
|
|
638
|
+
const result = await listTokensTool(validatedInput);
|
|
639
|
+
return {
|
|
640
|
+
content: [
|
|
641
|
+
{
|
|
642
|
+
type: 'text',
|
|
643
|
+
text: JSON.stringify(result, null, 2),
|
|
644
|
+
},
|
|
645
|
+
],
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
case 'list-components': {
|
|
649
|
+
// Validate input
|
|
650
|
+
const validatedInput = ListComponentsInputSchema.parse(args);
|
|
651
|
+
const result = await listComponentsTool(validatedInput);
|
|
652
|
+
return {
|
|
653
|
+
content: [
|
|
654
|
+
{
|
|
655
|
+
type: 'text',
|
|
656
|
+
text: JSON.stringify(result, null, 2),
|
|
657
|
+
},
|
|
658
|
+
],
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
case 'preview-component': {
|
|
662
|
+
// Validate input
|
|
663
|
+
const validatedInput = PreviewComponentInputSchema.parse(args);
|
|
664
|
+
const result = await previewComponentTool(validatedInput);
|
|
665
|
+
return {
|
|
666
|
+
content: [
|
|
667
|
+
{
|
|
668
|
+
type: 'text',
|
|
669
|
+
text: JSON.stringify(result, null, 2),
|
|
670
|
+
},
|
|
671
|
+
],
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
case 'list-screen-templates': {
|
|
675
|
+
// Validate input
|
|
676
|
+
const validatedInput = ListScreenTemplatesInputSchema.parse(args);
|
|
677
|
+
const result = await listScreenTemplatesTool(validatedInput);
|
|
678
|
+
return {
|
|
679
|
+
content: [
|
|
680
|
+
{
|
|
681
|
+
type: 'text',
|
|
682
|
+
text: JSON.stringify(result, null, 2),
|
|
683
|
+
},
|
|
684
|
+
],
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
case 'preview-screen-template': {
|
|
688
|
+
// Validate input
|
|
689
|
+
const validatedInput = PreviewScreenTemplateInputSchema.parse(args);
|
|
690
|
+
const result = await previewScreenTemplateTool(validatedInput);
|
|
691
|
+
return {
|
|
692
|
+
content: [
|
|
693
|
+
{
|
|
694
|
+
type: 'text',
|
|
695
|
+
text: JSON.stringify(result, null, 2),
|
|
696
|
+
},
|
|
697
|
+
],
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
case 'get-screen-generation-context': {
|
|
701
|
+
// Validate input
|
|
702
|
+
const validatedInput = GetScreenGenerationContextInputSchema.parse(args);
|
|
703
|
+
const result = await getScreenGenerationContextTool(validatedInput);
|
|
704
|
+
return {
|
|
705
|
+
content: [
|
|
706
|
+
{
|
|
707
|
+
type: 'text',
|
|
708
|
+
text: JSON.stringify(result, null, 2),
|
|
709
|
+
},
|
|
710
|
+
],
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
case 'validate-screen-definition': {
|
|
714
|
+
// Validate input
|
|
715
|
+
const validatedInput = ValidateScreenDefinitionInputSchema.parse(args);
|
|
716
|
+
const result = await validateScreenDefinitionTool(validatedInput);
|
|
717
|
+
return {
|
|
718
|
+
content: [
|
|
719
|
+
{
|
|
720
|
+
type: 'text',
|
|
721
|
+
text: JSON.stringify(result, null, 2),
|
|
722
|
+
},
|
|
723
|
+
],
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
case 'validate-environment': {
|
|
727
|
+
// Validate input
|
|
728
|
+
const validatedInput = ValidateEnvironmentInputSchema.parse(args);
|
|
729
|
+
const result = await validateEnvironmentTool(validatedInput);
|
|
730
|
+
return {
|
|
731
|
+
content: [
|
|
732
|
+
{
|
|
733
|
+
type: 'text',
|
|
734
|
+
text: JSON.stringify(result, null, 2),
|
|
735
|
+
},
|
|
736
|
+
],
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
default:
|
|
740
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
catch (error) {
|
|
744
|
+
logError(`Tool execution error: ${error}`);
|
|
745
|
+
return {
|
|
746
|
+
content: [
|
|
747
|
+
{
|
|
748
|
+
type: 'text',
|
|
749
|
+
text: JSON.stringify({
|
|
750
|
+
success: false,
|
|
751
|
+
error: error instanceof Error ? error.message : String(error),
|
|
752
|
+
}, null, 2),
|
|
753
|
+
},
|
|
754
|
+
],
|
|
755
|
+
isError: true,
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
});
|
|
759
|
+
// ============================================================================
|
|
760
|
+
// Server Initialization
|
|
761
|
+
// ============================================================================
|
|
762
|
+
info('Starting Tekton MCP Server v2.1.0...');
|
|
763
|
+
// ============================================================================
|
|
764
|
+
// Authentication: Credential Chain
|
|
765
|
+
// 1. 환경변수 TEKTON_API_KEY (기존 방식 호환)
|
|
766
|
+
// 2. ~/.tekton/credentials.json (CLI login 방식)
|
|
767
|
+
// 3. 둘 다 없으면: 인증 없이 시작 (도구 호출 시 에러)
|
|
768
|
+
// ============================================================================
|
|
769
|
+
// 크레덴셜 체인으로 API Key 결정
|
|
770
|
+
let apiKey = process.env.TEKTON_API_KEY;
|
|
771
|
+
let apiKeySource = 'TEKTON_API_KEY env';
|
|
772
|
+
if (!apiKey) {
|
|
773
|
+
const creds = loadCredentials();
|
|
774
|
+
if (creds) {
|
|
775
|
+
apiKey = creds.api_key;
|
|
776
|
+
apiKeySource = '~/.tekton/credentials.json';
|
|
777
|
+
// 크레덴셜 파일의 API URL도 적용
|
|
778
|
+
if (creds.api_url && !process.env.TEKTON_API_URL) {
|
|
779
|
+
process.env.TEKTON_API_URL = creds.api_url;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
if (apiKey) {
|
|
784
|
+
info(`API key detected from ${apiKeySource}, verifying...`);
|
|
785
|
+
try {
|
|
786
|
+
const authResult = await verifyApiKey(apiKey);
|
|
787
|
+
if (authResult.valid) {
|
|
788
|
+
setAuthData(authResult);
|
|
789
|
+
info(`Authentication successful - User: ${authResult.user?.email || 'unknown'}, Plan: ${authResult.user?.plan || 'unknown'}`);
|
|
790
|
+
const licensedCount = authResult.themes?.licensed?.length || 0;
|
|
791
|
+
info(`Theme access: ${licensedCount} licensed themes`);
|
|
792
|
+
}
|
|
793
|
+
else {
|
|
794
|
+
logError(`Authentication failed: ${authResult.error || 'Unknown error'}`);
|
|
795
|
+
logError('All tool calls will require re-authentication.');
|
|
796
|
+
setAuthData(null);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
catch (err) {
|
|
800
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
801
|
+
logError(`Failed to verify API key: ${errorMessage}`);
|
|
802
|
+
logError('All tool calls will require re-authentication.');
|
|
803
|
+
setAuthData(null);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
else {
|
|
807
|
+
info('No API key found. Run `tekton-mcp login` or set TEKTON_API_KEY to authenticate.');
|
|
808
|
+
setAuthData(null);
|
|
809
|
+
}
|
|
810
|
+
// ============================================================================
|
|
811
|
+
// Connect Server
|
|
812
|
+
// ============================================================================
|
|
813
|
+
// Connect via stdio
|
|
814
|
+
const transport = new StdioServerTransport();
|
|
815
|
+
await server.connect(transport);
|
|
816
|
+
info('Tekton MCP Server connected via stdio transport');
|
|
817
|
+
info('16 MCP tools registered: generate-blueprint, list-themes, preview-theme, list-icon-libraries, preview-icon-library, export-screen, generate_screen, validate_screen, list_tokens, list-components, preview-component, list-screen-templates, preview-screen-template, get-screen-generation-context, validate-screen-definition, validate-environment');
|
|
818
|
+
//# sourceMappingURL=index.js.map
|