Merge branch 'main' into patch-1

This commit is contained in:
Ola Hungerford
2025-03-30 07:11:19 -07:00
committed by GitHub
9 changed files with 180 additions and 31 deletions

View File

@@ -73,6 +73,7 @@ Official integrations are maintained by companies building production ready MCP
- <img height="12" width="12" src="https://cdn.prod.website-files.com/6605a2979ff17b2cd1939cd4/6605a460de47e7596ed84f06_icon256.png" alt="gotoHuman Logo" /> **[gotoHuman](https://github.com/gotohuman/gotohuman-mcp-server)** - Human-in-the-loop platform - Allow AI agents and automations to send requests for approval to your [gotoHuman](https://www.gotohuman.com) inbox. - <img height="12" width="12" src="https://cdn.prod.website-files.com/6605a2979ff17b2cd1939cd4/6605a460de47e7596ed84f06_icon256.png" alt="gotoHuman Logo" /> **[gotoHuman](https://github.com/gotohuman/gotohuman-mcp-server)** - Human-in-the-loop platform - Allow AI agents and automations to send requests for approval to your [gotoHuman](https://www.gotohuman.com) inbox.
- <img height="12" width="12" src="https://grafana.com/favicon.ico" alt="Grafana Logo" /> **[Grafana](https://github.com/grafana/mcp-grafana)** - Search dashboards, investigate incidents and query datasources in your Grafana instance - <img height="12" width="12" src="https://grafana.com/favicon.ico" alt="Grafana Logo" /> **[Grafana](https://github.com/grafana/mcp-grafana)** - Search dashboards, investigate incidents and query datasources in your Grafana instance
- <img height="12" width="12" src="https://framerusercontent.com/images/KCOWBYLKunDff1Dr452y6EfjiU.png" alt="Graphlit Logo" /> **[Graphlit](https://github.com/graphlit/graphlit-mcp-server)** - Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a searchable [Graphlit](https://www.graphlit.com) project. - <img height="12" width="12" src="https://framerusercontent.com/images/KCOWBYLKunDff1Dr452y6EfjiU.png" alt="Graphlit Logo" /> **[Graphlit](https://github.com/graphlit/graphlit-mcp-server)** - Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a searchable [Graphlit](https://www.graphlit.com) project.
- <img height="12" width="12" src="https://greptime.com/favicon.ico" alt="Greptime Logo" /> **[GreptimeDB](https://github.com/GreptimeTeam/greptimedb-mcp-server)** - Provides AI assistants with a secure and structured way to explore and analyze data in [GreptimeDB](https://github.com/GreptimeTeam/greptimedb).
- <img height="12" width="12" src="https://img.alicdn.com/imgextra/i3/O1CN01d9qrry1i6lTNa2BRa_!!6000000004364-2-tps-218-200.png" alt="Hologres Logo" /> **[Hologres](https://github.com/aliyun/alibabacloud-hologres-mcp-server)** - Connect to a [Hologres](https://www.alibabacloud.com/en/product/hologres) instance, get table metadata, query and analyze data. - <img height="12" width="12" src="https://img.alicdn.com/imgextra/i3/O1CN01d9qrry1i6lTNa2BRa_!!6000000004364-2-tps-218-200.png" alt="Hologres Logo" /> **[Hologres](https://github.com/aliyun/alibabacloud-hologres-mcp-server)** - Connect to a [Hologres](https://www.alibabacloud.com/en/product/hologres) instance, get table metadata, query and analyze data.
- <img height="12" width="12" src="https://hyperbrowser-assets-bucket.s3.us-east-1.amazonaws.com/Hyperbrowser-logo.png" alt="Hyperbrowsers23 Logo" /> **[Hyperbrowser](https://github.com/hyperbrowserai/mcp)** - [Hyperbrowser](https://www.hyperbrowser.ai/) is the next-generation platform empowering AI agents and enabling effortless, scalable browser automation. - <img height="12" width="12" src="https://hyperbrowser-assets-bucket.s3.us-east-1.amazonaws.com/Hyperbrowser-logo.png" alt="Hyperbrowsers23 Logo" /> **[Hyperbrowser](https://github.com/hyperbrowserai/mcp)** - [Hyperbrowser](https://www.hyperbrowser.ai/) is the next-generation platform empowering AI agents and enabling effortless, scalable browser automation.
- **[IBM wxflows](https://github.com/IBM/wxflows/tree/main/examples/mcp/javascript)** - Tool platform by IBM to build, test and deploy tools for any data source - **[IBM wxflows](https://github.com/IBM/wxflows/tree/main/examples/mcp/javascript)** - Tool platform by IBM to build, test and deploy tools for any data source
@@ -82,6 +83,7 @@ Official integrations are maintained by companies building production ready MCP
- <img height="12" width="12" src="https://integration.app/favicon.ico" alt="Integration App Icon" /> **[Integration App](https://github.com/integration-app/mcp-server)** - Interact with any other SaaS applications on behalf of your customers. - <img height="12" width="12" src="https://integration.app/favicon.ico" alt="Integration App Icon" /> **[Integration App](https://github.com/integration-app/mcp-server)** - Interact with any other SaaS applications on behalf of your customers.
- <img height="12" width="12" src="https://cdn.simpleicons.org/jetbrains" /> **[JetBrains](https://github.com/JetBrains/mcp-jetbrains)** Work on your code with JetBrains IDEs - <img height="12" width="12" src="https://cdn.simpleicons.org/jetbrains" /> **[JetBrains](https://github.com/JetBrains/mcp-jetbrains)** Work on your code with JetBrains IDEs
- <img height="12" width="12" src="https://kagi.com/favicon.ico" alt="Kagi Logo" /> **[Kagi Search](https://github.com/kagisearch/kagimcp)** - Search the web using Kagi's search API - <img height="12" width="12" src="https://kagi.com/favicon.ico" alt="Kagi Logo" /> **[Kagi Search](https://github.com/kagisearch/kagimcp)** - Search the web using Kagi's search API
- <img height="12" width="12" src="https://connection.keboola.com/favicon.ico" alt="Keboola Logo" /> **[Keboola](https://github.com/keboola/keboola-mcp-server)** - Build robust data workflows, integrations, and analytics on a single intuitive platform.
- <img height="12" width="12" src="https://logfire.pydantic.dev/favicon.ico" alt="Logfire Logo" /> **[Logfire](https://github.com/pydantic/logfire-mcp)** - Provides access to OpenTelemetry traces and metrics through Logfire. - <img height="12" width="12" src="https://logfire.pydantic.dev/favicon.ico" alt="Logfire Logo" /> **[Logfire](https://github.com/pydantic/logfire-mcp)** - Provides access to OpenTelemetry traces and metrics through Logfire.
- <img height="12" width="12" src="https://langfuse.com/favicon.ico" alt="Langfuse Logo" /> **[Langfuse Prompt Management](https://github.com/langfuse/mcp-server-langfuse)** - Open-source tool for collaborative editing, versioning, evaluating, and releasing prompts. - <img height="12" width="12" src="https://langfuse.com/favicon.ico" alt="Langfuse Logo" /> **[Langfuse Prompt Management](https://github.com/langfuse/mcp-server-langfuse)** - Open-source tool for collaborative editing, versioning, evaluating, and releasing prompts.
- <img height="12" width="12" src="https://lingo.dev/favicon.ico" alt="Lingo.dev Logo" /> **[Lingo.dev](https://github.com/lingodotdev/lingo.dev/blob/main/mcp.md)** - Make your AI agent speak every language on the planet, using [Lingo.dev](https://lingo.dev) Localization Engine. - <img height="12" width="12" src="https://lingo.dev/favicon.ico" alt="Lingo.dev Logo" /> **[Lingo.dev](https://github.com/lingodotdev/lingo.dev/blob/main/mcp.md)** - Make your AI agent speak every language on the planet, using [Lingo.dev](https://lingo.dev) Localization Engine.
@@ -106,6 +108,7 @@ Official integrations are maintained by companies building production ready MCP
- <img height="12" width="12" src="https://pics.fatwang2.com/56912e614b35093426c515860f9f2234.svg" /> [Search1API](https://github.com/fatwang2/search1api-mcp) - One API for Search, Crawling, and Sitemaps - <img height="12" width="12" src="https://pics.fatwang2.com/56912e614b35093426c515860f9f2234.svg" /> [Search1API](https://github.com/fatwang2/search1api-mcp) - One API for Search, Crawling, and Sitemaps
- <img height="12" width="12" src="https://screenshotone.com/favicon.ico" alt="ScreenshotOne Logo" /> **[ScreenshotOne](https://github.com/screenshotone/mcp/)** - Render website screenshots with [ScreenshotOne](https://screenshotone.com/) - <img height="12" width="12" src="https://screenshotone.com/favicon.ico" alt="ScreenshotOne Logo" /> **[ScreenshotOne](https://github.com/screenshotone/mcp/)** - Render website screenshots with [ScreenshotOne](https://screenshotone.com/)
- <img height="12" width="12" src="https://semgrep.dev/favicon.ico" alt="Semgrep Logo" /> **[Semgrep](https://github.com/semgrep/mcp)** - Enable AI agents to secure code with [Semgrep](https://semgrep.dev/). - <img height="12" width="12" src="https://semgrep.dev/favicon.ico" alt="Semgrep Logo" /> **[Semgrep](https://github.com/semgrep/mcp)** - Enable AI agents to secure code with [Semgrep](https://semgrep.dev/).
- <img height="12" width="12" src="https://www.singlestore.com/favicon-32x32.png?v=277b9cbbe31e8bc416504cf3b902d430"/> **[SingleStore](https://github.com/singlestore-labs/mcp-server-singlestore)** - Interact with the SingleStore database platform
- <img height="12" width="12" src="https://www.starrocks.io/favicon.ico" alt="StarRocks Logo" /> **[StarRocks](https://github.com/StarRocks/mcp-server-starrocks)** - Interact with [StarRocks](https://www.starrocks.io/) - <img height="12" width="12" src="https://www.starrocks.io/favicon.ico" alt="StarRocks Logo" /> **[StarRocks](https://github.com/StarRocks/mcp-server-starrocks)** - Interact with [StarRocks](https://www.starrocks.io/)
- <img height="12" width="12" src="https://stripe.com/favicon.ico" alt="Stripe Logo" /> **[Stripe](https://github.com/stripe/agent-toolkit)** - Interact with Stripe API - <img height="12" width="12" src="https://stripe.com/favicon.ico" alt="Stripe Logo" /> **[Stripe](https://github.com/stripe/agent-toolkit)** - Interact with Stripe API
- <img height="12" width="12" src="https://tavily.com/favicon.ico" alt="Tavily Logo" /> **[Tavily](https://github.com/tavily-ai/tavily-mcp)** - Search engine for AI agents (search + extract) powered by [Tavily](https://tavily.com/) - <img height="12" width="12" src="https://tavily.com/favicon.ico" alt="Tavily Logo" /> **[Tavily](https://github.com/tavily-ai/tavily-mcp)** - Search engine for AI agents (search + extract) powered by [Tavily](https://tavily.com/)
@@ -117,6 +120,7 @@ Official integrations are maintained by companies building production ready MCP
- <img height="12" width="12" src="https://verodat.io/assets/favicon-16x16.png" alt="Verodat Logo" /> **[Verodat](https://github.com/Verodat/verodat-mcp-server)** - Interact with Verodat AI Ready Data platform - <img height="12" width="12" src="https://verodat.io/assets/favicon-16x16.png" alt="Verodat Logo" /> **[Verodat](https://github.com/Verodat/verodat-mcp-server)** - Interact with Verodat AI Ready Data platform
- <img height="12" width="12" src="https://www.veyrax.com/favicon.ico" alt="VeyraX Logo" /> **[VeyraX](https://github.com/VeyraX/veyrax-mcp)** - Single tool to control all 100+ API integrations, and UI components - <img height="12" width="12" src="https://www.veyrax.com/favicon.ico" alt="VeyraX Logo" /> **[VeyraX](https://github.com/VeyraX/veyrax-mcp)** - Single tool to control all 100+ API integrations, and UI components
- <img height="12" width="12" src="https://www.xero.com/favicon.ico" alt="Xero Logo" /> **[Xero](https://github.com/XeroAPI/xero-mcp-server)** - Interact with the accounting data in your business using our official MCP server - <img height="12" width="12" src="https://www.xero.com/favicon.ico" alt="Xero Logo" /> **[Xero](https://github.com/XeroAPI/xero-mcp-server)** - Interact with the accounting data in your business using our official MCP server
- <img height="12" width="12" src="https://cdn.zapier.com/zapier/images/favicon.ico" alt="Zapier Logo" /> **[Zapier](https://zapier.com/mcp)** - Connect your AI Agents to 8,000 apps instantly.
- **[ZenML](https://github.com/zenml-io/mcp-zenml)** - Interact with your MLOps and LLMOps pipelines through your [ZenML](https://www.zenml.io) MCP server - **[ZenML](https://github.com/zenml-io/mcp-zenml)** - Interact with your MLOps and LLMOps pipelines through your [ZenML](https://www.zenml.io) MCP server
### 🌎 Community Servers ### 🌎 Community Servers
@@ -152,6 +156,7 @@ A growing set of community-developed and maintained servers demonstrates various
- **[Bitable MCP](https://github.com/lloydzhou/bitable-mcp)** (by lloydzhou) - MCP server provides access to Lark Bitable through the Model Context Protocol. It allows users to interact with Bitable tables using predefined tools. - **[Bitable MCP](https://github.com/lloydzhou/bitable-mcp)** (by lloydzhou) - MCP server provides access to Lark Bitable through the Model Context Protocol. It allows users to interact with Bitable tables using predefined tools.
- **[Blender](https://github.com/ahujasid/blender-mcp)** (by ahujasid) - Blender integration allowing prompt enabled 3D scene creation, modeling and manipulation. - **[Blender](https://github.com/ahujasid/blender-mcp)** (by ahujasid) - Blender integration allowing prompt enabled 3D scene creation, modeling and manipulation.
- **[Bsc-mcp](https://github.com/TermiX-official/bsc-mcp)** The first MCP server that serves as the bridge between AI and BNB Chain, enabling AI agents to execute complex on-chain operations through seamless integration with the BNB Chain, including transfer, swap, launch, security check on any token and even more. - **[Bsc-mcp](https://github.com/TermiX-official/bsc-mcp)** The first MCP server that serves as the bridge between AI and BNB Chain, enabling AI agents to execute complex on-chain operations through seamless integration with the BNB Chain, including transfer, swap, launch, security check on any token and even more.
- **[Calculator](https://github.com/githejie/mcp-server-calculator)** - This server enables LLMs to use calculator for precise numerical calculations.
- **[CFBD API](https://github.com/lenwood/cfbd-mcp-server)** - An MCP server for the [College Football Data API](https://collegefootballdata.com/). - **[CFBD API](https://github.com/lenwood/cfbd-mcp-server)** - An MCP server for the [College Football Data API](https://collegefootballdata.com/).
- **[ChatMCP](https://github.com/AI-QL/chat-mcp)** An Open Source Cross-platform GUI Desktop application compatible with Linux, macOS, and Windows, enabling seamless interaction with MCP servers across dynamically selectable LLMs, by **[AIQL](https://github.com/AI-QL)** - **[ChatMCP](https://github.com/AI-QL/chat-mcp)** An Open Source Cross-platform GUI Desktop application compatible with Linux, macOS, and Windows, enabling seamless interaction with MCP servers across dynamically selectable LLMs, by **[AIQL](https://github.com/AI-QL)**
- **[ChatSum](https://github.com/mcpso/mcp-server-chatsum)** - Query and Summarize chat messages with LLM. by [mcpso](https://mcp.so) - **[ChatSum](https://github.com/mcpso/mcp-server-chatsum)** - Query and Summarize chat messages with LLM. by [mcpso](https://mcp.so)
@@ -222,6 +227,7 @@ A growing set of community-developed and maintained servers demonstrates various
- **[HubSpot](https://github.com/buryhuang/mcp-hubspot)** - HubSpot CRM integration for managing contacts and companies. Create and retrieve CRM data directly through Claude chat. - **[HubSpot](https://github.com/buryhuang/mcp-hubspot)** - HubSpot CRM integration for managing contacts and companies. Create and retrieve CRM data directly through Claude chat.
- **[HuggingFace Spaces](https://github.com/evalstate/mcp-hfspace)** - Server for using HuggingFace Spaces, supporting Open Source Image, Audio, Text Models and more. Claude Desktop mode for easy integration. - **[HuggingFace Spaces](https://github.com/evalstate/mcp-hfspace)** - Server for using HuggingFace Spaces, supporting Open Source Image, Audio, Text Models and more. Claude Desktop mode for easy integration.
- **[Hyperliquid](https://github.com/mektigboy/server-hyperliquid)** - An MCP server implementation that integrates the Hyperliquid SDK for exchange data. - **[Hyperliquid](https://github.com/mektigboy/server-hyperliquid)** - An MCP server implementation that integrates the Hyperliquid SDK for exchange data.
- **[iFlytek Workflow](https://github.com/iflytek/ifly-workflow-mcp-server)** - Connect to iFlytek Workflow via the MCP server and run your own Agent.
- **[Image Generation](https://github.com/GongRzhe/Image-Generation-MCP-Server)** - This MCP server provides image generation capabilities using the Replicate Flux model. - **[Image Generation](https://github.com/GongRzhe/Image-Generation-MCP-Server)** - This MCP server provides image generation capabilities using the Replicate Flux model.
- **[InfluxDB](https://github.com/idoru/influxdb-mcp-server)** - Run queries against InfluxDB OSS API v2. - **[InfluxDB](https://github.com/idoru/influxdb-mcp-server)** - Run queries against InfluxDB OSS API v2.
- **[Inoyu](https://github.com/sergehuber/inoyu-mcp-unomi-server)** - Interact with an Apache Unomi CDP customer data platform to retrieve and update customer profiles - **[Inoyu](https://github.com/sergehuber/inoyu-mcp-unomi-server)** - Interact with an Apache Unomi CDP customer data platform to retrieve and update customer profiles
@@ -363,6 +369,7 @@ These are high-level frameworks that make it easier to build MCP servers or clie
- **[FastAPI to MCP auto generator](https://github.com/tadata-org/fastapi_mcp)**  A zero-configuration tool for automatically exposing FastAPI endpoints as MCP tools by **[Tadata](https://tadata.com/)** - **[FastAPI to MCP auto generator](https://github.com/tadata-org/fastapi_mcp)**  A zero-configuration tool for automatically exposing FastAPI endpoints as MCP tools by **[Tadata](https://tadata.com/)**
* **[FastMCP](https://github.com/punkpeye/fastmcp)** (TypeScript) * **[FastMCP](https://github.com/punkpeye/fastmcp)** (TypeScript)
* **[Foxy Contexts](https://github.com/strowk/foxy-contexts)** A library to build MCP servers in Golang by **[strowk](https://github.com/strowk)** * **[Foxy Contexts](https://github.com/strowk/foxy-contexts)** A library to build MCP servers in Golang by **[strowk](https://github.com/strowk)**
* **[Higress MCP Server Hosting](https://github.com/alibaba/higress/tree/main/plugins/wasm-go/mcp-servers)** - A solution for hosting MCP Servers by extending the API Gateway (based on Envoy) with wasm plugins.
* **[MCP-Framework](https://mcp-framework.com)** Build MCP servers with elegance and speed in Typescript. Comes with a CLI to create your project with `mcp create app`. Get started with your first server in under 5 minutes by **[Alex Andru](https://github.com/QuantGeekDev)** * **[MCP-Framework](https://mcp-framework.com)** Build MCP servers with elegance and speed in Typescript. Comes with a CLI to create your project with `mcp create app`. Get started with your first server in under 5 minutes by **[Alex Andru](https://github.com/QuantGeekDev)**
* **[Quarkus MCP Server SDK](https://github.com/quarkiverse/quarkus-mcp-server)** (Java) * **[Quarkus MCP Server SDK](https://github.com/quarkiverse/quarkus-mcp-server)** (Java)
* **[Template MCP Server](https://github.com/mcpdotdirect/template-mcp-server)** - A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure * **[Template MCP Server](https://github.com/mcpdotdirect/template-mcp-server)** - A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure

View File

@@ -41,22 +41,16 @@ Node.js server implementing Model Context Protocol (MCP) for filesystem operatio
- Features: - Features:
- Line-based and multi-line content matching - Line-based and multi-line content matching
- Whitespace normalization with indentation preservation - Whitespace normalization with indentation preservation
- Fuzzy matching with confidence scoring
- Multiple simultaneous edits with correct positioning - Multiple simultaneous edits with correct positioning
- Indentation style detection and preservation - Indentation style detection and preservation
- Git-style diff output with context - Git-style diff output with context
- Preview changes with dry run mode - Preview changes with dry run mode
- Failed match debugging with confidence scores
- Inputs: - Inputs:
- `path` (string): File to edit - `path` (string): File to edit
- `edits` (array): List of edit operations - `edits` (array): List of edit operations
- `oldText` (string): Text to search for (can be substring) - `oldText` (string): Text to search for (can be substring)
- `newText` (string): Text to replace with - `newText` (string): Text to replace with
- `dryRun` (boolean): Preview changes without applying (default: false) - `dryRun` (boolean): Preview changes without applying (default: false)
- `options` (object): Optional formatting settings
- `preserveIndentation` (boolean): Keep existing indentation (default: true)
- `normalizeWhitespace` (boolean): Normalize spaces while preserving structure (default: true)
- `partialMatch` (boolean): Enable fuzzy matching (default: true)
- Returns detailed diff and match information for dry runs, otherwise applies changes - Returns detailed diff and match information for dry runs, otherwise applies changes
- Best Practice: Always use dryRun first to preview changes before applying them - Best Practice: Always use dryRun first to preview changes before applying them

View File

@@ -42,7 +42,7 @@ const allowedDirectories = args.map(dir =>
// Validate that all directories exist and are accessible // Validate that all directories exist and are accessible
await Promise.all(args.map(async (dir) => { await Promise.all(args.map(async (dir) => {
try { try {
const stats = await fs.stat(dir); const stats = await fs.stat(expandHome(dir));
if (!stats.isDirectory()) { if (!stats.isDirectory()) {
console.error(`Error: ${dir} is not a directory`); console.error(`Error: ${dir} is not a directory`);
process.exit(1); process.exit(1);

4
src/git/uv.lock generated
View File

@@ -165,9 +165,9 @@ dependencies = [
{ name = "sse-starlette" }, { name = "sse-starlette" },
{ name = "starlette" }, { name = "starlette" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/97/de/a9ec0a1b6439f90ea59f89004bb2e7ec6890dfaeef809751d9e6577dca7e/mcp-1.0.0.tar.gz", hash = "sha256:dba51ce0b5c6a80e25576f606760c49a91ee90210fed805b530ca165d3bbc9b7", size = 82891 } sdist = { url = "https://files.pythonhosted.org/packages/77/f2/067b1fc114e8d3ae4af02fc4f4ed8971a2c4900362d976fabe0f4e9a3418/mcp-1.1.0.tar.gz", hash = "sha256:e3c8d6df93a4de90230ea944dd667730744a3cd91a4cc0ee66a5acd53419e100", size = 83802 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/56/89/900c0c8445ec001d3725e475fc553b0feb2e8a51be018f3bb7de51e683db/mcp-1.0.0-py3-none-any.whl", hash = "sha256:bbe70ffa3341cd4da78b5eb504958355c68381fb29971471cea1e642a2af5b8a", size = 36361 }, { url = "https://files.pythonhosted.org/packages/b9/3e/aef19ac08a6f9a347c086c4e628c2f7329659828cbe92ffd524ec2aac833/mcp-1.1.0-py3-none-any.whl", hash = "sha256:44aa4d2e541f0924d6c344aa7f96b427a6ee1df2fab70b5f9ae2f8777b3f05f2", size = 36576 },
] ]
[[package]] [[package]]

View File

@@ -157,7 +157,7 @@ export const GitHubLabelSchema = z.object({
name: z.string(), name: z.string(),
color: z.string(), color: z.string(),
default: z.boolean(), default: z.boolean(),
description: z.string().optional(), description: z.string().nullable().optional(),
}); });
export const GitHubMilestoneSchema = z.object({ export const GitHubMilestoneSchema = z.object({

View File

@@ -7,6 +7,7 @@ import {
} from "@modelcontextprotocol/sdk/types.js"; } from "@modelcontextprotocol/sdk/types.js";
import { z } from 'zod'; import { z } from 'zod';
import { zodToJsonSchema } from 'zod-to-json-schema'; import { zodToJsonSchema } from 'zod-to-json-schema';
import fetch, { Request, Response } from 'node-fetch';
import * as repository from './operations/repository.js'; import * as repository from './operations/repository.js';
import * as files from './operations/files.js'; import * as files from './operations/files.js';
@@ -27,6 +28,11 @@ import {
} from './common/errors.js'; } from './common/errors.js';
import { VERSION } from "./common/version.js"; import { VERSION } from "./common/version.js";
// If fetch doesn't exist in global scope, add it
if (!globalThis.fetch) {
globalThis.fetch = fetch as unknown as typeof global.fetch;
}
const server = new Server( const server = new Server(
{ {
name: "github-mcp-server", name: "github-mcp-server",
@@ -293,10 +299,39 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
case "create_issue": { case "create_issue": {
const args = issues.CreateIssueSchema.parse(request.params.arguments); const args = issues.CreateIssueSchema.parse(request.params.arguments);
const { owner, repo, ...options } = args; const { owner, repo, ...options } = args;
try {
console.error(`[DEBUG] Attempting to create issue in ${owner}/${repo}`);
console.error(`[DEBUG] Issue options:`, JSON.stringify(options, null, 2));
const issue = await issues.createIssue(owner, repo, options); const issue = await issues.createIssue(owner, repo, options);
console.error(`[DEBUG] Issue created successfully`);
return { return {
content: [{ type: "text", text: JSON.stringify(issue, null, 2) }], content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
}; };
} catch (err) {
// Type guard for Error objects
const error = err instanceof Error ? err : new Error(String(err));
console.error(`[ERROR] Failed to create issue:`, error);
if (error instanceof GitHubResourceNotFoundError) {
throw new Error(
`Repository '${owner}/${repo}' not found. Please verify:\n` +
`1. The repository exists\n` +
`2. You have correct access permissions\n` +
`3. The owner and repository names are spelled correctly`
);
}
// Safely access error properties
throw new Error(
`Failed to create issue: ${error.message}${
error.stack ? `\nStack: ${error.stack}` : ''
}`
);
}
} }
case "create_pull_request": { case "create_pull_request": {

View File

@@ -22,10 +22,10 @@ export const GitLabRepositorySchema = z.object({
name: z.string(), name: z.string(),
path_with_namespace: z.string(), // Changed from full_name to match GitLab API path_with_namespace: z.string(), // Changed from full_name to match GitLab API
visibility: z.string(), // Changed from private to match GitLab API visibility: z.string(), // Changed from private to match GitLab API
owner: GitLabOwnerSchema, owner: GitLabOwnerSchema.optional(),
web_url: z.string(), // Changed from html_url to match GitLab API web_url: z.string(), // Changed from html_url to match GitLab API
description: z.string().nullable(), description: z.string().nullable(),
fork: z.boolean(), fork: z.boolean().optional(),
ssh_url_to_repo: z.string(), // Changed from ssh_url to match GitLab API ssh_url_to_repo: z.string(), // Changed from ssh_url to match GitLab API
http_url_to_repo: z.string(), // Changed from clone_url to match GitLab API http_url_to_repo: z.string(), // Changed from clone_url to match GitLab API
created_at: z.string(), created_at: z.string(),
@@ -218,12 +218,12 @@ export const GitLabMergeRequestSchema = z.object({
title: z.string(), title: z.string(),
description: z.string(), // Changed from body to match GitLab API description: z.string(), // Changed from body to match GitLab API
state: z.string(), state: z.string(),
merged: z.boolean(), merged: z.boolean().optional(),
author: GitLabUserSchema, author: GitLabUserSchema,
assignees: z.array(GitLabUserSchema), assignees: z.array(GitLabUserSchema),
source_branch: z.string(), // Changed from head to match GitLab API source_branch: z.string(), // Changed from head to match GitLab API
target_branch: z.string(), // Changed from base to match GitLab API target_branch: z.string(), // Changed from base to match GitLab API
diff_refs: GitLabMergeRequestDiffRefSchema, diff_refs: GitLabMergeRequestDiffRefSchema.nullable(),
web_url: z.string(), // Changed from html_url to match GitLab API web_url: z.string(), // Changed from html_url to match GitLab API
created_at: z.string(), created_at: z.string(),
updated_at: z.string(), updated_at: z.string(),

View File

@@ -8,7 +8,10 @@ A Model Context Protocol server that provides browser automation capabilities us
- **puppeteer_navigate** - **puppeteer_navigate**
- Navigate to any URL in the browser - Navigate to any URL in the browser
- Input: `url` (string) - Inputs:
- `url` (string, required): URL to navigate to
- `launchOptions` (object, optional): PuppeteerJS LaunchOptions. Default null. If changed and not null, browser restarts. Example: `{ headless: true, args: ['--user-data-dir="C:/Data"'] }`
- `allowDangerous` (boolean, optional): Allow dangerous LaunchOptions that reduce security. When false, dangerous args like `--no-sandbox`, `--disable-web-security` will throw errors. Default false.
- **puppeteer_screenshot** - **puppeteer_screenshot**
- Capture screenshots of the entire page or specific elements - Capture screenshots of the entire page or specific elements
@@ -61,6 +64,7 @@ The server provides access to two types of resources:
- Screenshot capabilities - Screenshot capabilities
- JavaScript execution - JavaScript execution
- Basic web interaction (navigation, clicking, form filling) - Basic web interaction (navigation, clicking, form filling)
- Customizable Puppeteer launch options
## Configuration to use Puppeteer Server ## Configuration to use Puppeteer Server
Here's the Claude Desktop configuration to use the Puppeter server: Here's the Claude Desktop configuration to use the Puppeter server:
@@ -93,6 +97,39 @@ Here's the Claude Desktop configuration to use the Puppeter server:
} }
``` ```
### Launch Options
You can customize Puppeteer's browser behavior in two ways:
1. **Environment Variable**: Set `PUPPETEER_LAUNCH_OPTIONS` with a JSON-encoded string in the MCP configuration's `env` parameter:
```json
{
"mcpServers": {
"mcp-puppeteer": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-puppeteer"]
"env": {
"PUPPETEER_LAUNCH_OPTIONS": "{ \"headless\": false, \"executablePath\": \"C:/Program Files/Google/Chrome/Application/chrome.exe\", \"args\": [] }",
"ALLOW_DANGEROUS": "true"
}
}
}
}
```
2. **Tool Call Arguments**: Pass `launchOptions` and `allowDangerous` parameters to the `puppeteer_navigate` tool:
```json
{
"url": "https://example.com",
"launchOptions": {
"headless": false,
"defaultViewport": {"width": 1280, "height": 720}
}
}
```
## Build ## Build
Docker build: Docker build:

View File

@@ -22,7 +22,9 @@ const TOOLS: Tool[] = [
inputSchema: { inputSchema: {
type: "object", type: "object",
properties: { properties: {
url: { type: "string" }, url: { type: "string", description: "URL to navigate to" },
launchOptions: { type: "object", description: "PuppeteerJS LaunchOptions. Default null. If changed and not null, browser restarts. Example: { headless: true, args: ['--no-sandbox'] }" },
allowDangerous: { type: "boolean", description: "Allow dangerous LaunchOptions that reduce security. When false, dangerous args like --no-sandbox will throw errors. Default false." },
}, },
required: ["url"], required: ["url"],
}, },
@@ -101,16 +103,65 @@ const TOOLS: Tool[] = [
]; ];
// Global state // Global state
let browser: Browser | undefined; let browser: Browser | null;
let page: Page | undefined; let page: Page | null;
const consoleLogs: string[] = []; const consoleLogs: string[] = [];
const screenshots = new Map<string, string>(); const screenshots = new Map<string, string>();
let previousLaunchOptions: any = null;
async function ensureBrowser({ launchOptions, allowDangerous }: any) {
const DANGEROUS_ARGS = [
'--no-sandbox',
'--disable-setuid-sandbox',
'--single-process',
'--disable-web-security',
'--ignore-certificate-errors',
'--disable-features=IsolateOrigins',
'--disable-site-isolation-trials',
'--allow-running-insecure-content'
];
// Parse environment config safely
let envConfig = {};
try {
envConfig = JSON.parse(process.env.PUPPETEER_LAUNCH_OPTIONS || '{}');
} catch (error: any) {
console.warn('Failed to parse PUPPETEER_LAUNCH_OPTIONS:', error?.message || error);
}
// Deep merge environment config with user-provided options
const mergedConfig = deepMerge(envConfig, launchOptions || {});
// Security validation for merged config
if (mergedConfig?.args) {
const dangerousArgs = mergedConfig.args?.filter?.((arg: string) => DANGEROUS_ARGS.some((dangerousArg: string) => arg.startsWith(dangerousArg)));
if (dangerousArgs?.length > 0 && !(allowDangerous || (process.env.ALLOW_DANGEROUS === 'true'))) {
throw new Error(`Dangerous browser arguments detected: ${dangerousArgs.join(', ')}. Fround from environment variable and tool call argument. ` +
'Set allowDangerous: true in the tool call arguments to override.');
}
}
try {
if ((browser && !browser.connected) ||
(launchOptions && (JSON.stringify(launchOptions) != JSON.stringify(previousLaunchOptions)))) {
await browser?.close();
browser = null;
}
}
catch (error) {
browser = null;
}
previousLaunchOptions = launchOptions;
async function ensureBrowser() {
if (!browser) { if (!browser) {
const npx_args = { headless: false } const npx_args = { headless: false }
const docker_args = { headless: true, args: ["--no-sandbox", "--single-process", "--no-zygote"] } const docker_args = { headless: true, args: ["--no-sandbox", "--single-process", "--no-zygote"] }
browser = await puppeteer.launch(process.env.DOCKER_CONTAINER ? docker_args : npx_args); browser = await puppeteer.launch(deepMerge(
process.env.DOCKER_CONTAINER ? docker_args : npx_args,
mergedConfig
));
const pages = await browser.pages(); const pages = await browser.pages();
page = pages[0]; page = pages[0];
@@ -126,6 +177,31 @@ async function ensureBrowser() {
return page!; return page!;
} }
// Deep merge utility function
function deepMerge(target: any, source: any): any {
const output = Object.assign({}, target);
if (typeof target !== 'object' || typeof source !== 'object') return source;
for (const key of Object.keys(source)) {
const targetVal = target[key];
const sourceVal = source[key];
if (Array.isArray(targetVal) && Array.isArray(sourceVal)) {
// Deduplicate args/ignoreDefaultArgs, prefer source values
output[key] = [...new Set([
...(key === 'args' || key === 'ignoreDefaultArgs' ?
targetVal.filter((arg: string) => !sourceVal.some((launchArg: string) => arg.startsWith('--') && launchArg.startsWith(arg.split('=')[0]))) :
targetVal),
...sourceVal
])];
} else if (sourceVal instanceof Object && key in target) {
output[key] = deepMerge(targetVal, sourceVal);
} else {
output[key] = sourceVal;
}
}
return output;
}
declare global { declare global {
interface Window { interface Window {
mcpHelper: { mcpHelper: {
@@ -136,7 +212,7 @@ declare global {
} }
async function handleToolCall(name: string, args: any): Promise<CallToolResult> { async function handleToolCall(name: string, args: any): Promise<CallToolResult> {
const page = await ensureBrowser(); const page = await ensureBrowser(args);
switch (name) { switch (name) {
case "puppeteer_navigate": case "puppeteer_navigate":
@@ -285,15 +361,15 @@ async function handleToolCall(name: string, args: any): Promise<CallToolResult>
window.mcpHelper.logs.push(`[${method}] ${args.join(' ')}`); window.mcpHelper.logs.push(`[${method}] ${args.join(' ')}`);
(window.mcpHelper.originalConsole as any)[method](...args); (window.mcpHelper.originalConsole as any)[method](...args);
}; };
} ); });
} ); });
const result = await page.evaluate( args.script ); const result = await page.evaluate(args.script);
const logs = await page.evaluate(() => { const logs = await page.evaluate(() => {
Object.assign(console, window.mcpHelper.originalConsole); Object.assign(console, window.mcpHelper.originalConsole);
const logs = window.mcpHelper.logs; const logs = window.mcpHelper.logs;
delete ( window as any).mcpHelper; delete (window as any).mcpHelper;
return logs; return logs;
}); });