Token导航 LogoToken导航TokenDH.com
Please MCP logo
开发工具未说明官方级别未说明来源级核验

Please MCP

MCP Server

MCP Wrapper是一个代理MCP服务器,用于选择性暴露上游SSE MCP服务器的工具,提供访问控制、OAuth支持、日志监控等功能。

工具数

0

提示词数

0

GitHub Stars

1

资源数

0
访问控制ShellClaudeClaude DesktopClaude

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

pleaseai

提供方

pleaseai

最后核验

2026/5/17 20:19

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

MCP 包装器

MCP 封装器 这是一个代理MCP服务器,它封装了现有的SSE MCP服务器,以选择性地仅暴露您所需的工具。

概述

在使用多个MCP服务器时,您可能不需要所有可用的工具,或者只想使用特定的工具。MCP Wrapper允许您在这些情况下过滤并自定义来自上游MCP服务器的工具。

Claude ↔️ MCP Wrapper ↔️ Upstream SSE MCP Server

主要特点

  • 选择性工具暴露仅向Claude提供您想要的工具
  • 🔒 表示“锁”或“安全”的意思。 访问控制增强敏感工具的安全性
  • 🔐 OAuth 2.1 支持连接到需要OAuth认证的MCP服务器(例如,Asana MCP)
  • 📝(一个待办事项或笔记的符号,可理解为“待办事项”或“笔记”) 日志记录与监控追踪工具使用模式
  • 🛠️(扳手) 定制化修改工具的元数据和行为
  • 🔄 旋转(循环、重复) 多重认证模式选择无认证、基于令牌或OAuth

安装

git clone https://github.com/amondnet/please-mcp.git
cd please-mcp
bun install
bun run build

快速入门:Asana MCP 服务器(OAuth)

要连接到需要OAuth认证的服务器,如Asana MCP服务器:

  1. 构建项目:
bun run build
  1. 配置MCP设置.mcp.json 或者 claude_desktop_config.json):
{
  "mcpServers": {
    "asana": {
      "command": "node",
      "args": ["/absolute/path/to/please-mcp/dist/index.js"],
      "env": {
        "UPSTREAM_URL": "https://mcp.asana.com/sse",
        "AUTH_MODE": "oauth",
        "ALLOWED_TOOLS": "asana_get_task,asana_get_tasks,asana_create_task,asana_update_task,asana_search_tasks",
        "DEBUG": "true"
      }
    }
  }
}
  1. 启动MCP客户端 - 将打开浏览器窗口以进行Asana认证

📖 有关OAuth设置的详细信息: OAUTH_GUIDE.md 翻译为中文是:“OAUTH 指南.md”

使用方法

1. 基本设置

import { Client } from '@modelcontextprotocol/sdk/client/index.js'
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'

// Connect to upstream MCP server
const upstreamClient = new Client({
  name: 'wrapper-client',
  version: '1.0.0'
}, {
  capabilities: {}
})

const sseTransport = new SSEClientTransport(
  new URL('http://localhost:3000/sse')
)
await upstreamClient.connect(sseTransport)

// Create wrapper server
const server = new Server({
  name: 'mcp-wrapper',
  version: '1.0.0'
}, {
  capabilities: {
    tools: {}
  }
})

2. 工具过滤

// List of allowed tools
const ALLOWED_TOOLS = [
  'search_web',
  'fetch_url',
  'read_file'
]

server.setRequestHandler('tools/list', async () => {
  const upstream = await upstreamClient.listTools()

  return {
    tools: upstream.tools.filter(tool =>
      ALLOWED_TOOLS.includes(tool.name)
    )
  }
})

3. 工具调用代理

server.setRequestHandler('tools/call', async (request) => {
  const toolName = request.params.name

  // Check if tool is allowed
  if (!ALLOWED_TOOLS.includes(toolName)) {
    throw new Error(`Tool '${toolName}' is not allowed`)
  }

  // Forward request to upstream server
  return await upstreamClient.callTool(request.params)
})

4. 启动服务器

const transport = new StdioServerTransport()
await server.connect(transport)

Claude 桌面配置

claude_desktop_config.json:

{
  "mcpServers": {
    "filtered-mcp": {
      "command": "node",
      "args": ["/path/to/mcp-wrapper.js"],
      "env": {
        "UPSTREAM_URL": "http://localhost:3000/sse"
      }
    }
  }
}

高级功能

修改工具元数据

server.setRequestHandler('tools/list', async () => {
  const upstream = await upstreamClient.listTools()

  return {
    tools: upstream.tools
      .filter(tool => ALLOWED_TOOLS.includes(tool.name))
      .map(tool => ({
        ...tool,
        description: `[Filtered] ${tool.description}`,
        // Modify parameter schema
        inputSchema: {
          ...tool.inputSchema,
          required: [...(tool.inputSchema.required || []), 'source']
        }
      }))
  }
})

日志记录和监控

server.setRequestHandler('tools/call', async (request) => {
  const startTime = Date.now()

  console.log(`[${new Date().toISOString()}] Tool called: ${request.params.name}`)
  console.log(`Arguments:`, JSON.stringify(request.params.arguments, null, 2))

  try {
    const result = await upstreamClient.callTool(request.params)
    const duration = Date.now() - startTime

    console.log(`[Success] Completed in ${duration}ms`)
    return result
  }
  catch (error) {
    console.error(`[Error] ${error.message}`)
    throw error
  }
})

访问控制和验证

server.setRequestHandler('tools/call', async (request) => {
  const { name, arguments: args } = request.params

  // Additional validation for sensitive tools
  if (name === 'delete_file') {
    if (!args.path.startsWith('/safe/directory/')) {
      throw new Error('Access denied: Path outside allowed directory')
    }
  }

  // Rate limiting
  if (shouldRateLimit(name)) {
    throw new Error('Rate limit exceeded')
  }

  return await upstreamClient.callTool(request.params)
})

多个上游服务器集成

const clients = {
  asana: await createClient('http://localhost:3000/sse'),
  github: await createClient('http://localhost:3001/sse'),
  slack: await createClient('http://localhost:3002/sse')
}

server.setRequestHandler('tools/list', async () => {
  const allTools = []

  for (const [source, client] of Object.entries(clients)) {
    const { tools } = await client.listTools()
    allTools.push(...tools.map(tool => ({
      ...tool,
      name: `${source}_${tool.name}` // Add namespace
    })))
  }

  return { tools: allTools }
})

server.setRequestHandler('tools/call', async (request) => {
  const [source, ...toolNameParts] = request.params.name.split('_')
  const toolName = toolNameParts.join('_')

  const client = clients[source]
  if (!client) {
    throw new Error(`Unknown source: ${source}`)
  }

  return await client.callTool({
    ...request.params,
    name: toolName
  })
})

完整示例

#!/usr/bin/env node

import { Client } from '@modelcontextprotocol/sdk/client/index.js'
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'

const UPSTREAM_URL = process.env.UPSTREAM_URL || 'http://localhost:3000/sse'
const ALLOWED_TOOLS = (process.env.ALLOWED_TOOLS || '').split(',').filter(Boolean)

async function main() {
  // Setup upstream client
  const upstreamClient = new Client({
    name: 'mcp-wrapper-client',
    version: '1.0.0'
  }, {
    capabilities: {}
  })

  const sseTransport = new SSEClientTransport(new URL(UPSTREAM_URL))
  await upstreamClient.connect(sseTransport)

  // Setup wrapper server
  const server = new Server({
    name: 'mcp-wrapper',
    version: '1.0.0'
  }, {
    capabilities: {
      tools: {}
    }
  })

  // List tools
  server.setRequestHandler('tools/list', async () => {
    const upstream = await upstreamClient.listTools()

    let tools = upstream.tools

    // Filter if configured
    if (ALLOWED_TOOLS.length > 0) {
      tools = tools.filter(tool => ALLOWED_TOOLS.includes(tool.name))
    }

    return { tools }
  })

  // Call tools
  server.setRequestHandler('tools/call', async (request) => {
    const { name, arguments: args } = request.params

    // Check allowlist
    if (ALLOWED_TOOLS.length > 0 && !ALLOWED_TOOLS.includes(name)) {
      throw new Error(`Tool '${name}' is not allowed`)
    }

    // Logging
    console.error(`[MCP Wrapper] Calling tool: ${name}`)

    try {
      const result = await upstreamClient.callTool(request.params)
      console.error(`[MCP Wrapper] Tool '${name}' succeeded`)
      return result
    }
    catch (error) {
      console.error(`[MCP Wrapper] Tool '${name}' failed:`, error.message)
      throw error
    }
  })

  // Start stdio transport
  const transport = new StdioServerTransport()
  await server.connect(transport)

  console.error('MCP Wrapper started')
}

main().catch(console.error)

环境变量

变量描述默认值示例
UPSTREAM_URL 上游SSE MCP服务器URL http://localhost:3000/ssehttp://api.example.com/mcp
ALLOWED_TOOLS允许的工具列表(逗号分隔)全部允许search_web,fetch_url,read_file

用例

1. 增强的安全性

限制执行敏感操作的工具的访问权限,并维护审计日志。

2. 性能优化

过滤掉不常用的工具,以高效利用Claude的上下文窗口。

3. 团队专属定制

为不同的团队或项目提供不同的工具集。

4. 统一界面

通过单一统一接口呈现多个MCP服务器。

故障排除

无法连接到上游服务器

# Check if server is running
curl http://localhost:3000/sse

# Check firewall settings
# Verify URL is correct

工具未显示

# Check ALLOWED_TOOLS environment variable
echo $ALLOWED_TOOLS

# Check logs
# Check MCP logs in Claude Desktop's developer tools

权限错误

# Check script execution permissions
chmod +x mcp-wrapper.js

# Check Node.js version (18+ required)
node --version

许可证

麻省理工学院(MIT)

贡献

欢迎提出问题和提交拉取请求(PRs)!

相关链接

目录标签

目录标签

访问控制ShellClaude本地部署MCP代理工具过滤OAuth认证日志监控

支持客户端

Claude DesktopClaude

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

oauth

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明oauth部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP