@musashishao/agent-kit 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/agents/backend-specialist.md +263 -0
- package/.agent/agents/database-architect.md +226 -0
- package/.agent/agents/debugger.md +225 -0
- package/.agent/agents/devops-engineer.md +242 -0
- package/.agent/agents/documentation-writer.md +104 -0
- package/.agent/agents/explorer-agent.md +73 -0
- package/.agent/agents/frontend-specialist.md +556 -0
- package/.agent/agents/game-developer.md +162 -0
- package/.agent/agents/mobile-developer.md +377 -0
- package/.agent/agents/orchestrator.md +416 -0
- package/.agent/agents/penetration-tester.md +188 -0
- package/.agent/agents/performance-optimizer.md +187 -0
- package/.agent/agents/project-planner.md +403 -0
- package/.agent/agents/security-auditor.md +170 -0
- package/.agent/agents/seo-specialist.md +111 -0
- package/.agent/agents/test-engineer.md +158 -0
- package/.agent/mcp/README.md +69 -0
- package/.agent/mcp/config/mcp-config.json +62 -0
- package/.agent/mcp/config/registry.json +54 -0
- package/.agent/mcp/servers/agent-kit-core/package.json +28 -0
- package/.agent/mcp/servers/agent-kit-core/src/index.ts +455 -0
- package/.agent/mcp/servers/agent-kit-core/tsconfig.json +16 -0
- package/.agent/mcp/servers/agent-kit-fs/package.json +25 -0
- package/.agent/mcp/servers/agent-kit-fs/src/index.ts +399 -0
- package/.agent/mcp/servers/agent-kit-fs/tsconfig.json +16 -0
- package/.agent/mcp/servers/agent-kit-git/package.json +24 -0
- package/.agent/mcp/servers/agent-kit-git/src/index.ts +283 -0
- package/.agent/mcp/servers/agent-kit-git/tsconfig.json +16 -0
- package/.agent/mcp/templates/README.md +49 -0
- package/.agent/mcp/templates/api/README.md.template +45 -0
- package/.agent/mcp/templates/api/src/index.ts.template +185 -0
- package/.agent/mcp/templates/base-package.json.template +27 -0
- package/.agent/mcp/templates/base-tsconfig.json +21 -0
- package/.agent/mcp/templates/custom/src/index.ts.template +133 -0
- package/.agent/mcp/templates/database/src/index.ts.template +273 -0
- package/.agent/mcp/templates/web-scraper/src/index.ts.template +239 -0
- package/.agent/rules/CODEX.md +250 -0
- package/.agent/rules/GEMINI.md +251 -0
- package/.agent/skills/api-patterns/SKILL.md +81 -0
- package/.agent/skills/api-patterns/api-style.md +42 -0
- package/.agent/skills/api-patterns/auth.md +24 -0
- package/.agent/skills/api-patterns/documentation.md +26 -0
- package/.agent/skills/api-patterns/graphql.md +41 -0
- package/.agent/skills/api-patterns/rate-limiting.md +31 -0
- package/.agent/skills/api-patterns/response.md +37 -0
- package/.agent/skills/api-patterns/rest.md +40 -0
- package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
- package/.agent/skills/api-patterns/security-testing.md +122 -0
- package/.agent/skills/api-patterns/trpc.md +41 -0
- package/.agent/skills/api-patterns/versioning.md +22 -0
- package/.agent/skills/app-builder/SKILL.md +75 -0
- package/.agent/skills/app-builder/agent-coordination.md +71 -0
- package/.agent/skills/app-builder/feature-building.md +53 -0
- package/.agent/skills/app-builder/project-detection.md +34 -0
- package/.agent/skills/app-builder/scaffolding.md +118 -0
- package/.agent/skills/app-builder/tech-stack.md +40 -0
- package/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +82 -0
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +100 -0
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +106 -0
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +101 -0
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +93 -0
- package/.agent/skills/architecture/SKILL.md +55 -0
- package/.agent/skills/architecture/context-discovery.md +43 -0
- package/.agent/skills/architecture/examples.md +94 -0
- package/.agent/skills/architecture/pattern-selection.md +68 -0
- package/.agent/skills/architecture/patterns-reference.md +50 -0
- package/.agent/skills/architecture/trade-off-analysis.md +77 -0
- package/.agent/skills/bash-linux/SKILL.md +199 -0
- package/.agent/skills/behavioral-modes/SKILL.md +242 -0
- package/.agent/skills/brainstorming/SKILL.md +163 -0
- package/.agent/skills/brainstorming/dynamic-questioning.md +350 -0
- package/.agent/skills/clean-code/SKILL.md +201 -0
- package/.agent/skills/code-review-checklist/SKILL.md +109 -0
- package/.agent/skills/context-engineering/SKILL.md +74 -0
- package/.agent/skills/context-engineering/examples/advanced_code_request.md +73 -0
- package/.agent/skills/context-engineering/scripts/quality_validator.py +294 -0
- package/.agent/skills/context-engineering/scripts/repo_mapper.py +27 -0
- package/.agent/skills/context-engineering/scripts/skill_checker.py +194 -0
- package/.agent/skills/context-engineering/scripts/token_counter.py +65 -0
- package/.agent/skills/context-engineering/strategies/context-caching.md +50 -0
- package/.agent/skills/context-engineering/strategies/few-shot-examples.md +56 -0
- package/.agent/skills/context-engineering/strategies/skeleton-code.md +59 -0
- package/.agent/skills/context-engineering/strategies/xml-framing.md +57 -0
- package/.agent/skills/database-design/SKILL.md +52 -0
- package/.agent/skills/database-design/database-selection.md +43 -0
- package/.agent/skills/database-design/indexing.md +39 -0
- package/.agent/skills/database-design/migrations.md +48 -0
- package/.agent/skills/database-design/optimization.md +36 -0
- package/.agent/skills/database-design/orm-selection.md +30 -0
- package/.agent/skills/database-design/schema-design.md +56 -0
- package/.agent/skills/database-design/scripts/schema_validator.py +172 -0
- package/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/.agent/skills/doc.md +177 -0
- package/.agent/skills/docker-expert/SKILL.md +409 -0
- package/.agent/skills/documentation-templates/SKILL.md +194 -0
- package/.agent/skills/frontend-design/SKILL.md +396 -0
- package/.agent/skills/frontend-design/animation-guide.md +331 -0
- package/.agent/skills/frontend-design/color-system.md +311 -0
- package/.agent/skills/frontend-design/decision-trees.md +418 -0
- package/.agent/skills/frontend-design/motion-graphics.md +306 -0
- package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
- package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
- package/.agent/skills/frontend-design/typography-system.md +345 -0
- package/.agent/skills/frontend-design/ux-psychology.md +541 -0
- package/.agent/skills/frontend-design/visual-effects.md +383 -0
- package/.agent/skills/game-development/2d-games/SKILL.md +119 -0
- package/.agent/skills/game-development/3d-games/SKILL.md +135 -0
- package/.agent/skills/game-development/SKILL.md +167 -0
- package/.agent/skills/game-development/game-art/SKILL.md +185 -0
- package/.agent/skills/game-development/game-audio/SKILL.md +190 -0
- package/.agent/skills/game-development/game-design/SKILL.md +129 -0
- package/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
- package/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
- package/.agent/skills/game-development/pc-games/SKILL.md +144 -0
- package/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
- package/.agent/skills/game-development/web-games/SKILL.md +150 -0
- package/.agent/skills/geo-fundamentals/SKILL.md +156 -0
- package/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
- package/.agent/skills/i18n-localization/SKILL.md +154 -0
- package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
- package/.agent/skills/lint-and-validate/SKILL.md +45 -0
- package/.agent/skills/lint-and-validate/scripts/lint_runner.py +172 -0
- package/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -0
- package/.agent/skills/mcp-builder/SKILL.md +662 -0
- package/.agent/skills/mcp-builder/python-template.md +522 -0
- package/.agent/skills/mcp-builder/tool-patterns.md +642 -0
- package/.agent/skills/mcp-builder/typescript-template.md +361 -0
- package/.agent/skills/mobile-design/SKILL.md +394 -0
- package/.agent/skills/mobile-design/decision-trees.md +516 -0
- package/.agent/skills/mobile-design/mobile-backend.md +491 -0
- package/.agent/skills/mobile-design/mobile-color-system.md +420 -0
- package/.agent/skills/mobile-design/mobile-debugging.md +122 -0
- package/.agent/skills/mobile-design/mobile-design-thinking.md +357 -0
- package/.agent/skills/mobile-design/mobile-navigation.md +458 -0
- package/.agent/skills/mobile-design/mobile-performance.md +767 -0
- package/.agent/skills/mobile-design/mobile-testing.md +356 -0
- package/.agent/skills/mobile-design/mobile-typography.md +433 -0
- package/.agent/skills/mobile-design/platform-android.md +666 -0
- package/.agent/skills/mobile-design/platform-ios.md +561 -0
- package/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -0
- package/.agent/skills/mobile-design/touch-psychology.md +537 -0
- package/.agent/skills/nestjs-expert/SKILL.md +552 -0
- package/.agent/skills/nextjs-best-practices/SKILL.md +203 -0
- package/.agent/skills/nodejs-best-practices/SKILL.md +333 -0
- package/.agent/skills/parallel-agents/SKILL.md +175 -0
- package/.agent/skills/performance-profiling/SKILL.md +143 -0
- package/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
- package/.agent/skills/plan-writing/SKILL.md +152 -0
- package/.agent/skills/powershell-windows/SKILL.md +167 -0
- package/.agent/skills/prisma-expert/SKILL.md +355 -0
- package/.agent/skills/problem-solving/SKILL.md +556 -0
- package/.agent/skills/problem-solving/collision-zone-thinking.md +285 -0
- package/.agent/skills/problem-solving/inversion-exercise.md +205 -0
- package/.agent/skills/problem-solving/meta-pattern-recognition.md +313 -0
- package/.agent/skills/problem-solving/scale-game.md +300 -0
- package/.agent/skills/problem-solving/simplification-cascades.md +321 -0
- package/.agent/skills/problem-solving/when-stuck.md +146 -0
- package/.agent/skills/python-patterns/SKILL.md +441 -0
- package/.agent/skills/react-patterns/SKILL.md +198 -0
- package/.agent/skills/red-team-tactics/SKILL.md +199 -0
- package/.agent/skills/seo-fundamentals/SKILL.md +129 -0
- package/.agent/skills/seo-fundamentals/scripts/seo_checker.py +219 -0
- package/.agent/skills/server-management/SKILL.md +161 -0
- package/.agent/skills/systematic-debugging/SKILL.md +109 -0
- package/.agent/skills/tailwind-patterns/SKILL.md +269 -0
- package/.agent/skills/tdd-workflow/SKILL.md +149 -0
- package/.agent/skills/testing-patterns/SKILL.md +178 -0
- package/.agent/skills/testing-patterns/scripts/test_runner.py +219 -0
- package/.agent/skills/typescript-expert/SKILL.md +429 -0
- package/.agent/skills/typescript-expert/references/tsconfig-strict.json +92 -0
- package/.agent/skills/typescript-expert/references/typescript-cheatsheet.md +383 -0
- package/.agent/skills/typescript-expert/references/utility-types.ts +335 -0
- package/.agent/skills/typescript-expert/scripts/ts_diagnostic.py +203 -0
- package/.agent/skills/ui-ux-pro-max/SKILL.md +351 -0
- package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.agent/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.agent/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.agent/skills/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.agent/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agent/skills/ui-ux-pro-max/data/styles.csv +59 -0
- package/.agent/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.agent/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agent/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.agent/skills/ui-ux-pro-max/scripts/core.py +257 -0
- package/.agent/skills/ui-ux-pro-max/scripts/design_system.py +487 -0
- package/.agent/skills/ui-ux-pro-max/scripts/search.py +76 -0
- package/.agent/skills/vulnerability-scanner/SKILL.md +276 -0
- package/.agent/skills/vulnerability-scanner/checklists.md +121 -0
- package/.agent/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
- package/.agent/skills/webapp-testing/SKILL.md +187 -0
- package/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -0
- package/.agent/templates/AGENTS.backend.md +230 -0
- package/.agent/templates/AGENTS.md +121 -0
- package/.agent/templates/AGENTS.mobile.md +183 -0
- package/.agent/templates/AGENTS.web.md +192 -0
- package/.agent/workflows/brainstorm.md +113 -0
- package/.agent/workflows/context.md +47 -0
- package/.agent/workflows/create.md +59 -0
- package/.agent/workflows/debug.md +103 -0
- package/.agent/workflows/deploy.md +176 -0
- package/.agent/workflows/enhance.md +63 -0
- package/.agent/workflows/orchestrate.md +237 -0
- package/.agent/workflows/plan.md +89 -0
- package/.agent/workflows/preview.md +80 -0
- package/.agent/workflows/quality.md +89 -0
- package/.agent/workflows/status.md +86 -0
- package/.agent/workflows/test.md +144 -0
- package/.agent/workflows/ui-ux-pro-max.md +250 -0
- package/LICENSE +21 -0
- package/README.md +317 -0
- package/bin/cli.js +1267 -0
- package/index.js +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* {{SERVER_NAME}} - Custom MCP Server
|
|
4
|
+
*
|
|
5
|
+
* A minimal template to build your own MCP server.
|
|
6
|
+
*
|
|
7
|
+
* Generated by Agent Kit MCP Generator
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
|
|
14
|
+
const server = new McpServer({
|
|
15
|
+
name: "{{SERVER_NAME}}",
|
|
16
|
+
version: "1.0.0",
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Your Tools Here
|
|
21
|
+
// ============================================================================
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Example tool - Hello World
|
|
25
|
+
* Replace this with your own tools
|
|
26
|
+
*/
|
|
27
|
+
server.tool(
|
|
28
|
+
"hello",
|
|
29
|
+
"A simple hello world tool",
|
|
30
|
+
{
|
|
31
|
+
name: z.string().optional().describe("Name to greet"),
|
|
32
|
+
},
|
|
33
|
+
async ({ name }) => {
|
|
34
|
+
const greeting = name ? `Hello, ${name}!` : "Hello, World!";
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
content: [{
|
|
38
|
+
type: "text",
|
|
39
|
+
text: greeting,
|
|
40
|
+
}],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Example tool with complex input
|
|
47
|
+
*/
|
|
48
|
+
server.tool(
|
|
49
|
+
"calculate",
|
|
50
|
+
"Perform a calculation",
|
|
51
|
+
{
|
|
52
|
+
operation: z.enum(["add", "subtract", "multiply", "divide"])
|
|
53
|
+
.describe("The operation to perform"),
|
|
54
|
+
a: z.number().describe("First number"),
|
|
55
|
+
b: z.number().describe("Second number"),
|
|
56
|
+
},
|
|
57
|
+
async ({ operation, a, b }) => {
|
|
58
|
+
let result: number;
|
|
59
|
+
|
|
60
|
+
switch (operation) {
|
|
61
|
+
case "add":
|
|
62
|
+
result = a + b;
|
|
63
|
+
break;
|
|
64
|
+
case "subtract":
|
|
65
|
+
result = a - b;
|
|
66
|
+
break;
|
|
67
|
+
case "multiply":
|
|
68
|
+
result = a * b;
|
|
69
|
+
break;
|
|
70
|
+
case "divide":
|
|
71
|
+
if (b === 0) {
|
|
72
|
+
return {
|
|
73
|
+
content: [{
|
|
74
|
+
type: "text",
|
|
75
|
+
text: JSON.stringify({ error: "Cannot divide by zero" }),
|
|
76
|
+
}],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
result = a / b;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
content: [{
|
|
85
|
+
type: "text",
|
|
86
|
+
text: JSON.stringify({
|
|
87
|
+
operation,
|
|
88
|
+
a,
|
|
89
|
+
b,
|
|
90
|
+
result
|
|
91
|
+
}),
|
|
92
|
+
}],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// ============================================================================
|
|
98
|
+
// Your Resources Here
|
|
99
|
+
// ============================================================================
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Example resource
|
|
103
|
+
*/
|
|
104
|
+
server.resource(
|
|
105
|
+
"server-info",
|
|
106
|
+
"info://server",
|
|
107
|
+
async (uri) => ({
|
|
108
|
+
contents: [{
|
|
109
|
+
uri: uri.href,
|
|
110
|
+
mimeType: "application/json",
|
|
111
|
+
text: JSON.stringify({
|
|
112
|
+
name: "{{SERVER_NAME}}",
|
|
113
|
+
version: "1.0.0",
|
|
114
|
+
timestamp: new Date().toISOString(),
|
|
115
|
+
}),
|
|
116
|
+
}],
|
|
117
|
+
})
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// ============================================================================
|
|
121
|
+
// Start Server
|
|
122
|
+
// ============================================================================
|
|
123
|
+
|
|
124
|
+
async function main() {
|
|
125
|
+
const transport = new StdioServerTransport();
|
|
126
|
+
await server.connect(transport);
|
|
127
|
+
console.error("{{SERVER_NAME}} MCP Server running on stdio");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
main().catch((error) => {
|
|
131
|
+
console.error("Failed to start MCP server:", error);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
});
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* {{SERVER_NAME}} - Database MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Query and manage databases from your AI assistant.
|
|
6
|
+
* Supports: SQLite, PostgreSQL (via connection string)
|
|
7
|
+
*
|
|
8
|
+
* Generated by Agent Kit MCP Generator
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
12
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import * as fs from "fs";
|
|
15
|
+
import * as path from "path";
|
|
16
|
+
|
|
17
|
+
// Configuration
|
|
18
|
+
const DB_TYPE = process.env.DB_TYPE || "sqlite";
|
|
19
|
+
const DB_PATH = process.env.DB_PATH || "./database.db";
|
|
20
|
+
const DB_URL = process.env.DATABASE_URL || "";
|
|
21
|
+
|
|
22
|
+
const server = new McpServer({
|
|
23
|
+
name: "{{SERVER_NAME}}",
|
|
24
|
+
version: "1.0.0",
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// SQLite Implementation
|
|
29
|
+
// ============================================================================
|
|
30
|
+
|
|
31
|
+
interface QueryResult {
|
|
32
|
+
success: boolean;
|
|
33
|
+
rows?: Record<string, unknown>[];
|
|
34
|
+
rowCount?: number;
|
|
35
|
+
error?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function executeSqliteQuery(sql: string, params: unknown[] = []): Promise<QueryResult> {
|
|
39
|
+
// Dynamic import for sqlite3
|
|
40
|
+
try {
|
|
41
|
+
const sqlite3 = await import("better-sqlite3");
|
|
42
|
+
const db = new sqlite3.default(DB_PATH);
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
// Check if it's a SELECT query
|
|
46
|
+
const isSelect = sql.trim().toUpperCase().startsWith("SELECT");
|
|
47
|
+
|
|
48
|
+
if (isSelect) {
|
|
49
|
+
const stmt = db.prepare(sql);
|
|
50
|
+
const rows = stmt.all(...params) as Record<string, unknown>[];
|
|
51
|
+
return { success: true, rows, rowCount: rows.length };
|
|
52
|
+
} else {
|
|
53
|
+
const stmt = db.prepare(sql);
|
|
54
|
+
const result = stmt.run(...params);
|
|
55
|
+
return {
|
|
56
|
+
success: true,
|
|
57
|
+
rowCount: result.changes,
|
|
58
|
+
rows: [{ changes: result.changes, lastInsertRowid: result.lastInsertRowid }]
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
} finally {
|
|
62
|
+
db.close();
|
|
63
|
+
}
|
|
64
|
+
} catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
success: false,
|
|
67
|
+
error: `Database error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// Tool: db_query
|
|
74
|
+
// ============================================================================
|
|
75
|
+
|
|
76
|
+
server.tool(
|
|
77
|
+
"db_query",
|
|
78
|
+
"Execute a read-only SQL query (SELECT only for safety)",
|
|
79
|
+
{
|
|
80
|
+
sql: z.string().describe("SQL SELECT query to execute"),
|
|
81
|
+
limit: z.number().optional().describe("Max rows to return (default: 100)"),
|
|
82
|
+
},
|
|
83
|
+
async ({ sql, limit = 100 }) => {
|
|
84
|
+
// Security: Only allow SELECT queries
|
|
85
|
+
const trimmedSql = sql.trim().toUpperCase();
|
|
86
|
+
if (!trimmedSql.startsWith("SELECT")) {
|
|
87
|
+
return {
|
|
88
|
+
content: [{
|
|
89
|
+
type: "text",
|
|
90
|
+
text: JSON.stringify({
|
|
91
|
+
error: "Only SELECT queries are allowed. Use db_execute for writes."
|
|
92
|
+
}),
|
|
93
|
+
}],
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Add LIMIT if not present
|
|
98
|
+
let safeSql = sql;
|
|
99
|
+
if (!trimmedSql.includes("LIMIT")) {
|
|
100
|
+
safeSql = `${sql} LIMIT ${limit}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const result = await executeSqliteQuery(safeSql);
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
content: [{
|
|
107
|
+
type: "text",
|
|
108
|
+
text: JSON.stringify(result, null, 2),
|
|
109
|
+
}],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
// ============================================================================
|
|
115
|
+
// Tool: db_schema
|
|
116
|
+
// ============================================================================
|
|
117
|
+
|
|
118
|
+
server.tool(
|
|
119
|
+
"db_schema",
|
|
120
|
+
"Get database schema (tables and columns)",
|
|
121
|
+
{},
|
|
122
|
+
async () => {
|
|
123
|
+
const result = await executeSqliteQuery(`
|
|
124
|
+
SELECT
|
|
125
|
+
m.name as table_name,
|
|
126
|
+
p.name as column_name,
|
|
127
|
+
p.type as column_type
|
|
128
|
+
FROM sqlite_master m
|
|
129
|
+
JOIN pragma_table_info(m.name) p
|
|
130
|
+
WHERE m.type = 'table' AND m.name NOT LIKE 'sqlite_%'
|
|
131
|
+
ORDER BY m.name, p.cid
|
|
132
|
+
`);
|
|
133
|
+
|
|
134
|
+
if (!result.success) {
|
|
135
|
+
return {
|
|
136
|
+
content: [{
|
|
137
|
+
type: "text",
|
|
138
|
+
text: JSON.stringify({ error: result.error }),
|
|
139
|
+
}],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Group by table
|
|
144
|
+
const tables: Record<string, Array<{ name: string; type: string }>> = {};
|
|
145
|
+
for (const row of result.rows || []) {
|
|
146
|
+
const tableName = row.table_name as string;
|
|
147
|
+
if (!tables[tableName]) {
|
|
148
|
+
tables[tableName] = [];
|
|
149
|
+
}
|
|
150
|
+
tables[tableName].push({
|
|
151
|
+
name: row.column_name as string,
|
|
152
|
+
type: row.column_type as string,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
content: [{
|
|
158
|
+
type: "text",
|
|
159
|
+
text: JSON.stringify({ tables }, null, 2),
|
|
160
|
+
}],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
// ============================================================================
|
|
166
|
+
// Tool: db_tables
|
|
167
|
+
// ============================================================================
|
|
168
|
+
|
|
169
|
+
server.tool(
|
|
170
|
+
"db_tables",
|
|
171
|
+
"List all tables in the database",
|
|
172
|
+
{},
|
|
173
|
+
async () => {
|
|
174
|
+
const result = await executeSqliteQuery(`
|
|
175
|
+
SELECT name, type
|
|
176
|
+
FROM sqlite_master
|
|
177
|
+
WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%'
|
|
178
|
+
ORDER BY name
|
|
179
|
+
`);
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
content: [{
|
|
183
|
+
type: "text",
|
|
184
|
+
text: JSON.stringify(result, null, 2),
|
|
185
|
+
}],
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
// ============================================================================
|
|
191
|
+
// Tool: db_describe
|
|
192
|
+
// ============================================================================
|
|
193
|
+
|
|
194
|
+
server.tool(
|
|
195
|
+
"db_describe",
|
|
196
|
+
"Describe a specific table's structure",
|
|
197
|
+
{
|
|
198
|
+
table: z.string().describe("Table name to describe"),
|
|
199
|
+
},
|
|
200
|
+
async ({ table }) => {
|
|
201
|
+
// Validate table name (prevent SQL injection)
|
|
202
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
|
|
203
|
+
return {
|
|
204
|
+
content: [{
|
|
205
|
+
type: "text",
|
|
206
|
+
text: JSON.stringify({ error: "Invalid table name" }),
|
|
207
|
+
}],
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const result = await executeSqliteQuery(`PRAGMA table_info(${table})`);
|
|
212
|
+
|
|
213
|
+
if (!result.success || !result.rows?.length) {
|
|
214
|
+
return {
|
|
215
|
+
content: [{
|
|
216
|
+
type: "text",
|
|
217
|
+
text: JSON.stringify({ error: `Table '${table}' not found or empty` }),
|
|
218
|
+
}],
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Get row count
|
|
223
|
+
const countResult = await executeSqliteQuery(`SELECT COUNT(*) as count FROM ${table}`);
|
|
224
|
+
const rowCount = countResult.rows?.[0]?.count || 0;
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
content: [{
|
|
228
|
+
type: "text",
|
|
229
|
+
text: JSON.stringify({
|
|
230
|
+
table,
|
|
231
|
+
columns: result.rows,
|
|
232
|
+
rowCount,
|
|
233
|
+
}, null, 2),
|
|
234
|
+
}],
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
// ============================================================================
|
|
240
|
+
// Resource: Database Info
|
|
241
|
+
// ============================================================================
|
|
242
|
+
|
|
243
|
+
server.resource(
|
|
244
|
+
"db-info",
|
|
245
|
+
"db://info",
|
|
246
|
+
async (uri) => ({
|
|
247
|
+
contents: [{
|
|
248
|
+
uri: uri.href,
|
|
249
|
+
mimeType: "application/json",
|
|
250
|
+
text: JSON.stringify({
|
|
251
|
+
type: DB_TYPE,
|
|
252
|
+
path: DB_PATH,
|
|
253
|
+
exists: fs.existsSync(DB_PATH),
|
|
254
|
+
timestamp: new Date().toISOString(),
|
|
255
|
+
}),
|
|
256
|
+
}],
|
|
257
|
+
})
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
// ============================================================================
|
|
261
|
+
// Start Server
|
|
262
|
+
// ============================================================================
|
|
263
|
+
|
|
264
|
+
async function main() {
|
|
265
|
+
const transport = new StdioServerTransport();
|
|
266
|
+
await server.connect(transport);
|
|
267
|
+
console.error("{{SERVER_NAME}} MCP Server running on stdio");
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
main().catch((error) => {
|
|
271
|
+
console.error("Failed to start MCP server:", error);
|
|
272
|
+
process.exit(1);
|
|
273
|
+
});
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* {{SERVER_NAME}} - Web Scraper MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Extract data from websites for your AI assistant.
|
|
6
|
+
*
|
|
7
|
+
* Generated by Agent Kit MCP Generator
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
|
|
14
|
+
const server = new McpServer({
|
|
15
|
+
name: "{{SERVER_NAME}}",
|
|
16
|
+
version: "1.0.0",
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Helper Functions
|
|
21
|
+
// ============================================================================
|
|
22
|
+
|
|
23
|
+
interface FetchResult {
|
|
24
|
+
success: boolean;
|
|
25
|
+
html?: string;
|
|
26
|
+
text?: string;
|
|
27
|
+
title?: string;
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function fetchPage(url: string): Promise<FetchResult> {
|
|
32
|
+
try {
|
|
33
|
+
const response = await fetch(url, {
|
|
34
|
+
headers: {
|
|
35
|
+
"User-Agent": "Mozilla/5.0 (compatible; MCPBot/1.0)",
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
error: `HTTP ${response.status}: ${response.statusText}`
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const html = await response.text();
|
|
47
|
+
|
|
48
|
+
// Extract title
|
|
49
|
+
const titleMatch = html.match(/<title[^>]*>([^<]+)<\/title>/i);
|
|
50
|
+
const title = titleMatch ? titleMatch[1].trim() : undefined;
|
|
51
|
+
|
|
52
|
+
// Extract text (basic - remove tags)
|
|
53
|
+
const text = html
|
|
54
|
+
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "")
|
|
55
|
+
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "")
|
|
56
|
+
.replace(/<[^>]+>/g, " ")
|
|
57
|
+
.replace(/\s+/g, " ")
|
|
58
|
+
.trim();
|
|
59
|
+
|
|
60
|
+
return { success: true, html, text, title };
|
|
61
|
+
} catch (error) {
|
|
62
|
+
return {
|
|
63
|
+
success: false,
|
|
64
|
+
error: `Fetch error: ${error instanceof Error ? error.message : "Unknown"}`
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// Tool: scrape_url
|
|
71
|
+
// ============================================================================
|
|
72
|
+
|
|
73
|
+
server.tool(
|
|
74
|
+
"scrape_url",
|
|
75
|
+
"Fetch and extract text content from a URL",
|
|
76
|
+
{
|
|
77
|
+
url: z.string().url().describe("URL to scrape"),
|
|
78
|
+
maxLength: z.number().optional().describe("Max text length (default: 5000)"),
|
|
79
|
+
},
|
|
80
|
+
async ({ url, maxLength = 5000 }) => {
|
|
81
|
+
const result = await fetchPage(url);
|
|
82
|
+
|
|
83
|
+
if (!result.success) {
|
|
84
|
+
return {
|
|
85
|
+
content: [{
|
|
86
|
+
type: "text",
|
|
87
|
+
text: JSON.stringify({ error: result.error }),
|
|
88
|
+
}],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const truncatedText = result.text?.slice(0, maxLength);
|
|
93
|
+
const truncated = (result.text?.length || 0) > maxLength;
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
content: [{
|
|
97
|
+
type: "text",
|
|
98
|
+
text: JSON.stringify({
|
|
99
|
+
url,
|
|
100
|
+
title: result.title,
|
|
101
|
+
text: truncatedText,
|
|
102
|
+
truncated,
|
|
103
|
+
originalLength: result.text?.length,
|
|
104
|
+
}, null, 2),
|
|
105
|
+
}],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// ============================================================================
|
|
111
|
+
// Tool: extract_links
|
|
112
|
+
// ============================================================================
|
|
113
|
+
|
|
114
|
+
server.tool(
|
|
115
|
+
"extract_links",
|
|
116
|
+
"Extract all links from a webpage",
|
|
117
|
+
{
|
|
118
|
+
url: z.string().url().describe("URL to extract links from"),
|
|
119
|
+
filter: z.string().optional().describe("Filter links containing this string"),
|
|
120
|
+
},
|
|
121
|
+
async ({ url, filter }) => {
|
|
122
|
+
const result = await fetchPage(url);
|
|
123
|
+
|
|
124
|
+
if (!result.success || !result.html) {
|
|
125
|
+
return {
|
|
126
|
+
content: [{
|
|
127
|
+
type: "text",
|
|
128
|
+
text: JSON.stringify({ error: result.error }),
|
|
129
|
+
}],
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Extract href attributes
|
|
134
|
+
const linkRegex = /href=["']([^"']+)["']/gi;
|
|
135
|
+
const links: string[] = [];
|
|
136
|
+
let match;
|
|
137
|
+
|
|
138
|
+
while ((match = linkRegex.exec(result.html)) !== null) {
|
|
139
|
+
let href = match[1];
|
|
140
|
+
|
|
141
|
+
// Convert relative URLs to absolute
|
|
142
|
+
if (href.startsWith("/")) {
|
|
143
|
+
const urlObj = new URL(url);
|
|
144
|
+
href = `${urlObj.origin}${href}`;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Filter if specified
|
|
148
|
+
if (filter && !href.includes(filter)) continue;
|
|
149
|
+
|
|
150
|
+
// Skip non-http links
|
|
151
|
+
if (!href.startsWith("http")) continue;
|
|
152
|
+
|
|
153
|
+
if (!links.includes(href)) {
|
|
154
|
+
links.push(href);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
content: [{
|
|
160
|
+
type: "text",
|
|
161
|
+
text: JSON.stringify({
|
|
162
|
+
url,
|
|
163
|
+
links: links.slice(0, 50), // Limit to 50
|
|
164
|
+
count: links.length,
|
|
165
|
+
}, null, 2),
|
|
166
|
+
}],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
// ============================================================================
|
|
172
|
+
// Tool: extract_metadata
|
|
173
|
+
// ============================================================================
|
|
174
|
+
|
|
175
|
+
server.tool(
|
|
176
|
+
"extract_metadata",
|
|
177
|
+
"Extract metadata (title, description, og tags) from a webpage",
|
|
178
|
+
{
|
|
179
|
+
url: z.string().url().describe("URL to extract metadata from"),
|
|
180
|
+
},
|
|
181
|
+
async ({ url }) => {
|
|
182
|
+
const result = await fetchPage(url);
|
|
183
|
+
|
|
184
|
+
if (!result.success || !result.html) {
|
|
185
|
+
return {
|
|
186
|
+
content: [{
|
|
187
|
+
type: "text",
|
|
188
|
+
text: JSON.stringify({ error: result.error }),
|
|
189
|
+
}],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const html = result.html;
|
|
194
|
+
|
|
195
|
+
// Extract meta tags
|
|
196
|
+
const getMeta = (name: string): string | undefined => {
|
|
197
|
+
const match = html.match(
|
|
198
|
+
new RegExp(`<meta[^>]*(?:name|property)=["']${name}["'][^>]*content=["']([^"']+)["']`, "i")
|
|
199
|
+
) || html.match(
|
|
200
|
+
new RegExp(`<meta[^>]*content=["']([^"']+)["'][^>]*(?:name|property)=["']${name}["']`, "i")
|
|
201
|
+
);
|
|
202
|
+
return match?.[1];
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const metadata = {
|
|
206
|
+
url,
|
|
207
|
+
title: result.title,
|
|
208
|
+
description: getMeta("description"),
|
|
209
|
+
ogTitle: getMeta("og:title"),
|
|
210
|
+
ogDescription: getMeta("og:description"),
|
|
211
|
+
ogImage: getMeta("og:image"),
|
|
212
|
+
ogType: getMeta("og:type"),
|
|
213
|
+
twitterCard: getMeta("twitter:card"),
|
|
214
|
+
twitterTitle: getMeta("twitter:title"),
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
content: [{
|
|
219
|
+
type: "text",
|
|
220
|
+
text: JSON.stringify(metadata, null, 2),
|
|
221
|
+
}],
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
// ============================================================================
|
|
227
|
+
// Start Server
|
|
228
|
+
// ============================================================================
|
|
229
|
+
|
|
230
|
+
async function main() {
|
|
231
|
+
const transport = new StdioServerTransport();
|
|
232
|
+
await server.connect(transport);
|
|
233
|
+
console.error("{{SERVER_NAME}} MCP Server running on stdio");
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
main().catch((error) => {
|
|
237
|
+
console.error("Failed to start MCP server:", error);
|
|
238
|
+
process.exit(1);
|
|
239
|
+
});
|