MCP Builder by yldgio/vibe-vscode
npx skills add https://github.com/yldgio/vibe-vscode --skill 'MCP Builder'此技能可帮助您创建模型上下文协议 (MCP) 服务器,通过自定义工具、资源和数据源来扩展 GitHub Copilot 和 AI 代理的能力。
在以下情况下使用此技能:
模型上下文协议 (MCP) 是一种开放协议,用于标准化像 GitHub Copilot 这样的 AI 应用程序如何连接到数据源和工具。它允许您:
# 创建新的 MCP 服务器
npm init -y
npm install @modelcontextprotocol/sdk
# 或使用 TypeScript
npm install --save-dev typescript @types/node
npx tsc --init
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
// 创建服务器
const server = new Server(
{
name: "example-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// 注册工具处理器
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "get-weather",
description: "获取指定位置的当前天气",
inputSchema: {
type: "object",
properties: {
location: {
type: "string",
description: "城市名称或邮政编码",
},
},
required: ["location"],
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "get-weather") {
const { location } = request.params.arguments as { location: string };
// 模拟天气数据(替换为实际的 API 调用)
const weather = {
location,
temperature: 72,
condition: "Sunny",
humidity: 45,
};
return {
content: [
{
type: "text",
text: JSON.stringify(weather, null, 2),
},
],
};
}
throw new Error(`Unknown tool: ${request.params.name}`);
});
// 启动服务器
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Weather MCP server running on stdio");
}
main().catch((error) => {
console.error("Server error:", error);
process.exit(1);
});
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
import axios from "axios";
// GitHub 仓库信息工具
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "get-repo-info",
description: "获取 GitHub 仓库信息",
inputSchema: {
type: "object",
properties: {
owner: {
type: "string",
description: "仓库所有者(用户名或组织)",
},
repo: {
type: "string",
description: "仓库名称",
},
},
required: ["owner", "repo"],
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "get-repo-info") {
const { owner, repo } = request.params.arguments as {
owner: string;
repo: string;
};
try {
const response = await axios.get(
`https://api.github.com/repos/${owner}/${repo}`
);
const info = {
name: response.data.name,
description: response.data.description,
stars: response.data.stargazers_count,
forks: response.data.forks_count,
language: response.data.language,
url: response.data.html_url,
};
return {
content: [
{
type: "text",
text: JSON.stringify(info, null, 2),
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: `Error fetching repository: ${error.message}`,
},
],
isError: true,
};
}
}
throw new Error(`Unknown tool: ${request.params.name}`);
});
import { Pool } from "pg";
const pool = new Pool({
host: process.env.DB_HOST,
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
});
// 数据库查询工具
{
name: "query-customers",
description: "查询客户数据库",
inputSchema: {
type: "object",
properties: {
search: {
type: "string",
description: "要搜索的客户名称或 ID",
},
limit: {
type: "number",
description: "最大结果数",
default: 10,
},
},
required: ["search"],
},
}
// 处理器
const result = await pool.query(
"SELECT id, name, email FROM customers WHERE name ILIKE $1 LIMIT $2",
[`%${search}%`, limit]
);
return {
content: [
{
type: "text",
text: JSON.stringify(result.rows, null, 2),
},
],
};
资源是 AI 可以读取的数据源:
import {
ListResourcesRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
// 启用资源功能
const server = new Server(
{
name: "docs-server",
version: "1.0.0",
},
{
capabilities: {
resources: {},
},
}
);
// 列出可用资源
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{
uri: "docs://api-reference",
name: "API 参考文档",
description: "完整的 API 文档",
mimeType: "text/plain",
},
{
uri: "docs://getting-started",
name: "入门指南",
description: "新用户快速入门指南",
mimeType: "text/plain",
},
],
};
});
// 读取资源内容
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const uri = request.params.uri;
if (uri === "docs://api-reference") {
const content = await loadApiDocs();
return {
contents: [
{
uri,
mimeType: "text/plain",
text: content,
},
],
};
}
if (uri === "docs://getting-started") {
const content = await loadGettingStarted();
return {
contents: [
{
uri,
mimeType: "text/plain",
text: content,
},
],
};
}
throw new Error(`Unknown resource: ${uri}`);
});
提示是可重用的模板:
import {
ListPromptsRequestSchema,
GetPromptRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
// 启用提示功能
const server = new Server(
{
name: "prompt-server",
version: "1.0.0",
},
{
capabilities: {
prompts: {},
},
}
);
// 列出可用提示
server.setRequestHandler(ListPromptsRequestSchema, async () => {
return {
prompts: [
{
name: "code-review",
description: "审查代码质量和最佳实践",
arguments: [
{
name: "language",
description: "编程语言",
required: true,
},
{
name: "code",
description: "要审查的代码",
required: true,
},
],
},
{
name: "summarize-text",
description: "将长文本总结为要点",
arguments: [
{
name: "text",
description: "要总结的文本",
required: true,
},
{
name: "length",
description: "期望的总结长度(short/medium/long)",
required: false,
},
],
},
],
};
});
// 获取提示内容
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
if (request.params.name === "code-review") {
const { language, code } = request.params.arguments as {
language: string;
code: string;
};
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `Review this ${language} code for:
1. Code quality and readability
2. Best practices
3. Potential bugs
4. Security issues
5. Performance concerns
Code:
\`\`\`${language}
${code}
\`\`\`
Provide specific, actionable feedback.`,
},
},
],
};
}
if (request.params.name === "summarize-text") {
const { text, length = "medium" } = request.params.arguments as {
text: string;
length?: string;
};
const lengthGuide = {
short: "3-5 bullet points",
medium: "1-2 paragraphs",
long: "detailed summary with sections",
};
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `Summarize the following text into ${lengthGuide[length]}:
${text}`,
},
},
],
};
}
throw new Error(`Unknown prompt: ${request.params.name}`);
});
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
ListResourcesRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import * as fs from "fs/promises";
import * as path from "path";
class FileSystemServer {
private server: Server;
private rootPath: string;
constructor(rootPath: string) {
this.rootPath = rootPath;
this.server = new Server(
{
name: "filesystem-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
resources: {},
},
}
);
this.setupHandlers();
}
private setupHandlers() {
// 列出工具
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "read-file",
description: "读取文件内容",
inputSchema: {
type: "object",
properties: {
path: { type: "string", description: "文件路径" },
},
required: ["path"],
},
},
{
name: "write-file",
description: "将内容写入文件",
inputSchema: {
type: "object",
properties: {
path: { type: "string", description: "文件路径" },
content: { type: "string", description: "文件内容" },
},
required: ["path", "content"],
},
},
{
name: "list-directory",
description: "列出目录中的文件",
inputSchema: {
type: "object",
properties: {
path: { type: "string", description: "目录路径" },
},
required: ["path"],
},
},
],
};
});
// 处理工具调用
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case "read-file":
return this.readFile(args.path as string);
case "write-file":
return this.writeFile(args.path as string, args.content as string);
case "list-directory":
return this.listDirectory(args.path as string);
default:
throw new Error(`Unknown tool: ${name}`);
}
});
// 列出资源
this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
const files = await this.getAllFiles(this.rootPath);
return {
resources: files.map((filePath) => ({
uri: `file://${filePath}`,
name: path.basename(filePath),
description: `File: ${path.relative(this.rootPath, filePath)}`,
mimeType: "text/plain",
})),
};
});
// 读取资源
this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const uri = request.params.uri;
if (uri.startsWith("file://")) {
const filePath = uri.slice(7);
const content = await fs.readFile(filePath, "utf-8");
return {
contents: [
{
uri,
mimeType: "text/plain",
text: content,
},
],
};
}
throw new Error(`Unknown resource: ${uri}`);
});
}
private async readFile(filePath: string) {
const fullPath = path.join(this.rootPath, filePath);
const content = await fs.readFile(fullPath, "utf-8");
return {
content: [{ type: "text", text: content }],
};
}
private async writeFile(filePath: string, content: string) {
const fullPath = path.join(this.rootPath, filePath);
await fs.writeFile(fullPath, content, "utf-8");
return {
content: [{ type: "text", text: `File written: ${filePath}` }],
};
}
private async listDirectory(dirPath: string) {
const fullPath = path.join(this.rootPath, dirPath);
const entries = await fs.readdir(fullPath, { withFileTypes: true });
const list = entries.map((entry) => ({
name: entry.name,
type: entry.isDirectory() ? "directory" : "file",
}));
return {
content: [{ type: "text", text: JSON.stringify(list, null, 2) }],
};
}
private async getAllFiles(dir: string): Promise<string[]> {
const entries = await fs.readdir(dir, { withFileTypes: true });
const files = await Promise.all(
entries.map((entry) => {
const fullPath = path.join(dir, entry.name);
return entry.isDirectory() ? this.getAllFiles(fullPath) : [fullPath];
})
);
return files.flat();
}
async start() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error("Filesystem MCP server running");
}
}
// 运行服务器
const server = new FileSystemServer(process.env.ROOT_PATH || "./");
server.start().catch(console.error);
将您的 MCP 服务器添加到 VS Code 设置中以供 GitHub Copilot 使用:
选项 1:VS Code settings.json
{
"github.copilot.mcpServers": {
"filesystem": {
"command": "node",
"args": ["/path/to/filesystem-server/build/index.js"],
"env": {
"ROOT_PATH": "/path/to/allowed/directory"
}
}
}
}
选项 2:工作区设置
在您的项目中创建 .vscode/settings.json:
{
"github.copilot.mcpServers": {
"project-tools": {
"command": "node",
"args": ["./tools/mcp-server.js"]
}
}
}
isError: true// 测试工具处理器
import { describe, it, expect } from "vitest";
describe("Weather Tool", () => {
it("should return weather data", async () => {
const result = await server.callTool("get-weather", {
location: "San Francisco",
});
expect(result.content[0].type).toBe("text");
expect(JSON.parse(result.content[0].text)).toHaveProperty("temperature");
});
});
{
"name": "my-mcp-server",
"version": "1.0.0",
"type": "module",
"main": "build/index.js",
"bin": {
"my-mcp-server": "build/index.js"
},
"scripts": {
"build": "tsc",
"start": "node build/index.js"
}
}
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY build ./build
CMD ["node", "build/index.js"]
每周安装次数
–
仓库
GitHub 星标数
8
首次出现时间
–
安全审计
This skill helps you create Model Context Protocol (MCP) servers to extend GitHub Copilot and AI agent capabilities with custom tools, resources, and data sources.
Use this skill when you need to:
Model Context Protocol (MCP) is an open protocol that standardizes how AI applications like GitHub Copilot connect to data sources and tools. It allows you to:
# Create new MCP server
npm init -y
npm install @modelcontextprotocol/sdk
# Or with TypeScript
npm install --save-dev typescript @types/node
npx tsc --init
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
// Create server
const server = new Server(
{
name: "example-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// Register tool handlers
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "get-weather",
description: "Get current weather for a location",
inputSchema: {
type: "object",
properties: {
location: {
type: "string",
description: "City name or zip code",
},
},
required: ["location"],
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "get-weather") {
const { location } = request.params.arguments as { location: string };
// Mock weather data (replace with actual API call)
const weather = {
location,
temperature: 72,
condition: "Sunny",
humidity: 45,
};
return {
content: [
{
type: "text",
text: JSON.stringify(weather, null, 2),
},
],
};
}
throw new Error(`Unknown tool: ${request.params.name}`);
});
// Start server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Weather MCP server running on stdio");
}
main().catch((error) => {
console.error("Server error:", error);
process.exit(1);
});
import axios from "axios";
// GitHub repo info tool
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "get-repo-info",
description: "Get information about a GitHub repository",
inputSchema: {
type: "object",
properties: {
owner: {
type: "string",
description: "Repository owner (username or organization)",
},
repo: {
type: "string",
description: "Repository name",
},
},
required: ["owner", "repo"],
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "get-repo-info") {
const { owner, repo } = request.params.arguments as {
owner: string;
repo: string;
};
try {
const response = await axios.get(
`https://api.github.com/repos/${owner}/${repo}`
);
const info = {
name: response.data.name,
description: response.data.description,
stars: response.data.stargazers_count,
forks: response.data.forks_count,
language: response.data.language,
url: response.data.html_url,
};
return {
content: [
{
type: "text",
text: JSON.stringify(info, null, 2),
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: `Error fetching repository: ${error.message}`,
},
],
isError: true,
};
}
}
throw new Error(`Unknown tool: ${request.params.name}`);
});
import { Pool } from "pg";
const pool = new Pool({
host: process.env.DB_HOST,
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
});
// Database query tool
{
name: "query-customers",
description: "Query customer database",
inputSchema: {
type: "object",
properties: {
search: {
type: "string",
description: "Customer name or ID to search for",
},
limit: {
type: "number",
description: "Maximum number of results",
default: 10,
},
},
required: ["search"],
},
}
// Handler
const result = await pool.query(
"SELECT id, name, email FROM customers WHERE name ILIKE $1 LIMIT $2",
[`%${search}%`, limit]
);
return {
content: [
{
type: "text",
text: JSON.stringify(result.rows, null, 2),
},
],
};
Resources are data sources AI can read:
import {
ListResourcesRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
// Enable resources capability
const server = new Server(
{
name: "docs-server",
version: "1.0.0",
},
{
capabilities: {
resources: {},
},
}
);
// List available resources
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{
uri: "docs://api-reference",
name: "API Reference",
description: "Complete API documentation",
mimeType: "text/plain",
},
{
uri: "docs://getting-started",
name: "Getting Started Guide",
description: "Quick start guide for new users",
mimeType: "text/plain",
},
],
};
});
// Read resource content
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const uri = request.params.uri;
if (uri === "docs://api-reference") {
const content = await loadApiDocs();
return {
contents: [
{
uri,
mimeType: "text/plain",
text: content,
},
],
};
}
if (uri === "docs://getting-started") {
const content = await loadGettingStarted();
return {
contents: [
{
uri,
mimeType: "text/plain",
text: content,
},
],
};
}
throw new Error(`Unknown resource: ${uri}`);
});
Prompts are reusable templates:
import {
ListPromptsRequestSchema,
GetPromptRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
// Enable prompts capability
const server = new Server(
{
name: "prompt-server",
version: "1.0.0",
},
{
capabilities: {
prompts: {},
},
}
);
// List available prompts
server.setRequestHandler(ListPromptsRequestSchema, async () => {
return {
prompts: [
{
name: "code-review",
description: "Review code for quality and best practices",
arguments: [
{
name: "language",
description: "Programming language",
required: true,
},
{
name: "code",
description: "Code to review",
required: true,
},
],
},
{
name: "summarize-text",
description: "Summarize long text into key points",
arguments: [
{
name: "text",
description: "Text to summarize",
required: true,
},
{
name: "length",
description: "Desired summary length (short/medium/long)",
required: false,
},
],
},
],
};
});
// Get prompt content
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
if (request.params.name === "code-review") {
const { language, code } = request.params.arguments as {
language: string;
code: string;
};
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `Review this ${language} code for:
1. Code quality and readability
2. Best practices
3. Potential bugs
4. Security issues
5. Performance concerns
Code:
\`\`\`${language}
${code}
\`\`\`
Provide specific, actionable feedback.`,
},
},
],
};
}
if (request.params.name === "summarize-text") {
const { text, length = "medium" } = request.params.arguments as {
text: string;
length?: string;
};
const lengthGuide = {
short: "3-5 bullet points",
medium: "1-2 paragraphs",
long: "detailed summary with sections",
};
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `Summarize the following text into ${lengthGuide[length]}:
${text}`,
},
},
],
};
}
throw new Error(`Unknown prompt: ${request.params.name}`);
});
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
ListResourcesRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import * as fs from "fs/promises";
import * as path from "path";
class FileSystemServer {
private server: Server;
private rootPath: string;
constructor(rootPath: string) {
this.rootPath = rootPath;
this.server = new Server(
{
name: "filesystem-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
resources: {},
},
}
);
this.setupHandlers();
}
private setupHandlers() {
// List tools
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "read-file",
description: "Read contents of a file",
inputSchema: {
type: "object",
properties: {
path: { type: "string", description: "File path" },
},
required: ["path"],
},
},
{
name: "write-file",
description: "Write contents to a file",
inputSchema: {
type: "object",
properties: {
path: { type: "string", description: "File path" },
content: { type: "string", description: "File content" },
},
required: ["path", "content"],
},
},
{
name: "list-directory",
description: "List files in a directory",
inputSchema: {
type: "object",
properties: {
path: { type: "string", description: "Directory path" },
},
required: ["path"],
},
},
],
};
});
// Handle tool calls
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case "read-file":
return this.readFile(args.path as string);
case "write-file":
return this.writeFile(args.path as string, args.content as string);
case "list-directory":
return this.listDirectory(args.path as string);
default:
throw new Error(`Unknown tool: ${name}`);
}
});
// List resources
this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
const files = await this.getAllFiles(this.rootPath);
return {
resources: files.map((filePath) => ({
uri: `file://${filePath}`,
name: path.basename(filePath),
description: `File: ${path.relative(this.rootPath, filePath)}`,
mimeType: "text/plain",
})),
};
});
// Read resource
this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const uri = request.params.uri;
if (uri.startsWith("file://")) {
const filePath = uri.slice(7);
const content = await fs.readFile(filePath, "utf-8");
return {
contents: [
{
uri,
mimeType: "text/plain",
text: content,
},
],
};
}
throw new Error(`Unknown resource: ${uri}`);
});
}
private async readFile(filePath: string) {
const fullPath = path.join(this.rootPath, filePath);
const content = await fs.readFile(fullPath, "utf-8");
return {
content: [{ type: "text", text: content }],
};
}
private async writeFile(filePath: string, content: string) {
const fullPath = path.join(this.rootPath, filePath);
await fs.writeFile(fullPath, content, "utf-8");
return {
content: [{ type: "text", text: `File written: ${filePath}` }],
};
}
private async listDirectory(dirPath: string) {
const fullPath = path.join(this.rootPath, dirPath);
const entries = await fs.readdir(fullPath, { withFileTypes: true });
const list = entries.map((entry) => ({
name: entry.name,
type: entry.isDirectory() ? "directory" : "file",
}));
return {
content: [{ type: "text", text: JSON.stringify(list, null, 2) }],
};
}
private async getAllFiles(dir: string): Promise<string[]> {
const entries = await fs.readdir(dir, { withFileTypes: true });
const files = await Promise.all(
entries.map((entry) => {
const fullPath = path.join(dir, entry.name);
return entry.isDirectory() ? this.getAllFiles(fullPath) : [fullPath];
})
);
return files.flat();
}
async start() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error("Filesystem MCP server running");
}
}
// Run server
const server = new FileSystemServer(process.env.ROOT_PATH || "./");
server.start().catch(console.error);
Add your MCP server to VS Code settings for GitHub Copilot:
Option 1: VS Code settings.json
{
"github.copilot.mcpServers": {
"filesystem": {
"command": "node",
"args": ["/path/to/filesystem-server/build/index.js"],
"env": {
"ROOT_PATH": "/path/to/allowed/directory"
}
}
}
}
Option 2: Workspace settings
Create .vscode/settings.json in your project:
{
"github.copilot.mcpServers": {
"project-tools": {
"command": "node",
"args": ["./tools/mcp-server.js"]
}
}
}
isError: true for error responses// Test tool handler
import { describe, it, expect } from "vitest";
describe("Weather Tool", () => {
it("should return weather data", async () => {
const result = await server.callTool("get-weather", {
location: "San Francisco",
});
expect(result.content[0].type).toBe("text");
expect(JSON.parse(result.content[0].text)).toHaveProperty("temperature");
});
});
{
"name": "my-mcp-server",
"version": "1.0.0",
"type": "module",
"main": "build/index.js",
"bin": {
"my-mcp-server": "build/index.js"
},
"scripts": {
"build": "tsc",
"start": "node build/index.js"
}
}
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY build ./build
CMD ["node", "build/index.js"]
Weekly Installs
–
Repository
GitHub Stars
8
First Seen
–
Security Audits
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
150,000 周安装
PocketBase 最佳实践指南:42条关键规则,涵盖集合设计、API安全与性能优化
206 周安装
Python模块化代码组织指南:文件大小、分割方法与最佳实践
206 周安装
房地产专家系统:MLS集成、虚拟看房、AI估值与物业管理技术解决方案
206 周安装
TypeScript/JavaScript 开发技能 - 掌握 Metabase 开源项目开发流程与工具
206 周安装
Upstash Redis SDK 完整指南 - Redis-JS 安装、使用与性能优化教程
206 周安装
Tavily API 网络搜索技能 - 实现网页爬取、内容提取和智能研究功能
206 周安装