本项目的首要目标是创建一个轻量级、基于TypeScript的模型上下文协议(MCP)服务器。该服务器专注于以简单、标准化的JSON格式提供关于npmjs包的结构化信息,如版本详情、下载统计、发布日期、描述和许可证等。这种格式适合大型语言模型(LLMs)和AI驱动的开发工具使用。
该服务器旨在通过抽象多个npmjs API端点的直接交互来简化对npm包元数据的访问。
git clone https://github.com/yiannis-spyridakis/npmjs-mcp-server.git
cd npmjs-mcp-server
npm install
此MCP服务器设计为由MCP客户端(如LLM代理或开发工具)作为子进程运行。它通过标准输入(stdin)和标准输出(stdout)使用模型上下文协议与客户端通信。
为了直接运行服务器进行开发,并在文件更改时自动重启:
npm run dev
或者,不监视更改的情况下单次运行:
npm run watch
(注意:npm run watch 使用 package.json 中指定的 nodemon 和 ts-node 进行开发。npm run dev 直接使用 ts-node。)
服务器启动后,将通过标准输入/输出监听MCP请求。
要将TypeScript代码编译成JavaScript用于生产:
npm run build
这将在根目录下生成一个包含编译文件的 dist 目录。
要在生产环境中运行已编译的服务器:
npm start
此命令执行 node dist/index.js。MCP客户端负责将此命令作为子进程启动。
此服务器提供了可以通过MCP客户端调用的工具。
get_npm_package_summary{
"type": "object",
"properties": {
"packageName": {
"type": "string",
"description": "npm包的名称(例如,'express','react')"
}
},
"required": ["packageName"]
}
get_npm_package_versions{
"type": "object",
"properties": {
"packageName": {
"type": "string",
"description": "npm包的名称"
}
},
"required": ["packageName"]
}
get_npm_package_downloadslast-day,last-week,last-month)的数据,如果未指定period。{
"type": "object",
"properties": {
"packageName": {
"type": "string",
"description": "npm包的名称"
},
"period": {
"type": "string",
"description": "可选:'last-day','last-week','last-month'。如果未指定,则获取所有。",
"enum": ["last-day", "last-week", "last-month"]
}
},
"required": ["packageName"]
}
get_npm_package_details{
"type": "object",
"properties": {
"packageName": {
"type": "string",
"description": "npm包的名称"
}
},
"required": ["packageName"]
}
除了工具外,此服务器还提供了提示,这些提示可以被MCP客户端用来根据提供的变量生成特定的用户请求,从而简化常见的交互。
get_summary_prompt{
"packageName": {
"type": "string",
"description": "npm包的名称"
}
}
get_details_prompt{
"packageName": {
"type": "string",
"description": "npm包的名称"
}
}
find_homepage_prompt{
"packageName": {
"type": "string",
"description": "npm包的名称"
}
}
list_versions_prompt{
"packageName": {
"type": "string",
"description": "npm包的名称"
}
}
get_version_date_prompt{
"packageName": {
"type": "string",
"description": "npm包的名称"
},
"version": {
"type": "string",
"description": "特定版本字符串(例如,'16.8.0')"
}
}
get_downloads_prompt{
"packageName": {
"type": "string",
"description": "npm包的名称"
},
"timePeriod": {
"type": "string",
"enum": ["last-day", "last-week", "last-month"],
"description": "下载次数的时间段"
}
}
get_all_downloads_prompt{
"packageName": {
"type": "string",
"description": "npm包的名称"
}
}
audit_project_prompt{
"projectPath": {
"type": "string",
"description": "项目目录的路径(例如,'.','../my-app')"
}
}
simulate_audit_fix_promptnpm audit fix。{
"projectPath": {
"type": "string",
"description": "项目目录的路径(例如,'.','../my-app')"
}
}
以下示例展示了如何调用一个工具(概念性,实际客户端使用可能有所不同)以及成功MCP CallToolResponse 的预期 data 部分。MCP SDK 处理完整的响应信封(版本、时间戳等)。MCP 响应中的 data 字段将包含一个 content 数组,其中第一个元素是一个类型为 text 的对象,其 text 属性保存了如下所示的结果的 JSON 字符串。
get_npm_package_summary工具调用参数:
{
"packageName": "express"
}
预期 data.content[0].text 中的 JSON 字符串:
{
"name": "express",
"latestVersion": "4.19.2",
"description": "快速、无偏见、极简的Node.js Web框架。",
"publishDateLatest": "2024-03-25T14:30:36.103Z",
"license": "MIT",
"homepage": "http://expressjs.com/",
"repository": "https://github.com/expressjs/express",
"source": "https://registry.npmjs.org/express"
}
(注:版本和日期是示例,查询时会反映实际数据)
get_npm_package_versions工具调用参数:
{
"packageName": "express"
}
预期 data.content[0].text 中的 JSON 字符串:
{
"versions": {
"1.0.0": "2010-12-29T19:38:25.450Z",
"1.0.1": "2010-12-29T19:38:25.450Z",
"4.19.2": "2024-03-25T14:30:36.103Z"
// ... 可能还有更多版本
},
"source": "https://registry.npmjs.org/express"
}
get_npm_package_downloads(所有默认时间段)工具调用参数:
{
"packageName": "express"
}
预期 data.content[0].text 中的 JSON 字符串:
{
"downloads": {
"last-day": 7895822,
"last-week": 37439130,
"last-month": 162348160
},
"package": "express",
"source": "https://api.npmjs.org/downloads/point"
}
(注:下载次数是示例,查询时会反映实际数据)
get_npm_package_details工具调用参数:
{
"packageName": "express"
}
预期 data.content[0].text 中的 JSON 字符串:
{
"name": "express",
"latestVersion": "4.19.2",
"description": "快速、无偏见、极简的Node.js Web框架。",
"publishDateLatest": "2024-03-25T14:30:36.103Z",
"license": "MIT",
"homepage": "https://expressjs.com/",
"repository": "https://github.com/expressjs/express",
"maintainers": [
{ "name": "dougwilson", "email": "doug@somethingdoug.com" },
{ "name": "wesleytodd", "email": "wes@wesleytodd.com" }
// ... 其他维护者
],
"keywords": [
"express",
"框架",
"sinatra",
"web",
"rest",
"restful",
"路由器"
],
"source": "https://registry.npmjs.org/express"
}
(注:版本、日期、维护者和关键词是示例,查询时会反映实际数据)
如果工具调用失败(例如,找不到包、参数无效),MCP服务器将返回一个标准的MCP错误响应。此响应中的 result.error 对象将包含一个 message,详细说明问题。
示例 MCP 错误响应(概念性结构):
{
"version": "0.2.0", // SDK 版本
"id": "response-id-string",
"type": "CallToolResponse",
"timestamp": "YYYY-MM-DDTHH:mm:ss.sssZ",
"result": {
"error": {
"type": "ToolError", // 或来自SDK的其他错误类型
"message": "在npmjs上找不到包 'nonexistent-pkg'。"
// 可能还有其他字段,如 'toolName'
}
}
}
如果缺少像 packageName 这样的必需参数,工具处理器将抛出一个错误,导致类似的MCP错误响应。
以下示例展示了如何通过提供参数来使用可用的提示。服务器将返回一个包含生成的用户消息的 GetPromptResponse。
get_summary_prompt提示调用参数:
{ "packageName": "react" }
生成的用户消息(messages[0].content.text):
获取 'react' npm包的快速概要。
get_version_date_prompt提示调用参数:
{ "packageName": "lodash", "version": "4.17.21" }
生成的用户消息(messages[0].content.text):
'lodash' 版本 4.17.21 的发布日期是什么时候?
get_downloads_prompt提示调用参数:
{ "packageName": "axios", "timePeriod": "last-week" }
生成的用户消息(messages[0].content.text):
'axios' 在过去一周内被下载了多少次?
audit_project_prompt提示调用参数:
{ "projectPath": "../my-frontend-app" }
生成的用户消息(messages[0].content.text):
审核位于 '../my-frontend-app' 的项目中的依赖项是否存在安全漏洞。
simulate_audit_fix_prompt提示调用参数:
{ "projectPath": "." }
生成的用户消息(messages[0].content.text):
模拟在位于 '.' 的项目上运行 'npm audit fix' 并显示会发生什么变化。