Back to MCP directory
publicPublicdnsLocal runtime

css-mcp-server

该项目是一个基于Node.js和TypeScript构建的CSS教学MCP服务器,提供个性化CSS特性更新服务,包含资源管理、工具调用和提示引导功能。

article

README

🚀 使用Model Context Protocol构建一个简单的服务器

本项目展示了如何借助 TypeScript SDK 搭建一个基础的 MCP 服务器。此服务器具备资源管理、工具交互和提示指导等功能,能有效辅助 AI 客户端与工具、资源进行交互。

🚀 快速开始

运行服务器

  1. 克隆项目仓库到本地:

    git clone https://github.com/yourusername/css-tutor-server.git
    cd css-tutor-server
    
  2. 安装依赖项:

    npm install
    
  3. 启动服务器:

    npm start
    

调试工具

为了帮助开发者调试,项目提供了以下调试工具:

npx @modelcontextprotocol/inspector

运行上述命令后,将在浏览器中打开一个界面,允许您查看和测试服务器的状态、资源、工具以及提示。

✨ 主要特性

  • 资源管理:定义了一个简单的资源 (css_knowledge_memory) 来存储已知的 CSS 概念。
  • 工具交互:实现了三个工具,分别为 read_from_memory(从内存中读取数据)、write_to_memory(向内存中写入数据)和 get_latest_updates(调用 OpenRouter API 获取最新的更新)。
  • 提示指导:定义了一个静态提示 (css-tutor-guidance) 来指导 AI 客户端如何有效地与工具和资源交互。

📦 安装指南

环境变量

为了使服务器正常运行,您需要在环境中设置以下变量:

OPENROUTER_API_KEY=your_api_key_here

可以将此环境变量添加到 .env 文件中,或者直接设置在操作系统环境中。

项目配置

package.json 配置

{
  "name": "css_tutor_server",
  "version": "1.0.0",
  "description": "CSS 教学辅助服务器,基于Model Context Protocol构建。",
  "scripts": {
    "start": "ts-node src/index.ts"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^0.5.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.3.3",
    "zod": "^1.24.0"
  }
}

tsconfig.json 配置

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["**/*.ts"],
  "exclude": ["node_modules"]
}

💻 使用示例

基础用法

const server = await createServer({
  prompts: [css_tutor_guidance],
  tools: [
    read_from_memory,
    write_to_memory,
    get_latest_updates
  ],
});

// 启动服务器
await server.start();

📚 详细文档

项目结构

项目的文件结构如下:

project-root/
├── data/                   # 数据目录,包含memory.json数据库文件
├── src/
│   ├── resources/          # 资源定义目录
│   ├── tools/              # 工具定义目录
│   ├── prompts/            # 提示定义目录
│   └── index.ts           # 主程序入口文件
├── package.json           # 项目依赖和脚本配置
├── tsconfig.json          # TypeScript编译器配置
└── .gitignore             # 代码库忽略规则

项目文件结构说明

  • data/memory.json:存储已知的 CSS 概念。
  • src/resources/:包含内存资源的读写逻辑。
  • src/tools/:包含可执行的具体功能工具。
  • src/prompts/:定义了教学提示内容。
  • src/index.ts:服务器入口文件,负责初始化和启动服务。

代码实现

资源定义 (src/resources/index.ts)

import { readFileSync, writeFileSync } from 'fs';
import { resource, ResourceHandler } from '@modelcontextprotocol/sdk';

const memorySchema = z.object({
  concepts: z.record(z.string()),
});

export async function readMemory(): Promise<unknown> {
  try {
    const data = readFileSync('./data/memory.json', 'utf8');
    return JSON.parse(data);
  } catch (error) {
    console.error('读取内存错误:', error);
    throw error;
  }
}

export async function writeMemory(data: unknown): Promise<void> {
  try {
    const isValid = memorySchema.safeParse(data).success;
    if (!isValid) {
      throw new Error('数据格式无效');
    }
    writeFileSync('./data/memory.json', JSON.stringify(data, null, 2));
  } catch (error) {
    console.error('写入内存错误:', error);
    throw error;
  }
}

resource({
  name: 'css_knowledge_memory',
  uriPrefix: 'memory://',
  readHandler: async () => await readMemory(),
  writePermission: true,
  writeHandler: async (data) => await writeMemory(data),
});

工具定义 (src/tools/index.ts)

import { resource } from '@modelcontextprotocol/sdk';
import { readMemory, writeMemory } from './resources';
import { z } from 'zod';

export const read_from_memory = tool({
  name: 'read_from_memory',
  description: '读取内存中的知识库数据',
  handler: async () => await readMemory(),
});

export const write_to_memory = tool({
  name: 'write_to_memory',
  description: '向内存中写入新的知识',
  parameters: {
    concept: z.string().describe('要标记为已知的CSS概念'),
    known: z.boolean().describe('指示该概念是否已知')
  },
  handler: async ({ concept, known }) => {
    const currentData = await readMemory();
    if (known) {
      // 添加到已知概念列表
      currentData.concepts[concept] = true;
    } else {
      // 移除或标记为未知
      delete currentData.concepts[concept];
    }
    return await writeMemory(currentData);
  },
});

export const get_latest_updates = tool({
  name: 'get_latest_updates',
  description: '获取最新的CSS更新信息',
  handler: async () => {
    try {
      // 这里应调用实际的API来获取最新更新
      // 示例中仅返回静态数据
      return {
        updates: ['新增了 CSS Grid 的新布局模式', '修复了 Flexbox 中的一个已知问题']
      };
    } catch (error) {
      console.error('获取更新失败:', error);
      throw error;
    }
  },
});

提示定义 (src/prompts/index.ts)

import { prompt } from '@modelcontextprotocol/sdk';

export const css_tutor_guidance = prompt({
  name: 'css_tutor_guidance',
  description: '指导学习者如何掌握CSS核心概念',
  content: `作为经验丰富的CSS开发者,帮助学习者理解和掌握关键的CSS概念。请以清晰、有条理的方式进行教学。`
});

主程序 (src/index.ts)

import { createServer } from '@modelcontextprotocol/sdk';
import { css_tutor_guidance } from './prompts';
import { read_from_memory, write_to_memory, get_latest_updates } from './tools';

async function main() {
  try {
    const server = await createServer({
      prompts: [css_tutor_guidance],
      tools: [
        read_from_memory,
        write_to_memory,
        get_latest_updates
      ],
    });

    console.log('服务器已启动,监听地址:', server.url);
    await server.start();
  } catch (error) {
    console.error('服务器启动失败:', error);
  }
}

main().catch(console.error);

🔧 技术细节

错误处理

src/tools/index.ts 中,我们已经为每个工具添加了错误捕获和处理机制。生产环境中建议增加额外的错误监控和报告功能。

扩展功能

未来可以考虑以下扩展:

  1. 数据持久化:使用数据库替代本地文件存储。
  2. 日志系统:集成专业的日志管理工具。
  3. 认证授权:为不同的用户角色分配权限。
  4. 国际化支持:支持多语言教学内容。
  5. 进度跟踪:记录学习者的学习进展和成果。

📄 许可证

文档未提及相关信息,故跳过该章节。

🔗 参考资料

help

Runtime guide

cloud

Hosted runtime

Hosted servers run from a provider-managed environment. You usually connect the MCP client to the hosted endpoint or follow the provider's authorization flow, without keeping a local process alive

  1. Open provider connection page
  2. Authorize or copy endpoint
  3. Connect from your MCP client
terminal

Local runtime / other methods

Local servers run on your own machine or infrastructure. You normally copy the server_config into your MCP client, install the required package, and provide env variables from env_schema when needed

  1. Copy server_config
  2. Install required package
  3. Fill env variables and restart client