skillsmp-mcp-lite 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SkillsMP
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # SkillsMP MCP Server
2
+
3
+ An MCP (Model Context Protocol) server that enables AI assistants to search for skills from [SkillsMP](https://skillsmp.com) marketplace before starting any task.
4
+
5
+ ## Features
6
+
7
+ - **Keyword Search**: Search skills using specific keywords like "PDF", "web scraper", "SEO"
8
+ - **AI Semantic Search**: Find skills using natural language descriptions powered by Cloudflare AI
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install
14
+ npm run build
15
+ ```
16
+
17
+ ## Configuration
18
+
19
+ ### Environment Variables
20
+
21
+ | Variable | Required | Description |
22
+ | ------------------ | -------- | --------------------- |
23
+ | `SKILLSMP_API_KEY` | Yes | Your SkillsMP API key |
24
+
25
+ Get your API key from: https://skillsmp.com/docs/api
26
+
27
+ ### VS Code / Cursor Setup
28
+
29
+ Add to your `settings.json`:
30
+
31
+ ```json
32
+ {
33
+ "mcp": {
34
+ "servers": {
35
+ "skillsmp": {
36
+ "command": "node",
37
+ "args": ["path/to/skillsmp-mcp-server/dist/index.js"],
38
+ "env": {
39
+ "SKILLSMP_API_KEY": "sk_live_skillsmp_YOUR_API_KEY"
40
+ }
41
+ }
42
+ }
43
+ }
44
+ }
45
+ ```
46
+
47
+ ### Claude Desktop Setup
48
+
49
+ Add to your `claude_desktop_config.json`:
50
+
51
+ ```json
52
+ {
53
+ "mcpServers": {
54
+ "skillsmp": {
55
+ "command": "node",
56
+ "args": ["/absolute/path/to/skillsmp-mcp-server/dist/index.js"],
57
+ "env": {
58
+ "SKILLSMP_API_KEY": "sk_live_skillsmp_YOUR_API_KEY"
59
+ }
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ ## Available Tools
66
+
67
+ ### `skillsmp_search_skills`
68
+
69
+ Search for skills using keywords.
70
+
71
+ **Parameters:**
72
+
73
+ - `query` (string, required): Search keywords
74
+ - `page` (number, optional): Page number (default: 1)
75
+ - `limit` (number, optional): Items per page (default: 20, max: 100)
76
+ - `sortBy` (string, optional): Sort by "stars" or "recent"
77
+
78
+ **Example:**
79
+
80
+ ```
81
+ Search for "PDF manipulation" skills
82
+ ```
83
+
84
+ ### `skillsmp_ai_search_skills`
85
+
86
+ AI semantic search for skills using natural language.
87
+
88
+ **Parameters:**
89
+
90
+ - `query` (string, required): Natural language description of what you want to accomplish
91
+
92
+ **Example:**
93
+
94
+ ```
95
+ Find skills for "How to create a web scraper that extracts product data"
96
+ ```
97
+
98
+ ## Usage Workflow
99
+
100
+ The recommended workflow is:
101
+
102
+ 1. **Before starting any task**, search for relevant skills
103
+ 2. If a matching skill is found, use `npx openskills read <skill-name>` to load it
104
+ 3. Follow the skill's instructions to complete the task
105
+
106
+ ## API Reference
107
+
108
+ This server uses the SkillsMP REST API:
109
+
110
+ - `GET /api/v1/skills/search` - Keyword search
111
+ - `GET /api/v1/skills/ai-search` - AI semantic search
112
+
113
+ ## License
114
+
115
+ MIT
package/dist/api.d.ts ADDED
@@ -0,0 +1,80 @@
1
+ /**
2
+ * SkillsMP API Client and Types
3
+ */
4
+ export declare const SKILLSMP_API_BASE = "https://skillsmp.com/api/v1";
5
+ export interface Skill {
6
+ id: string;
7
+ name: string;
8
+ description: string;
9
+ author?: string;
10
+ stars?: number;
11
+ updatedAt?: number;
12
+ tags?: string[];
13
+ githubUrl?: string;
14
+ skillUrl?: string;
15
+ }
16
+ export interface Pagination {
17
+ page: number;
18
+ limit: number;
19
+ total: number;
20
+ totalPages: number;
21
+ hasNext: boolean;
22
+ hasPrev: boolean;
23
+ }
24
+ export interface SearchResponse {
25
+ success: boolean;
26
+ data: {
27
+ skills: Skill[];
28
+ pagination: Pagination;
29
+ filters?: {
30
+ search: string;
31
+ sortBy: string;
32
+ };
33
+ };
34
+ meta?: {
35
+ requestId: string;
36
+ responseTimeMs: number;
37
+ };
38
+ }
39
+ export interface AISearchResponse {
40
+ success: boolean;
41
+ data: {
42
+ object: string;
43
+ search_query: string;
44
+ data: Array<{
45
+ file_id: string;
46
+ filename: string;
47
+ score: number;
48
+ skill?: Skill;
49
+ }>;
50
+ has_more: boolean;
51
+ next_page: string | null;
52
+ };
53
+ meta?: {
54
+ requestId: string;
55
+ responseTimeMs: number;
56
+ };
57
+ }
58
+ export interface ApiError {
59
+ success: false;
60
+ error: {
61
+ code: string;
62
+ message: string;
63
+ };
64
+ }
65
+ export declare function makeApiRequest<T>(endpoint: string, apiKey: string, params?: Record<string, string | number>): Promise<T>;
66
+ /**
67
+ * Validate search response structure
68
+ */
69
+ export declare function validateSearchResponse(data: unknown): asserts data is SearchResponse;
70
+ /**
71
+ * Validate AI search response structure
72
+ */
73
+ export declare function validateAISearchResponse(data: unknown): asserts data is AISearchResponse;
74
+ /**
75
+ * Custom error for API structure changes
76
+ */
77
+ export declare class ApiStructureError extends Error {
78
+ constructor(message: string);
79
+ }
80
+ export declare function handleApiError(error: unknown): string;
package/dist/api.js ADDED
@@ -0,0 +1,95 @@
1
+ /**
2
+ * SkillsMP API Client and Types
3
+ */
4
+ // API Configuration
5
+ export const SKILLSMP_API_BASE = "https://skillsmp.com/api/v1";
6
+ // API Client
7
+ export async function makeApiRequest(endpoint, apiKey, params) {
8
+ const url = new URL(`${SKILLSMP_API_BASE}/${endpoint}`);
9
+ if (params) {
10
+ Object.entries(params).forEach(([key, value]) => {
11
+ if (value !== undefined && value !== null) {
12
+ url.searchParams.append(key, String(value));
13
+ }
14
+ });
15
+ }
16
+ const response = await fetch(url.toString(), {
17
+ method: "GET",
18
+ headers: {
19
+ "Authorization": `Bearer ${apiKey}`,
20
+ "Content-Type": "application/json"
21
+ }
22
+ });
23
+ if (!response.ok) {
24
+ const errorData = await response.json().catch(() => ({}));
25
+ throw new Error(errorData.error?.message ||
26
+ `API request failed with status ${response.status}`);
27
+ }
28
+ return response.json();
29
+ }
30
+ /**
31
+ * Validate base response structure (shared logic)
32
+ */
33
+ function validateBaseResponse(data) {
34
+ if (!data || typeof data !== 'object') {
35
+ throw new ApiStructureError('Invalid response: expected object');
36
+ }
37
+ const response = data;
38
+ if (typeof response.success !== 'boolean') {
39
+ throw new ApiStructureError('Invalid response: missing "success" field');
40
+ }
41
+ if (!response.success) {
42
+ throw new ApiStructureError(`API returned failure: ${JSON.stringify(response)}`);
43
+ }
44
+ if (!response.data || typeof response.data !== 'object') {
45
+ throw new ApiStructureError('Invalid response: missing "data" object');
46
+ }
47
+ return response.data;
48
+ }
49
+ /**
50
+ * Validate search response structure
51
+ */
52
+ export function validateSearchResponse(data) {
53
+ const responseData = validateBaseResponse(data);
54
+ if (!Array.isArray(responseData.skills)) {
55
+ throw new ApiStructureError('Invalid response structure: expected "data.skills" array. ' +
56
+ `Got: ${JSON.stringify(Object.keys(responseData))}. ` +
57
+ 'The SkillsMP API structure may have changed.');
58
+ }
59
+ }
60
+ /**
61
+ * Validate AI search response structure
62
+ */
63
+ export function validateAISearchResponse(data) {
64
+ const responseData = validateBaseResponse(data);
65
+ if (!Array.isArray(responseData.data)) {
66
+ throw new ApiStructureError('Invalid AI search response structure: expected "data.data" array. ' +
67
+ `Got: ${JSON.stringify(Object.keys(responseData))}. ` +
68
+ 'The SkillsMP API structure may have changed.');
69
+ }
70
+ }
71
+ /**
72
+ * Custom error for API structure changes
73
+ */
74
+ export class ApiStructureError extends Error {
75
+ constructor(message) {
76
+ super(message);
77
+ this.name = 'ApiStructureError';
78
+ }
79
+ }
80
+ // Error Handler
81
+ export function handleApiError(error) {
82
+ if (error instanceof ApiStructureError) {
83
+ return `⚠️ API Structure Error: ${error.message}\n\nThis likely means the SkillsMP API has changed. Please report this issue.`;
84
+ }
85
+ if (error instanceof Error) {
86
+ if (error.message.includes("401")) {
87
+ return "Error: Invalid or missing API key. Please check your SKILLSMP_API_KEY environment variable.";
88
+ }
89
+ if (error.message.includes("429")) {
90
+ return "Error: Rate limit exceeded. Please wait before making more requests.";
91
+ }
92
+ return `Error: ${error.message}`;
93
+ }
94
+ return "Error: An unexpected error occurred";
95
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { registerSkillsTools } from "./tools/skills.js";
5
+ /**
6
+ * SkillsMP MCP Server
7
+ *
8
+ * This server provides tools to search for AI skills from SkillsMP marketplace
9
+ * before starting any task. It supports both keyword search and AI semantic search.
10
+ *
11
+ * Environment Variables:
12
+ * SKILLSMP_API_KEY - Your SkillsMP API key (required)
13
+ */
14
+ const API_KEY = process.env.SKILLSMP_API_KEY;
15
+ if (!API_KEY) {
16
+ console.error("Error: SKILLSMP_API_KEY environment variable is required");
17
+ console.error("Get your API key from: https://skillsmp.com/docs/api");
18
+ process.exit(1);
19
+ }
20
+ // Initialize MCP Server
21
+ const server = new McpServer({
22
+ name: "skillsmp-mcp-server",
23
+ version: "1.0.0"
24
+ });
25
+ // Register skills search tools
26
+ registerSkillsTools(server, API_KEY);
27
+ // Start server with stdio transport
28
+ async function main() {
29
+ const transport = new StdioServerTransport();
30
+ await server.connect(transport);
31
+ console.error("SkillsMP MCP Server started");
32
+ console.error("Available tools:");
33
+ console.error(" - skillsmp_search_skills: Keyword search for skills");
34
+ console.error(" - skillsmp_ai_search_skills: AI semantic search for skills");
35
+ }
36
+ main().catch((error) => {
37
+ console.error("Failed to start server:", error);
38
+ process.exit(1);
39
+ });
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Zod Schemas for SkillsMP Tools
4
+ */
5
+ export declare enum SortBy {
6
+ STARS = "stars",
7
+ RECENT = "recent"
8
+ }
9
+ export declare const KeywordSearchSchema: z.ZodObject<{
10
+ query: z.ZodString;
11
+ page: z.ZodDefault<z.ZodNumber>;
12
+ limit: z.ZodDefault<z.ZodNumber>;
13
+ sortBy: z.ZodOptional<z.ZodNativeEnum<typeof SortBy>>;
14
+ }, "strict", z.ZodTypeAny, {
15
+ query: string;
16
+ page: number;
17
+ limit: number;
18
+ sortBy?: SortBy | undefined;
19
+ }, {
20
+ query: string;
21
+ page?: number | undefined;
22
+ limit?: number | undefined;
23
+ sortBy?: SortBy | undefined;
24
+ }>;
25
+ export type KeywordSearchInput = z.infer<typeof KeywordSearchSchema>;
26
+ export declare const AISearchSchema: z.ZodObject<{
27
+ query: z.ZodString;
28
+ }, "strict", z.ZodTypeAny, {
29
+ query: string;
30
+ }, {
31
+ query: string;
32
+ }>;
33
+ export type AISearchInput = z.infer<typeof AISearchSchema>;
@@ -0,0 +1,38 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Zod Schemas for SkillsMP Tools
4
+ */
5
+ // Sort options enum
6
+ export var SortBy;
7
+ (function (SortBy) {
8
+ SortBy["STARS"] = "stars";
9
+ SortBy["RECENT"] = "recent";
10
+ })(SortBy || (SortBy = {}));
11
+ // Keyword Search Schema
12
+ export const KeywordSearchSchema = z.object({
13
+ query: z.string()
14
+ .min(1, "Query is required")
15
+ .max(200, "Query must not exceed 200 characters")
16
+ .describe("Search keywords for finding skills"),
17
+ page: z.number()
18
+ .int()
19
+ .min(1)
20
+ .default(1)
21
+ .describe("Page number (default: 1)"),
22
+ limit: z.number()
23
+ .int()
24
+ .min(1)
25
+ .max(100)
26
+ .default(20)
27
+ .describe("Items per page (default: 20, max: 100)"),
28
+ sortBy: z.nativeEnum(SortBy)
29
+ .optional()
30
+ .describe("Sort by: 'stars' or 'recent'")
31
+ }).strict();
32
+ // AI Semantic Search Schema
33
+ export const AISearchSchema = z.object({
34
+ query: z.string()
35
+ .min(1, "Query is required")
36
+ .max(500, "Query must not exceed 500 characters")
37
+ .describe("Natural language description of what you want to accomplish")
38
+ }).strict();
@@ -0,0 +1,5 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ /**
3
+ * Register SkillsMP tools on the MCP server
4
+ */
5
+ export declare function registerSkillsTools(server: McpServer, apiKey: string): void;
@@ -0,0 +1,210 @@
1
+ import { makeApiRequest, handleApiError, validateSearchResponse, validateAISearchResponse } from "../api.js";
2
+ import { KeywordSearchSchema, AISearchSchema } from "../schemas.js";
3
+ /**
4
+ * Register SkillsMP tools on the MCP server
5
+ */
6
+ export function registerSkillsTools(server, apiKey) {
7
+ // Tool 1: Keyword Search
8
+ server.registerTool("skillsmp_search_skills", {
9
+ title: "Search SkillsMP Skills",
10
+ description: `Search for AI skills using keywords from SkillsMP marketplace.
11
+
12
+ Use this tool to find skills by specific terms like 'SEO', 'web scraper', 'PDF', 'data analysis', etc.
13
+
14
+ **IMPORTANT**: Before starting any task, use this tool to check if there's an existing skill that can help complete the task more effectively.
15
+
16
+ Args:
17
+ - query (string, required): Search keywords
18
+ - page (number, optional): Page number (default: 1)
19
+ - limit (number, optional): Items per page (default: 20, max: 100)
20
+ - sortBy (string, optional): Sort by 'stars' or 'recent'
21
+
22
+ Returns:
23
+ List of matching skills with name, description, author, and star count.
24
+
25
+ Examples:
26
+ - "PDF manipulation" -> Find skills for working with PDFs
27
+ - "web scraper" -> Find web scraping skills
28
+ - "SEO optimization" -> Find SEO-related skills`,
29
+ inputSchema: KeywordSearchSchema,
30
+ annotations: {
31
+ readOnlyHint: true,
32
+ destructiveHint: false,
33
+ idempotentHint: true,
34
+ openWorldHint: true
35
+ }
36
+ }, async (params) => {
37
+ try {
38
+ const queryParams = {
39
+ q: params.query
40
+ };
41
+ if (params.page)
42
+ queryParams.page = params.page;
43
+ if (params.limit)
44
+ queryParams.limit = params.limit;
45
+ if (params.sortBy)
46
+ queryParams.sortBy = params.sortBy;
47
+ const rawData = await makeApiRequest("skills/search", apiKey, queryParams);
48
+ // Validate API response structure before processing
49
+ validateSearchResponse(rawData);
50
+ const skills = rawData.data?.skills || [];
51
+ const pagination = rawData.data?.pagination;
52
+ if (!skills.length) {
53
+ return {
54
+ content: [{
55
+ type: "text",
56
+ text: `No skills found matching '${params.query}'. Try different keywords or use AI semantic search for natural language queries.`
57
+ }]
58
+ };
59
+ }
60
+ const output = formatSkillsResponse(skills, params.query, pagination);
61
+ return {
62
+ content: [{ type: "text", text: output }],
63
+ structuredContent: {
64
+ query: params.query,
65
+ count: skills.length,
66
+ skills: skills,
67
+ pagination: pagination
68
+ }
69
+ };
70
+ }
71
+ catch (error) {
72
+ return {
73
+ content: [{
74
+ type: "text",
75
+ text: handleApiError(error)
76
+ }]
77
+ };
78
+ }
79
+ });
80
+ // Tool 2: AI Semantic Search
81
+ server.registerTool("skillsmp_ai_search_skills", {
82
+ title: "AI Search SkillsMP Skills",
83
+ description: `AI semantic search for skills using natural language descriptions.
84
+
85
+ Use this when you need to find skills based on what you want to accomplish rather than specific keywords.
86
+
87
+ **IMPORTANT**: Before starting any complex task, use this tool to discover relevant skills that can help.
88
+
89
+ Args:
90
+ - query (string, required): Natural language description of what you want to accomplish
91
+
92
+ Returns:
93
+ List of semantically relevant skills that match your intent.
94
+
95
+ Examples:
96
+ - "How to create a web scraper" -> Find skills for web scraping
97
+ - "Build a dashboard with charts" -> Find data visualization skills
98
+ - "Generate PDF reports from data" -> Find PDF generation skills
99
+ - "Automate social media posting" -> Find social media automation skills`,
100
+ inputSchema: AISearchSchema,
101
+ annotations: {
102
+ readOnlyHint: true,
103
+ destructiveHint: false,
104
+ idempotentHint: true,
105
+ openWorldHint: true
106
+ }
107
+ }, async (params) => {
108
+ try {
109
+ const rawData = await makeApiRequest("skills/ai-search", apiKey, { q: params.query });
110
+ // Validate API response structure before processing
111
+ validateAISearchResponse(rawData);
112
+ // AI search returns results in data.data array with skill objects
113
+ const results = rawData.data?.data || [];
114
+ const skills = results
115
+ .filter(item => item.skill) // Only include items with skill data
116
+ .map(item => ({
117
+ ...item.skill,
118
+ score: item.score
119
+ }));
120
+ if (!skills.length) {
121
+ return {
122
+ content: [{
123
+ type: "text",
124
+ text: `No skills found for: "${params.query}". Try rephrasing your query or use keyword search for specific terms.`
125
+ }]
126
+ };
127
+ }
128
+ const output = formatAISearchResponse(skills, params.query);
129
+ return {
130
+ content: [{ type: "text", text: output }],
131
+ structuredContent: {
132
+ query: params.query,
133
+ count: skills.length,
134
+ skills: skills
135
+ }
136
+ };
137
+ }
138
+ catch (error) {
139
+ return {
140
+ content: [{
141
+ type: "text",
142
+ text: handleApiError(error)
143
+ }]
144
+ };
145
+ }
146
+ });
147
+ }
148
+ /**
149
+ * Render a single skill as markdown lines
150
+ */
151
+ function renderSkill(skill, index) {
152
+ const lines = [];
153
+ // Header
154
+ const header = index !== undefined ? `## ${index + 1}. ${skill.name}` : `## ${skill.name}`;
155
+ lines.push(header);
156
+ // Meta info
157
+ const meta = [];
158
+ if (skill.stars !== undefined)
159
+ meta.push(`⭐ ${skill.stars} stars`);
160
+ if (skill.score !== undefined)
161
+ meta.push(`📊 Score: ${(skill.score * 100).toFixed(1)}%`);
162
+ if (meta.length)
163
+ lines.push(meta.join(" | "));
164
+ lines.push("");
165
+ lines.push(skill.description || "No description available");
166
+ if (skill.author) {
167
+ lines.push("");
168
+ lines.push(`**Author**: ${skill.author}`);
169
+ }
170
+ if (skill.skillUrl) {
171
+ lines.push(`**URL**: ${skill.skillUrl}`);
172
+ }
173
+ if (skill.tags?.length) {
174
+ lines.push(`**Tags**: ${skill.tags.join(", ")}`);
175
+ }
176
+ lines.push("", "---", "");
177
+ return lines;
178
+ }
179
+ /**
180
+ * Format skills search response as markdown
181
+ */
182
+ function formatSkillsResponse(skills, query, pagination) {
183
+ const lines = [
184
+ `# 🔍 Skills Search Results: "${query}"`,
185
+ "",
186
+ `Found ${pagination?.total || skills.length} skill(s) (showing ${skills.length})`,
187
+ ""
188
+ ];
189
+ skills.forEach(skill => lines.push(...renderSkill(skill)));
190
+ if (pagination?.hasNext) {
191
+ lines.push(`*More results available. Call this tool again with \`page: ${pagination.page + 1}\` to see more.*`);
192
+ }
193
+ return lines.join("\n");
194
+ }
195
+ /**
196
+ * Format AI search response as markdown
197
+ */
198
+ function formatAISearchResponse(skills, query) {
199
+ const lines = [
200
+ `# 🤖 AI Semantic Search Results`,
201
+ "",
202
+ `**Query**: "${query}"`,
203
+ "",
204
+ `Found ${skills.length} relevant skill(s)`,
205
+ ""
206
+ ];
207
+ skills.forEach((skill, i) => lines.push(...renderSkill(skill, i)));
208
+ lines.push("💡 **Tip**: Use `npx openskills read <skill-name>` to load a skill's detailed instructions.");
209
+ return lines.join("\n");
210
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "skillsmp-mcp-lite",
3
+ "version": "1.0.0",
4
+ "description": "Lightweight MCP server for searching AI skills from SkillsMP before starting any task",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "skillsmp-mcp-lite": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "start": "node dist/index.js",
16
+ "dev": "tsc --watch",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "model-context-protocol",
22
+ "skills",
23
+ "ai",
24
+ "skillsmp",
25
+ "ai-skills",
26
+ "marketplace"
27
+ ],
28
+ "author": "clancylllin <poerevan9@gmail.com>",
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/boyonglin/skillsmp-mcp-lite.git"
33
+ },
34
+ "homepage": "https://github.com/boyonglin/skillsmp-mcp-lite#readme",
35
+ "bugs": {
36
+ "url": "https://github.com/boyonglin/skillsmp-mcp-lite/issues"
37
+ },
38
+ "engines": {
39
+ "node": ">=18.0.0"
40
+ },
41
+ "dependencies": {
42
+ "@modelcontextprotocol/sdk": "^1.25.0",
43
+ "zod": "^3.25.0"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^22.0.0",
47
+ "typescript": "^5.7.0"
48
+ }
49
+ }