Merge branch 'main' into feature/monzo-mcp-bfdcampos
This commit is contained in:
commit
1705a35131
90 changed files with 1766 additions and 16840 deletions
25
README.md
25
README.md
|
|
@ -12,26 +12,31 @@ Each MCP server is implemented with either the [Typescript MCP SDK](https://gith
|
|||
|
||||
These servers aim to demonstrate MCP features and the TypeScript and Python SDKs.
|
||||
|
||||
- **[AWS KB Retrieval](src/aws-kb-retrieval-server)** - Retrieval from AWS Knowledge Base using Bedrock Agent Runtime
|
||||
- **[Brave Search](src/brave-search)** - Web and local search using Brave's Search API
|
||||
- **[EverArt](src/everart)** - AI image generation using various models
|
||||
- **[Everything](src/everything)** - Reference / test server with prompts, resources, and tools
|
||||
- **[Fetch](src/fetch)** - Web content fetching and conversion for efficient LLM usage
|
||||
- **[Filesystem](src/filesystem)** - Secure file operations with configurable access controls
|
||||
- **[Memory](src/memory)** - Knowledge graph-based persistent memory system
|
||||
- **[Sequential Thinking](src/sequentialthinking)** - Dynamic and reflective problem-solving through thought sequences
|
||||
- **[Time](src/time)** - Time and timezone conversion capabilities
|
||||
|
||||
### Archived
|
||||
|
||||
The following reference servers are now archived and can be found at [servers-archived](https://github.com/modelcontextprotocol/servers-archived).
|
||||
|
||||
- **[AWS KB Retrieval](src/aws-kb-retrieval-server)** - Retrieval from AWS Knowledge Base using Bedrock Agent Runtime
|
||||
- **[Brave Search](src/brave-search)** - Web and local search using Brave's Search API
|
||||
- **[EverArt](src/everart)** - AI image generation using various models
|
||||
- **[Git](src/git)** - Tools to read, search, and manipulate Git repositories
|
||||
- **[GitHub](src/github)** - Repository management, file operations, and GitHub API integration
|
||||
- **[GitLab](src/gitlab)** - GitLab API, enabling project management
|
||||
- **[Google Drive](src/gdrive)** - File access and search capabilities for Google Drive
|
||||
- **[Google Maps](src/google-maps)** - Location services, directions, and place details
|
||||
- **[Memory](src/memory)** - Knowledge graph-based persistent memory system
|
||||
- **[PostgreSQL](src/postgres)** - Read-only database access with schema inspection
|
||||
- **[Puppeteer](src/puppeteer)** - Browser automation and web scraping
|
||||
- **[Redis](src/redis)** - Interact with Redis key-value stores
|
||||
- **[Sentry](src/sentry)** - Retrieving and analyzing issues from Sentry.io
|
||||
- **[Sequential Thinking](src/sequentialthinking)** - Dynamic and reflective problem-solving through thought sequences
|
||||
- **[Slack](src/slack)** - Channel management and messaging capabilities
|
||||
- **[Sqlite](src/sqlite)** - Database interaction and business intelligence capabilities
|
||||
- **[Time](src/time)** - Time and timezone conversion capabilities
|
||||
|
||||
## 🤝 Third-Party Servers
|
||||
|
||||
|
|
@ -157,6 +162,7 @@ Official integrations are maintained by companies building production ready MCP
|
|||
- <img height="12" width="12" src="https://avatars.githubusercontent.com/u/54333248" /> **[Pinecone Assistant](https://github.com/pinecone-io/assistant-mcp)** - Retrieves context from your [Pinecone Assistant](https://docs.pinecone.io/guides/assistant/mcp-server) knowledge base.
|
||||
- <img height="12" width="12" src="https://www.prisma.io/images/favicon-32x32.png" alt="Prisma Logo" /> **[Prisma](https://www.prisma.io/docs/postgres/mcp-server)** - Create and manage Prisma Postgres databases
|
||||
- <img height="12" width="12" src="https://www.pulumi.com/images/favicon.ico" alt="Pulumi Logo" /> **[Pulumi](https://github.com/pulumi/mcp-server)** - Deploy and manage cloud infrastructure using [Pulumi](https://pulumi.com).
|
||||
- <img height="12" width="12" src="https://pure.md/favicon.png" alt="Pure.md Logo" /> **[Pure.md](https://github.com/puremd/puremd-mcp)** - Reliably access web content in markdown format with [pure.md](https://pure.md) (bot detection avoidance, proxy rotation, and headless JS rendering built in).
|
||||
- <img height="12" width="12" src="https://put.io/images/favicon.ico" alt="Put.io Logo" /> **[Put.io](https://github.com/putdotio/putio-mcp-server)** - Interact with your Put.io account to download torrents.
|
||||
- <img height="12" width="12" src="https://avatars.githubusercontent.com/u/165178062" /> **[Ragie](https://github.com/ragieai/ragie-mcp-server/)** - Retrieve context from your [Ragie](https://www.ragie.ai) (RAG) knowledge base connected to integrations like Google Drive, Notion, JIRA and more.
|
||||
- <img height="12" width="12" src="https://avatars.githubusercontent.com/u/1529926" /> **[Redis](https://github.com/redis/mcp-redis/)** - The Redis official MCP Server offers an interface to manage and search data in Redis.
|
||||
|
|
@ -382,8 +388,10 @@ A growing set of community-developed and maintained servers demonstrates various
|
|||
- **[MariaDB](https://github.com/abel9851/mcp-server-mariadb)** - MariaDB database integration with configurable access controls in Python.
|
||||
- **[Markdown2doc](https://github.com/Klavis-AI/klavis/tree/main/mcp_servers/pandoc)** - Convert between various file formats using Pandoc
|
||||
- **[Markitdown](https://github.com/Klavis-AI/klavis/tree/main/mcp_servers/markitdown)** - Convert files to Markdown
|
||||
- **[Matlab-MCP-Tools](https://github.com/neuromechanist/matlab-mcp-tools)** - An MCP to write and execute MATLAB scripts, maintain workspace context between MCP calls, visualize plots, and perform section-by-section analysis of MATLAB code with full access to MATLAB's computational capabilities.
|
||||
- **[Maton](https://github.com/maton-ai/agent-toolkit/tree/main/modelcontextprotocol)** - Connect to your SaaS tools like HubSpot, Salesforce, and more.
|
||||
- **[MCP Compass](https://github.com/liuyoshio/mcp-compass)** - Suggest the right MCP server for your needs
|
||||
- **[mcp-containerd](https://github.com/jokemanfire/mcp-containerd)** - The containerd MCP implemented by Rust supports the operation of the CRI interface.
|
||||
- **[MCP Create](https://github.com/tesla0225/mcp-create)** - A dynamic MCP server management service that creates, runs, and manages Model Context Protocol servers on-the-fly.
|
||||
- **[MCP Installer](https://github.com/anaisbetts/mcp-installer)** - This server is a server that installs other MCP servers for you.
|
||||
- **[mcp-k8s-go](https://github.com/strowk/mcp-k8s-go)** - Golang-based Kubernetes server for MCP to browse pods and their logs, events, namespaces and more. Built to be extensible.
|
||||
|
|
@ -409,6 +417,7 @@ A growing set of community-developed and maintained servers demonstrates various
|
|||
- **[Mobile MCP](https://github.com/mobile-next/mobile-mcp)** (by Mobile Next) - MCP server for Mobile(iOS/Android) automation, app scraping and development using physical devices or simulators/emulators.
|
||||
- **[MongoDB](https://github.com/kiliczsh/mcp-mongo-server)** - A Model Context Protocol Server for MongoDB.
|
||||
- **[MongoDB Lens](https://github.com/furey/mongodb-lens)** - Full Featured MCP Server for MongoDB Databases.
|
||||
- **[MongoDB & Mongoose](https://github.com/nabid-pf/mongo-mongoose-mcp)** - MongoDB MCP Server with Mongoose Schema and Validation.
|
||||
- **[Monday.com](https://github.com/sakce/mcp-server-monday)** - MCP Server to interact with Monday.com boards and items.
|
||||
- **[Monzo](https://github.com/BfdCampos/monzo-mcp-bfdcampos)** - Access and manage your Monzo bank accounts through natural language, including balance checking, pot management, transaction listing, and transaction annotation across multiple account types (personal, joint, flex).
|
||||
- **[Morningstar](https://github.com/Morningstar/morningstar-mcp-server)** - MCP Server to interact with Morningstar Research, Editorial and Datapoints
|
||||
|
|
@ -416,6 +425,7 @@ A growing set of community-developed and maintained servers demonstrates various
|
|||
- **[Multi-Model Advisor](https://github.com/YuChenSSR/multi-ai-advisor-mcp)** - A Model Context Protocol (MCP) server that orchestrates queries across multiple Ollama models, synthesizing their insights to deliver a comprehensive and multifaceted AI perspective on any given query.
|
||||
- **[MySQL](https://github.com/benborla/mcp-server-mysql)** (by benborla) - MySQL database integration in NodeJS with configurable access controls and schema inspection
|
||||
- **[MySQL](https://github.com/designcomputer/mysql_mcp_server)** (by DesignComputer) - MySQL database integration in Python with configurable access controls and schema inspection
|
||||
- **[MasterGo](https://github.com/mastergo-design/mastergo-magic-mcp)** - The server designed to connect MasterGo design tools with AI models. It enables AI models to directly retrieve DSL data from MasterGo design files.
|
||||
- **[n8n](https://github.com/leonardsellem/n8n-mcp-server)** - This MCP server provides tools and resources for AI assistants to manage n8n workflows and executions, including listing, creating, updating, and deleting workflows, as well as monitoring their execution status.
|
||||
- **[NASA](https://github.com/ProgramComputer/NASA-MCP-server)** (by ProgramComputer) - Access to a unified gateway of NASA's data sources including but not limited to APOD, NEO, EPIC, GIBS.
|
||||
- **[Nasdaq Data Link](https://github.com/stefanoamorelli/nasdaq-data-link-mcp)** (by stefanoamorelli) - An MCP server to access, explore, and interact with Nasdaq Data Link's extensive and valuable financial and economic datasets.
|
||||
|
|
@ -477,6 +487,7 @@ A growing set of community-developed and maintained servers demonstrates various
|
|||
- **[Reaper](https://github.com/dschuler36/reaper-mcp-server)** - Interact with your [Reaper](https://www.reaper.fm/) (Digital Audio Workstation) projects.
|
||||
- **[Redis](https://github.com/GongRzhe/REDIS-MCP-Server)** - Redis database operations and caching microservice server with support for key-value operations, expiration management, and pattern-based key listing.
|
||||
- **[Redis](https://github.com/prajwalnayak7/mcp-server-redis)** MCP server to interact with Redis Server, AWS Memory DB, etc for caching or other use-cases where in-memory and key-value based storage is appropriate
|
||||
- **[Reed Jobs](https://github.com/kld3v/reed_jobs_mcp)** - Search and retrieve job listings from Reed.co.uk.
|
||||
- **[Rememberizer AI](https://github.com/skydeckai/mcp-server-rememberizer)** - An MCP server designed for interacting with the Rememberizer data source, facilitating enhanced knowledge retrieval.
|
||||
- **[Replicate](https://github.com/deepfates/mcp-replicate)** - Search, run and manage machine learning models on Replicate through a simple tool-based interface. Browse models, create predictions, track their status, and handle generated images.
|
||||
- **[Resend](https://github.com/Klavis-AI/klavis/tree/main/mcp_servers/resend)** - Send email using Resend services
|
||||
|
|
@ -500,6 +511,7 @@ A growing set of community-developed and maintained servers demonstrates various
|
|||
- **[SoccerDataAPI](https://github.com/yeonupark/mcp-soccer-data)** - This MCP server provides real-time football match data based on the SoccerDataAPI.
|
||||
- **[Solana Agent Kit](https://github.com/sendaifun/solana-agent-kit/tree/main/examples/agent-kit-mcp-server)** - This MCP server enables LLMs to interact with the Solana blockchain with help of Solana Agent Kit by SendAI, allowing for 40+ protcool actions and growing
|
||||
- **[Spotify](https://github.com/varunneal/spotify-mcp)** - This MCP allows an LLM to play and use Spotify.
|
||||
- **[Standard Korean Dictionary](https://github.com/privetin/stdict)** - Search the dictionary using API
|
||||
- **[Starwind UI](https://github.com/Boston343/starwind-ui-mcp/)** - This MCP provides relevant commands, documentation, and other information to allow LLMs to take full advantage of Starwind UI's open source Astro components.
|
||||
- **[Strava](https://github.com/r-huijts/strava-mcp)** - Connect to the Strava API to access activity data, athlete profiles, segments, and routes, enabling fitness tracking and analysis with Claude.
|
||||
- **[Stripe](https://github.com/atharvagupta2003/mcp-stripe)** - This MCP allows integration with Stripe for handling payments, customers, and refunds.
|
||||
|
|
@ -550,6 +562,7 @@ A growing set of community-developed and maintained servers demonstrates various
|
|||
- **[YNAB](https://github.com/ChuckBryan/ynabmcpserver)** - A Model Context Protocol (MCP) server for integrating with YNAB (You Need A Budget), allowing AI assistants to securely access and analyze your financial data.
|
||||
- **[YouTube](https://github.com/Klavis-AI/klavis/tree/main/mcp_servers/youtube)** - Extract Youtube video information (with proxies support).
|
||||
- **[YouTube](https://github.com/ZubeidHendricks/youtube-mcp-server)** - Comprehensive YouTube API integration for video management, Shorts creation, and analytics.
|
||||
- **[YouTube Video Summarizer](https://github.com/nabid-pf/youtube-video-summarizer-mcp)** - Summarize lengthy youtube videos.
|
||||
- **[Zoom](https://github.com/Prathamesh0901/zoom-mcp-server/tree/main)** - Create, update, read and delete your zoom meetings.
|
||||
- **[mcp_weather](https://github.com/isdaniel/mcp_weather_server)** - Get weather information from <https://api.open-meteo.com> API.
|
||||
|
||||
|
|
|
|||
4176
package-lock.json
generated
4176
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -20,14 +20,8 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/server-everything": "*",
|
||||
"@modelcontextprotocol/server-gdrive": "*",
|
||||
"@modelcontextprotocol/server-postgres": "*",
|
||||
"@modelcontextprotocol/server-puppeteer": "*",
|
||||
"@modelcontextprotocol/server-slack": "*",
|
||||
"@modelcontextprotocol/server-brave-search": "*",
|
||||
"@modelcontextprotocol/server-memory": "*",
|
||||
"@modelcontextprotocol/server-filesystem": "*",
|
||||
"@modelcontextprotocol/server-everart": "*",
|
||||
"@modelcontextprotocol/server-sequential-thinking": "*"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
FROM node:22.12-alpine AS builder
|
||||
|
||||
COPY src/aws-kb-retrieval-server /app
|
||||
COPY tsconfig.json /tsconfig.json
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN --mount=type=cache,target=/root/.npm npm install
|
||||
|
||||
FROM node:22-alpine AS release
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/dist /app/dist
|
||||
COPY --from=builder /app/package.json /app/package.json
|
||||
COPY --from=builder /app/package-lock.json /app/package-lock.json
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
RUN npm ci --ignore-scripts --omit-dev
|
||||
|
||||
ENTRYPOINT ["node", "dist/index.js"]
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
# AWS Knowledge Base Retrieval MCP Server
|
||||
|
||||
An MCP server implementation for retrieving information from the AWS Knowledge Base using the Bedrock Agent Runtime.
|
||||
|
||||
## Features
|
||||
|
||||
- **RAG (Retrieval-Augmented Generation)**: Retrieve context from the AWS Knowledge Base based on a query and a Knowledge Base ID.
|
||||
- **Supports multiple results retrieval**: Option to retrieve a customizable number of results.
|
||||
|
||||
## Tools
|
||||
|
||||
- **retrieve_from_aws_kb**
|
||||
- Perform retrieval operations using the AWS Knowledge Base.
|
||||
- Inputs:
|
||||
- `query` (string): The search query for retrieval.
|
||||
- `knowledgeBaseId` (string): The ID of the AWS Knowledge Base.
|
||||
- `n` (number, optional): Number of results to retrieve (default: 3).
|
||||
|
||||
## Configuration
|
||||
|
||||
### Setting up AWS Credentials
|
||||
|
||||
1. Obtain AWS access key ID, secret access key, and region from the AWS Management Console.
|
||||
2. Ensure these credentials have appropriate permissions for Bedrock Agent Runtime operations.
|
||||
|
||||
### Usage with Claude Desktop
|
||||
|
||||
Add this to your `claude_desktop_config.json`:
|
||||
|
||||
#### Docker
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"aws-kb-retrieval": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
"AWS_ACCESS_KEY_ID",
|
||||
"-e",
|
||||
"AWS_SECRET_ACCESS_KEY",
|
||||
"-e",
|
||||
"AWS_REGION",
|
||||
"mcp/aws-kb-retrieval-server"
|
||||
],
|
||||
"env": {
|
||||
"AWS_ACCESS_KEY_ID": "YOUR_ACCESS_KEY_HERE",
|
||||
"AWS_SECRET_ACCESS_KEY": "YOUR_SECRET_ACCESS_KEY_HERE",
|
||||
"AWS_REGION": "YOUR_AWS_REGION_HERE"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"aws-kb-retrieval": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-aws-kb-retrieval"],
|
||||
"env": {
|
||||
"AWS_ACCESS_KEY_ID": "YOUR_ACCESS_KEY_HERE",
|
||||
"AWS_SECRET_ACCESS_KEY": "YOUR_SECRET_ACCESS_KEY_HERE",
|
||||
"AWS_REGION": "YOUR_AWS_REGION_HERE"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Usage with VS Code
|
||||
|
||||
For quick installation, use one of the one-click install buttons below...
|
||||
|
||||
[](https://insiders.vscode.dev/redirect/mcp/install?name=aws-kb-retrieval&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_access_key%22%2C%22description%22%3A%22AWS%20Access%20Key%20ID%22%2C%22password%22%3Atrue%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_secret_key%22%2C%22description%22%3A%22AWS%20Secret%20Access%20Key%22%2C%22password%22%3Atrue%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_region%22%2C%22description%22%3A%22AWS%20Region%22%7D%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-aws-kb-retrieval%22%5D%2C%22env%22%3A%7B%22AWS_ACCESS_KEY_ID%22%3A%22%24%7Binput%3Aaws_access_key%7D%22%2C%22AWS_SECRET_ACCESS_KEY%22%3A%22%24%7Binput%3Aaws_secret_key%7D%22%2C%22AWS_REGION%22%3A%22%24%7Binput%3Aaws_region%7D%22%7D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=aws-kb-retrieval&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_access_key%22%2C%22description%22%3A%22AWS%20Access%20Key%20ID%22%2C%22password%22%3Atrue%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_secret_key%22%2C%22description%22%3A%22AWS%20Secret%20Access%20Key%22%2C%22password%22%3Atrue%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_region%22%2C%22description%22%3A%22AWS%20Region%22%7D%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-aws-kb-retrieval%22%5D%2C%22env%22%3A%7B%22AWS_ACCESS_KEY_ID%22%3A%22%24%7Binput%3Aaws_access_key%7D%22%2C%22AWS_SECRET_ACCESS_KEY%22%3A%22%24%7Binput%3Aaws_secret_key%7D%22%2C%22AWS_REGION%22%3A%22%24%7Binput%3Aaws_region%7D%22%7D%7D&quality=insiders)
|
||||
|
||||
[](https://insiders.vscode.dev/redirect/mcp/install?name=aws-kb-retrieval&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_access_key%22%2C%22description%22%3A%22AWS%20Access%20Key%20ID%22%2C%22password%22%3Atrue%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_secret_key%22%2C%22description%22%3A%22AWS%20Secret%20Access%20Key%22%2C%22password%22%3Atrue%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_region%22%2C%22description%22%3A%22AWS%20Region%22%7D%5D&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22mcp%2Faws-kb-retrieval-server%22%5D%2C%22env%22%3A%7B%22AWS_ACCESS_KEY_ID%22%3A%22%24%7Binput%3Aaws_access_key%7D%22%2C%22AWS_SECRET_ACCESS_KEY%22%3A%22%24%7Binput%3Aaws_secret_key%7D%22%2C%22AWS_REGION%22%3A%22%24%7Binput%3Aaws_region%7D%22%7D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=aws-kb-retrieval&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_access_key%22%2C%22description%22%3A%22AWS%20Access%20Key%20ID%22%2C%22password%22%3Atrue%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_secret_key%22%2C%22description%22%3A%22AWS%20Secret%20Access%20Key%22%2C%22password%22%3Atrue%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22aws_region%22%2C%22description%22%3A%22AWS%20Region%22%7D%5D&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22mcp%2Faws-kb-retrieval-server%22%5D%2C%22env%22%3A%7B%22AWS_ACCESS_KEY_ID%22%3A%22%24%7Binput%3Aaws_access_key%7D%22%2C%22AWS_SECRET_ACCESS_KEY%22%3A%22%24%7Binput%3Aaws_secret_key%7D%22%2C%22AWS_REGION%22%3A%22%24%7Binput%3Aaws_region%7D%22%7D%7D&quality=insiders)
|
||||
|
||||
#### Manual Installation
|
||||
|
||||
For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open Settings (JSON)`.
|
||||
|
||||
Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
|
||||
|
||||
> Note that the `mcp` key is not needed in the `.vscode/mcp.json` file.
|
||||
|
||||
```json
|
||||
{
|
||||
"mcp": {
|
||||
"inputs": [
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "aws_access_key",
|
||||
"description": "AWS Access Key ID",
|
||||
"password": true
|
||||
},
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "aws_secret_key",
|
||||
"description": "AWS Secret Access Key",
|
||||
"password": true
|
||||
},
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "aws_region",
|
||||
"description": "AWS Region"
|
||||
}
|
||||
],
|
||||
"servers": {
|
||||
"aws-kb-retrieval": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-aws-kb-retrieval"],
|
||||
"env": {
|
||||
"AWS_ACCESS_KEY_ID": "${input:aws_access_key}",
|
||||
"AWS_SECRET_ACCESS_KEY": "${input:aws_secret_key}",
|
||||
"AWS_REGION": "${input:aws_region}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For Docker installation:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcp": {
|
||||
"inputs": [
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "aws_access_key",
|
||||
"description": "AWS Access Key ID",
|
||||
"password": true
|
||||
},
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "aws_secret_key",
|
||||
"description": "AWS Secret Access Key",
|
||||
"password": true
|
||||
},
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "aws_region",
|
||||
"description": "AWS Region"
|
||||
}
|
||||
],
|
||||
"servers": {
|
||||
"aws-kb-retrieval": {
|
||||
"command": "docker",
|
||||
"args": ["run", "-i", "--rm", "mcp/aws-kb-retrieval-server"],
|
||||
"env": {
|
||||
"AWS_ACCESS_KEY_ID": "${input:aws_access_key}",
|
||||
"AWS_SECRET_ACCESS_KEY": "${input:aws_secret_key}",
|
||||
"AWS_REGION": "${input:aws_region}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
Docker:
|
||||
|
||||
```sh
|
||||
docker build -t mcp/aws-kb-retrieval -f src/aws-kb-retrieval-server/Dockerfile .
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import {
|
||||
CallToolRequestSchema,
|
||||
ListToolsRequestSchema,
|
||||
Tool,
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
import {
|
||||
BedrockAgentRuntimeClient,
|
||||
RetrieveCommand,
|
||||
RetrieveCommandInput,
|
||||
} from "@aws-sdk/client-bedrock-agent-runtime";
|
||||
|
||||
// AWS client initialization
|
||||
const bedrockClient = new BedrockAgentRuntimeClient({
|
||||
region: process.env.AWS_REGION,
|
||||
credentials: {
|
||||
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
||||
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
||||
},
|
||||
});
|
||||
|
||||
interface RAGSource {
|
||||
id: string;
|
||||
fileName: string;
|
||||
snippet: string;
|
||||
score: number;
|
||||
}
|
||||
|
||||
async function retrieveContext(
|
||||
query: string,
|
||||
knowledgeBaseId: string,
|
||||
n: number = 3
|
||||
): Promise<{
|
||||
context: string;
|
||||
isRagWorking: boolean;
|
||||
ragSources: RAGSource[];
|
||||
}> {
|
||||
try {
|
||||
if (!knowledgeBaseId) {
|
||||
console.error("knowledgeBaseId is not provided");
|
||||
return {
|
||||
context: "",
|
||||
isRagWorking: false,
|
||||
ragSources: [],
|
||||
};
|
||||
}
|
||||
|
||||
const input: RetrieveCommandInput = {
|
||||
knowledgeBaseId: knowledgeBaseId,
|
||||
retrievalQuery: { text: query },
|
||||
retrievalConfiguration: {
|
||||
vectorSearchConfiguration: { numberOfResults: n },
|
||||
},
|
||||
};
|
||||
|
||||
const command = new RetrieveCommand(input);
|
||||
const response = await bedrockClient.send(command);
|
||||
const rawResults = response?.retrievalResults || [];
|
||||
const ragSources: RAGSource[] = rawResults
|
||||
.filter((res) => res?.content?.text)
|
||||
.map((result, index) => {
|
||||
const uri = result?.location?.s3Location?.uri || "";
|
||||
const fileName = uri.split("/").pop() || `Source-${index}.txt`;
|
||||
return {
|
||||
id: (result.metadata?.["x-amz-bedrock-kb-chunk-id"] as string) || `chunk-${index}`,
|
||||
fileName: fileName.replace(/_/g, " ").replace(".txt", ""),
|
||||
snippet: result.content?.text || "",
|
||||
score: (result.score as number) || 0,
|
||||
};
|
||||
})
|
||||
.slice(0, 3);
|
||||
|
||||
const context = rawResults
|
||||
.filter((res): res is { content: { text: string } } => res?.content?.text !== undefined)
|
||||
.map(res => res.content.text)
|
||||
.join("\n\n");
|
||||
|
||||
return {
|
||||
context,
|
||||
isRagWorking: true,
|
||||
ragSources,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("RAG Error:", error);
|
||||
return { context: "", isRagWorking: false, ragSources: [] };
|
||||
}
|
||||
}
|
||||
|
||||
// Define the retrieval tool
|
||||
const RETRIEVAL_TOOL: Tool = {
|
||||
name: "retrieve_from_aws_kb",
|
||||
description: "Performs retrieval from the AWS Knowledge Base using the provided query and Knowledge Base ID.",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
query: { type: "string", description: "The query to perform retrieval on" },
|
||||
knowledgeBaseId: { type: "string", description: "The ID of the AWS Knowledge Base" },
|
||||
n: { type: "number", default: 3, description: "Number of results to retrieve" },
|
||||
},
|
||||
required: ["query", "knowledgeBaseId"],
|
||||
},
|
||||
};
|
||||
|
||||
// Server setup
|
||||
const server = new Server(
|
||||
{
|
||||
name: "aws-kb-retrieval-server",
|
||||
version: "0.2.0",
|
||||
},
|
||||
{
|
||||
capabilities: {
|
||||
tools: {},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// Request handlers
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
||||
tools: [RETRIEVAL_TOOL],
|
||||
}));
|
||||
|
||||
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
const { name, arguments: args } = request.params;
|
||||
|
||||
if (name === "retrieve_from_aws_kb") {
|
||||
const { query, knowledgeBaseId, n = 3 } = args as Record<string, any>;
|
||||
try {
|
||||
const result = await retrieveContext(query, knowledgeBaseId, n);
|
||||
if (result.isRagWorking) {
|
||||
return {
|
||||
content: [
|
||||
{ type: "text", text: `Context: ${result.context}` },
|
||||
{ type: "text", text: `RAG Sources: ${JSON.stringify(result.ragSources)}` },
|
||||
],
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
content: [{ type: "text", text: "Retrieval failed or returned no results." }],
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [{ type: "text", text: `Error occurred: ${error}` }],
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Server startup
|
||||
async function runServer() {
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
console.error("AWS KB Retrieval Server running on stdio");
|
||||
}
|
||||
|
||||
runServer().catch((error) => {
|
||||
console.error("Fatal error running server:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
{
|
||||
"name": "@modelcontextprotocol/server-aws-kb-retrieval",
|
||||
"version": "0.6.2",
|
||||
"description": "MCP server for AWS Knowledge Base retrieval using Bedrock Agent Runtime",
|
||||
"license": "MIT",
|
||||
"author": "Anthropic, PBC (https://anthropic.com)",
|
||||
"homepage": "https://modelcontextprotocol.io",
|
||||
"bugs": "https://github.com/modelcontextprotocol/servers/issues",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"mcp-server-aws-kb-retrieval": "dist/index.js"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc && shx chmod +x dist/*.js",
|
||||
"prepare": "npm run build",
|
||||
"watch": "tsc --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "0.5.0",
|
||||
"@aws-sdk/client-bedrock-agent-runtime": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22",
|
||||
"shx": "^0.3.4",
|
||||
"typescript": "^5.6.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": ".",
|
||||
"composite": true,
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": "./dist/.tsbuildinfo"
|
||||
},
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
FROM node:22.12-alpine AS builder
|
||||
|
||||
# Must be entire project because `prepare` script is run during `npm install` and requires all files.
|
||||
COPY src/brave-search /app
|
||||
COPY tsconfig.json /tsconfig.json
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN --mount=type=cache,target=/root/.npm npm install
|
||||
|
||||
FROM node:22-alpine AS release
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/dist /app/dist
|
||||
COPY --from=builder /app/package.json /app/package.json
|
||||
COPY --from=builder /app/package-lock.json /app/package-lock.json
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
RUN npm ci --ignore-scripts --omit-dev
|
||||
|
||||
ENTRYPOINT ["node", "dist/index.js"]
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
# Brave Search MCP Server
|
||||
|
||||
An MCP server implementation that integrates the Brave Search API, providing both web and local search capabilities.
|
||||
|
||||
## Features
|
||||
|
||||
- **Web Search**: General queries, news, articles, with pagination and freshness controls
|
||||
- **Local Search**: Find businesses, restaurants, and services with detailed information
|
||||
- **Flexible Filtering**: Control result types, safety levels, and content freshness
|
||||
- **Smart Fallbacks**: Local search automatically falls back to web when no results are found
|
||||
|
||||
## Tools
|
||||
|
||||
- **brave_web_search**
|
||||
|
||||
- Execute web searches with pagination and filtering
|
||||
- Inputs:
|
||||
- `query` (string): Search terms
|
||||
- `count` (number, optional): Results per page (max 20)
|
||||
- `offset` (number, optional): Pagination offset (max 9)
|
||||
|
||||
- **brave_local_search**
|
||||
- Search for local businesses and services
|
||||
- Inputs:
|
||||
- `query` (string): Local search terms
|
||||
- `count` (number, optional): Number of results (max 20)
|
||||
- Automatically falls back to web search if no local results found
|
||||
|
||||
## Configuration
|
||||
|
||||
### Getting an API Key
|
||||
|
||||
1. Sign up for a [Brave Search API account](https://brave.com/search/api/)
|
||||
2. Choose a plan (Free tier available with 2,000 queries/month)
|
||||
3. Generate your API key [from the developer dashboard](https://api-dashboard.search.brave.com/app/keys)
|
||||
|
||||
### Usage with Claude Desktop
|
||||
|
||||
Add this to your `claude_desktop_config.json`:
|
||||
|
||||
### Docker
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"brave-search": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
"BRAVE_API_KEY",
|
||||
"mcp/brave-search"
|
||||
],
|
||||
"env": {
|
||||
"BRAVE_API_KEY": "YOUR_API_KEY_HERE"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### NPX
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"brave-search": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-brave-search"
|
||||
],
|
||||
"env": {
|
||||
"BRAVE_API_KEY": "YOUR_API_KEY_HERE"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Usage with VS Code
|
||||
|
||||
For quick installation, use the one-click installation buttons below...
|
||||
|
||||
[](https://insiders.vscode.dev/redirect/mcp/install?name=brave&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22apiKey%22%7D%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-brave-search%22%5D%2C%22env%22%3A%7B%22BRAVE_API_KEY%22%3A%22%24%7Binput%3Abrave_api_key%7D%22%7D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=brave&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22apiKey%22%7D%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-brave-search%22%5D%2C%22env%22%3A%7B%22BRAVE_API_KEY%22%3A%22%24%7Binput%3Abrave_api_key%7D%22%7D%7D&quality=insiders)
|
||||
|
||||
[](https://insiders.vscode.dev/redirect/mcp/install?name=brave&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22apiKey%22%7D%5D&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22-e%22%2C%22BRAVE_API_KEY%22%2C%22mcp%2Fbrave-search%22%5D%2C%22env%22%3A%7B%22BRAVE_API_KEY%22%3A%22%24%7Binput%3Abrave_api_key%7D%22%7D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=brave&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22apiKey%22%7D%5D&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22-e%22%2C%22BRAVE_API_KEY%22%2C%22mcp%2Fbrave-search%22%5D%2C%22env%22%3A%7B%22BRAVE_API_KEY%22%3A%22%24%7Binput%3Abrave_api_key%7D%22%7D%7D&quality=insiders)
|
||||
|
||||
For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open User Settings (JSON)`.
|
||||
|
||||
Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
|
||||
|
||||
> Note that the `mcp` key is not needed in the `.vscode/mcp.json` file.
|
||||
|
||||
#### Docker
|
||||
|
||||
```json
|
||||
{
|
||||
"mcp": {
|
||||
"inputs": [
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "brave_api_key",
|
||||
"description": "Brave Search API Key",
|
||||
"password": true
|
||||
}
|
||||
],
|
||||
"servers": {
|
||||
"brave-search": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
"BRAVE_API_KEY",
|
||||
"mcp/brave-search"
|
||||
],
|
||||
"env": {
|
||||
"BRAVE_API_KEY": "${input:brave_api_key}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### NPX
|
||||
|
||||
```json
|
||||
{
|
||||
"mcp": {
|
||||
"inputs": [
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "brave_api_key",
|
||||
"description": "Brave Search API Key",
|
||||
"password": true
|
||||
}
|
||||
],
|
||||
"servers": {
|
||||
"brave-search": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-brave-search"],
|
||||
"env": {
|
||||
"BRAVE_API_KEY": "${input:brave_api_key}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
Docker build:
|
||||
|
||||
```bash
|
||||
docker build -t mcp/brave-search:latest -f src/brave-search/Dockerfile .
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
|
||||
|
|
@ -1,376 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import {
|
||||
CallToolRequestSchema,
|
||||
ListToolsRequestSchema,
|
||||
Tool,
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
|
||||
const WEB_SEARCH_TOOL: Tool = {
|
||||
name: "brave_web_search",
|
||||
description:
|
||||
"Performs a web search using the Brave Search API, ideal for general queries, news, articles, and online content. " +
|
||||
"Use this for broad information gathering, recent events, or when you need diverse web sources. " +
|
||||
"Supports pagination, content filtering, and freshness controls. " +
|
||||
"Maximum 20 results per request, with offset for pagination. ",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
query: {
|
||||
type: "string",
|
||||
description: "Search query (max 400 chars, 50 words)"
|
||||
},
|
||||
count: {
|
||||
type: "number",
|
||||
description: "Number of results (1-20, default 10)",
|
||||
default: 10
|
||||
},
|
||||
offset: {
|
||||
type: "number",
|
||||
description: "Pagination offset (max 9, default 0)",
|
||||
default: 0
|
||||
},
|
||||
},
|
||||
required: ["query"],
|
||||
},
|
||||
};
|
||||
|
||||
const LOCAL_SEARCH_TOOL: Tool = {
|
||||
name: "brave_local_search",
|
||||
description:
|
||||
"Searches for local businesses and places using Brave's Local Search API. " +
|
||||
"Best for queries related to physical locations, businesses, restaurants, services, etc. " +
|
||||
"Returns detailed information including:\n" +
|
||||
"- Business names and addresses\n" +
|
||||
"- Ratings and review counts\n" +
|
||||
"- Phone numbers and opening hours\n" +
|
||||
"Use this when the query implies 'near me' or mentions specific locations. " +
|
||||
"Automatically falls back to web search if no local results are found.",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
query: {
|
||||
type: "string",
|
||||
description: "Local search query (e.g. 'pizza near Central Park')"
|
||||
},
|
||||
count: {
|
||||
type: "number",
|
||||
description: "Number of results (1-20, default 5)",
|
||||
default: 5
|
||||
},
|
||||
},
|
||||
required: ["query"]
|
||||
}
|
||||
};
|
||||
|
||||
// Server implementation
|
||||
const server = new Server(
|
||||
{
|
||||
name: "example-servers/brave-search",
|
||||
version: "0.1.0",
|
||||
},
|
||||
{
|
||||
capabilities: {
|
||||
tools: {},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// Check for API key
|
||||
const BRAVE_API_KEY = process.env.BRAVE_API_KEY!;
|
||||
if (!BRAVE_API_KEY) {
|
||||
console.error("Error: BRAVE_API_KEY environment variable is required");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const RATE_LIMIT = {
|
||||
perSecond: 1,
|
||||
perMonth: 15000
|
||||
};
|
||||
|
||||
let requestCount = {
|
||||
second: 0,
|
||||
month: 0,
|
||||
lastReset: Date.now()
|
||||
};
|
||||
|
||||
function checkRateLimit() {
|
||||
const now = Date.now();
|
||||
if (now - requestCount.lastReset > 1000) {
|
||||
requestCount.second = 0;
|
||||
requestCount.lastReset = now;
|
||||
}
|
||||
if (requestCount.second >= RATE_LIMIT.perSecond ||
|
||||
requestCount.month >= RATE_LIMIT.perMonth) {
|
||||
throw new Error('Rate limit exceeded');
|
||||
}
|
||||
requestCount.second++;
|
||||
requestCount.month++;
|
||||
}
|
||||
|
||||
interface BraveWeb {
|
||||
web?: {
|
||||
results?: Array<{
|
||||
title: string;
|
||||
description: string;
|
||||
url: string;
|
||||
language?: string;
|
||||
published?: string;
|
||||
rank?: number;
|
||||
}>;
|
||||
};
|
||||
locations?: {
|
||||
results?: Array<{
|
||||
id: string; // Required by API
|
||||
title?: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
interface BraveLocation {
|
||||
id: string;
|
||||
name: string;
|
||||
address: {
|
||||
streetAddress?: string;
|
||||
addressLocality?: string;
|
||||
addressRegion?: string;
|
||||
postalCode?: string;
|
||||
};
|
||||
coordinates?: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
};
|
||||
phone?: string;
|
||||
rating?: {
|
||||
ratingValue?: number;
|
||||
ratingCount?: number;
|
||||
};
|
||||
openingHours?: string[];
|
||||
priceRange?: string;
|
||||
}
|
||||
|
||||
interface BravePoiResponse {
|
||||
results: BraveLocation[];
|
||||
}
|
||||
|
||||
interface BraveDescription {
|
||||
descriptions: {[id: string]: string};
|
||||
}
|
||||
|
||||
function isBraveWebSearchArgs(args: unknown): args is { query: string; count?: number } {
|
||||
return (
|
||||
typeof args === "object" &&
|
||||
args !== null &&
|
||||
"query" in args &&
|
||||
typeof (args as { query: string }).query === "string"
|
||||
);
|
||||
}
|
||||
|
||||
function isBraveLocalSearchArgs(args: unknown): args is { query: string; count?: number } {
|
||||
return (
|
||||
typeof args === "object" &&
|
||||
args !== null &&
|
||||
"query" in args &&
|
||||
typeof (args as { query: string }).query === "string"
|
||||
);
|
||||
}
|
||||
|
||||
async function performWebSearch(query: string, count: number = 10, offset: number = 0) {
|
||||
checkRateLimit();
|
||||
const url = new URL('https://api.search.brave.com/res/v1/web/search');
|
||||
url.searchParams.set('q', query);
|
||||
url.searchParams.set('count', Math.min(count, 20).toString()); // API limit
|
||||
url.searchParams.set('offset', offset.toString());
|
||||
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Accept-Encoding': 'gzip',
|
||||
'X-Subscription-Token': BRAVE_API_KEY
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Brave API error: ${response.status} ${response.statusText}\n${await response.text()}`);
|
||||
}
|
||||
|
||||
const data = await response.json() as BraveWeb;
|
||||
|
||||
// Extract just web results
|
||||
const results = (data.web?.results || []).map(result => ({
|
||||
title: result.title || '',
|
||||
description: result.description || '',
|
||||
url: result.url || ''
|
||||
}));
|
||||
|
||||
return results.map(r =>
|
||||
`Title: ${r.title}\nDescription: ${r.description}\nURL: ${r.url}`
|
||||
).join('\n\n');
|
||||
}
|
||||
|
||||
async function performLocalSearch(query: string, count: number = 5) {
|
||||
checkRateLimit();
|
||||
// Initial search to get location IDs
|
||||
const webUrl = new URL('https://api.search.brave.com/res/v1/web/search');
|
||||
webUrl.searchParams.set('q', query);
|
||||
webUrl.searchParams.set('search_lang', 'en');
|
||||
webUrl.searchParams.set('result_filter', 'locations');
|
||||
webUrl.searchParams.set('count', Math.min(count, 20).toString());
|
||||
|
||||
const webResponse = await fetch(webUrl, {
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Accept-Encoding': 'gzip',
|
||||
'X-Subscription-Token': BRAVE_API_KEY
|
||||
}
|
||||
});
|
||||
|
||||
if (!webResponse.ok) {
|
||||
throw new Error(`Brave API error: ${webResponse.status} ${webResponse.statusText}\n${await webResponse.text()}`);
|
||||
}
|
||||
|
||||
const webData = await webResponse.json() as BraveWeb;
|
||||
const locationIds = webData.locations?.results?.filter((r): r is {id: string; title?: string} => r.id != null).map(r => r.id) || [];
|
||||
|
||||
if (locationIds.length === 0) {
|
||||
return performWebSearch(query, count); // Fallback to web search
|
||||
}
|
||||
|
||||
// Get POI details and descriptions in parallel
|
||||
const [poisData, descriptionsData] = await Promise.all([
|
||||
getPoisData(locationIds),
|
||||
getDescriptionsData(locationIds)
|
||||
]);
|
||||
|
||||
return formatLocalResults(poisData, descriptionsData);
|
||||
}
|
||||
|
||||
async function getPoisData(ids: string[]): Promise<BravePoiResponse> {
|
||||
checkRateLimit();
|
||||
const url = new URL('https://api.search.brave.com/res/v1/local/pois');
|
||||
ids.filter(Boolean).forEach(id => url.searchParams.append('ids', id));
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Accept-Encoding': 'gzip',
|
||||
'X-Subscription-Token': BRAVE_API_KEY
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Brave API error: ${response.status} ${response.statusText}\n${await response.text()}`);
|
||||
}
|
||||
|
||||
const poisResponse = await response.json() as BravePoiResponse;
|
||||
return poisResponse;
|
||||
}
|
||||
|
||||
async function getDescriptionsData(ids: string[]): Promise<BraveDescription> {
|
||||
checkRateLimit();
|
||||
const url = new URL('https://api.search.brave.com/res/v1/local/descriptions');
|
||||
ids.filter(Boolean).forEach(id => url.searchParams.append('ids', id));
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Accept-Encoding': 'gzip',
|
||||
'X-Subscription-Token': BRAVE_API_KEY
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Brave API error: ${response.status} ${response.statusText}\n${await response.text()}`);
|
||||
}
|
||||
|
||||
const descriptionsData = await response.json() as BraveDescription;
|
||||
return descriptionsData;
|
||||
}
|
||||
|
||||
function formatLocalResults(poisData: BravePoiResponse, descData: BraveDescription): string {
|
||||
return (poisData.results || []).map(poi => {
|
||||
const address = [
|
||||
poi.address?.streetAddress ?? '',
|
||||
poi.address?.addressLocality ?? '',
|
||||
poi.address?.addressRegion ?? '',
|
||||
poi.address?.postalCode ?? ''
|
||||
].filter(part => part !== '').join(', ') || 'N/A';
|
||||
|
||||
return `Name: ${poi.name}
|
||||
Address: ${address}
|
||||
Phone: ${poi.phone || 'N/A'}
|
||||
Rating: ${poi.rating?.ratingValue ?? 'N/A'} (${poi.rating?.ratingCount ?? 0} reviews)
|
||||
Price Range: ${poi.priceRange || 'N/A'}
|
||||
Hours: ${(poi.openingHours || []).join(', ') || 'N/A'}
|
||||
Description: ${descData.descriptions[poi.id] || 'No description available'}
|
||||
`;
|
||||
}).join('\n---\n') || 'No local results found';
|
||||
}
|
||||
|
||||
// Tool handlers
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
||||
tools: [WEB_SEARCH_TOOL, LOCAL_SEARCH_TOOL],
|
||||
}));
|
||||
|
||||
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
try {
|
||||
const { name, arguments: args } = request.params;
|
||||
|
||||
if (!args) {
|
||||
throw new Error("No arguments provided");
|
||||
}
|
||||
|
||||
switch (name) {
|
||||
case "brave_web_search": {
|
||||
if (!isBraveWebSearchArgs(args)) {
|
||||
throw new Error("Invalid arguments for brave_web_search");
|
||||
}
|
||||
const { query, count = 10 } = args;
|
||||
const results = await performWebSearch(query, count);
|
||||
return {
|
||||
content: [{ type: "text", text: results }],
|
||||
isError: false,
|
||||
};
|
||||
}
|
||||
|
||||
case "brave_local_search": {
|
||||
if (!isBraveLocalSearchArgs(args)) {
|
||||
throw new Error("Invalid arguments for brave_local_search");
|
||||
}
|
||||
const { query, count = 5 } = args;
|
||||
const results = await performLocalSearch(query, count);
|
||||
return {
|
||||
content: [{ type: "text", text: results }],
|
||||
isError: false,
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
return {
|
||||
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
|
||||
},
|
||||
],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
async function runServer() {
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
console.error("Brave Search MCP Server running on stdio");
|
||||
}
|
||||
|
||||
runServer().catch((error) => {
|
||||
console.error("Fatal error running server:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"name": "@modelcontextprotocol/server-brave-search",
|
||||
"version": "0.6.2",
|
||||
"description": "MCP server for Brave Search API integration",
|
||||
"license": "MIT",
|
||||
"author": "Anthropic, PBC (https://anthropic.com)",
|
||||
"homepage": "https://modelcontextprotocol.io",
|
||||
"bugs": "https://github.com/modelcontextprotocol/servers/issues",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"mcp-server-brave-search": "dist/index.js"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc && shx chmod +x dist/*.js",
|
||||
"prepare": "npm run build",
|
||||
"watch": "tsc --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22",
|
||||
"shx": "^0.3.4",
|
||||
"typescript": "^5.6.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": "."
|
||||
},
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
FROM node:22.12-alpine AS builder
|
||||
|
||||
COPY src/everart /app
|
||||
COPY tsconfig.json /tsconfig.json
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN --mount=type=cache,target=/root/.npm npm install
|
||||
|
||||
FROM node:22-alpine AS release
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/dist /app/dist
|
||||
COPY --from=builder /app/package.json /app/package.json
|
||||
COPY --from=builder /app/package-lock.json /app/package-lock.json
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
RUN npm ci --ignore-scripts --omit-dev
|
||||
|
||||
ENTRYPOINT ["node", "dist/index.js"]
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
# EverArt MCP Server
|
||||
|
||||
Image generation server for Claude Desktop using EverArt's API.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install
|
||||
export EVERART_API_KEY=your_key_here
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
### Usage with Claude Desktop
|
||||
|
||||
Add to Claude Desktop config:
|
||||
|
||||
#### Docker
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"everart": {
|
||||
"command": "docker",
|
||||
"args": ["run", "-i", "--rm", "-e", "EVERART_API_KEY", "mcp/everart"],
|
||||
"env": {
|
||||
"EVERART_API_KEY": "your_key_here"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### NPX
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"everart": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-everart"],
|
||||
"env": {
|
||||
"EVERART_API_KEY": "your_key_here"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Usage with VS Code
|
||||
|
||||
For quick installation, use the one-click installation buttons below...
|
||||
|
||||
[](https://insiders.vscode.dev/redirect/mcp/install?name=everart&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22everart_api_key%22%2C%22description%22%3A%22EverArt%20API%20Key%22%2C%22password%22%3Atrue%7D%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-everart%22%5D%2C%22env%22%3A%7B%22EVERART_API_KEY%22%3A%22%24%7Binput%3Aeverart_api_key%7D%22%7D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=everart&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22everart_api_key%22%2C%22description%22%3A%22EverArt%20API%20Key%22%2C%22password%22%3Atrue%7D%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-everart%22%5D%2C%22env%22%3A%7B%22EVERART_API_KEY%22%3A%22%24%7Binput%3Aeverart_api_key%7D%22%7D%7D&quality=insiders)
|
||||
|
||||
[](https://insiders.vscode.dev/redirect/mcp/install?name=everart&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22everart_api_key%22%2C%22description%22%3A%22EverArt%20API%20Key%22%2C%22password%22%3Atrue%7D%5D&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22mcp%2Feverart%22%5D%2C%22env%22%3A%7B%22EVERART_API_KEY%22%3A%22%24%7Binput%3Aeverart_api_key%7D%22%7D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=everart&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22everart_api_key%22%2C%22description%22%3A%22EverArt%20API%20Key%22%2C%22password%22%3Atrue%7D%5D&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22mcp%2Feverart%22%5D%2C%22env%22%3A%7B%22EVERART_API_KEY%22%3A%22%24%7Binput%3Aeverart_api_key%7D%22%7D%7D&quality=insiders)
|
||||
|
||||
For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open Settings (JSON)`.
|
||||
|
||||
Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
|
||||
|
||||
> Note that the `mcp` key is needed when using the `mcp.json` file.
|
||||
|
||||
#### Docker
|
||||
|
||||
```json
|
||||
{
|
||||
"mcp": {
|
||||
"inputs": [
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "everart_api_key",
|
||||
"description": "EverArt API Key",
|
||||
"password": true
|
||||
}
|
||||
],
|
||||
"servers": {
|
||||
"everart": {
|
||||
"command": "docker",
|
||||
"args": ["run", "-i", "--rm", "-e", "EVERART_API_KEY", "mcp/everart"],
|
||||
"env": {
|
||||
"EVERART_API_KEY": "${input:everart_api_key}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### NPX
|
||||
|
||||
```json
|
||||
{
|
||||
"mcp": {
|
||||
"inputs": [
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "everart_api_key",
|
||||
"description": "EverArt API Key",
|
||||
"password": true
|
||||
}
|
||||
],
|
||||
"servers": {
|
||||
"everart": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-everart"],
|
||||
"env": {
|
||||
"EVERART_API_KEY": "${input:everart_api_key}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tools
|
||||
|
||||
### generate_image
|
||||
|
||||
Generates images with multiple model options. Opens result in browser and returns URL.
|
||||
|
||||
Parameters:
|
||||
|
||||
```typescript
|
||||
{
|
||||
prompt: string, // Image description
|
||||
model?: string, // Model ID (default: "207910310772879360")
|
||||
image_count?: number // Number of images (default: 1)
|
||||
}
|
||||
```
|
||||
|
||||
Models:
|
||||
|
||||
- 5000: FLUX1.1 (standard)
|
||||
- 9000: FLUX1.1-ultra
|
||||
- 6000: SD3.5
|
||||
- 7000: Recraft-Real
|
||||
- 8000: Recraft-Vector
|
||||
|
||||
All images generated at 1024x1024.
|
||||
|
||||
Sample usage:
|
||||
|
||||
```javascript
|
||||
const result = await client.callTool({
|
||||
name: "generate_image",
|
||||
arguments: {
|
||||
prompt: "A cat sitting elegantly",
|
||||
model: "7000",
|
||||
image_count: 1
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Response format:
|
||||
|
||||
```
|
||||
Image generated successfully!
|
||||
The image has been opened in your default browser.
|
||||
|
||||
Generation details:
|
||||
- Model: 7000
|
||||
- Prompt: "A cat sitting elegantly"
|
||||
- Image URL: https://storage.googleapis.com/...
|
||||
|
||||
You can also click the URL above to view the image again.
|
||||
```
|
||||
|
||||
## Building w/ Docker
|
||||
|
||||
```sh
|
||||
docker build -t mcp/everart -f src/everart/Dockerfile .
|
||||
```
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
import EverArt from "everart";
|
||||
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 fetch from "node-fetch";
|
||||
import open from "open";
|
||||
|
||||
const server = new Server(
|
||||
{
|
||||
name: "example-servers/everart",
|
||||
version: "0.2.0",
|
||||
},
|
||||
{
|
||||
capabilities: {
|
||||
tools: {},
|
||||
resources: {}, // Required for image resources
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!process.env.EVERART_API_KEY) {
|
||||
console.error("EVERART_API_KEY environment variable is not set");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const client = new EverArt.default(process.env.EVERART_API_KEY);
|
||||
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
||||
tools: [
|
||||
{
|
||||
name: "generate_image",
|
||||
description:
|
||||
"Generate images using EverArt Models and returns a clickable link to view the generated image. " +
|
||||
"The tool will return a URL that can be clicked to view the image in a browser. " +
|
||||
"Available models:\n" +
|
||||
"- 5000:FLUX1.1: Standard quality\n" +
|
||||
"- 9000:FLUX1.1-ultra: Ultra high quality\n" +
|
||||
"- 6000:SD3.5: Stable Diffusion 3.5\n" +
|
||||
"- 7000:Recraft-Real: Photorealistic style\n" +
|
||||
"- 8000:Recraft-Vector: Vector art style\n" +
|
||||
"\nThe response will contain a direct link to view the generated image.",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
prompt: {
|
||||
type: "string",
|
||||
description: "Text description of desired image",
|
||||
},
|
||||
model: {
|
||||
type: "string",
|
||||
description:
|
||||
"Model ID (5000:FLUX1.1, 9000:FLUX1.1-ultra, 6000:SD3.5, 7000:Recraft-Real, 8000:Recraft-Vector)",
|
||||
default: "5000",
|
||||
},
|
||||
image_count: {
|
||||
type: "number",
|
||||
description: "Number of images to generate",
|
||||
default: 1,
|
||||
},
|
||||
},
|
||||
required: ["prompt"],
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
||||
return {
|
||||
resources: [
|
||||
{
|
||||
uri: "everart://images",
|
||||
mimeType: "image/png",
|
||||
name: "Generated Images",
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
||||
if (request.params.uri === "everart://images") {
|
||||
return {
|
||||
contents: [
|
||||
{
|
||||
uri: "everart://images",
|
||||
mimeType: "image/png",
|
||||
blob: "", // Empty since this is just for listing
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
throw new Error("Resource not found");
|
||||
});
|
||||
|
||||
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
if (request.params.name === "generate_image") {
|
||||
try {
|
||||
const {
|
||||
prompt,
|
||||
model = "207910310772879360",
|
||||
image_count = 1,
|
||||
} = request.params.arguments as any;
|
||||
|
||||
// Use correct EverArt API method
|
||||
const generation = await client.v1.generations.create(
|
||||
model,
|
||||
prompt,
|
||||
"txt2img",
|
||||
{
|
||||
imageCount: image_count,
|
||||
height: 1024,
|
||||
width: 1024,
|
||||
},
|
||||
);
|
||||
|
||||
// Wait for generation to complete
|
||||
const completedGen = await client.v1.generations.fetchWithPolling(
|
||||
generation[0].id,
|
||||
);
|
||||
|
||||
const imgUrl = completedGen.image_url;
|
||||
if (!imgUrl) throw new Error("No image URL");
|
||||
|
||||
// Automatically open the image URL in the default browser
|
||||
await open(imgUrl);
|
||||
|
||||
// Return a formatted message with the clickable link
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `Image generated successfully!\nThe image has been opened in your default browser.\n\nGeneration details:\n- Model: ${model}\n- Prompt: "${prompt}"\n- Image URL: ${imgUrl}\n\nYou can also click the URL above to view the image again.`,
|
||||
},
|
||||
],
|
||||
};
|
||||
} catch (error: unknown) {
|
||||
console.error("Detailed error:", error);
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : "Unknown error";
|
||||
return {
|
||||
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
throw new Error(`Unknown tool: ${request.params.name}`);
|
||||
});
|
||||
|
||||
async function runServer() {
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
console.error("EverArt MCP Server running on stdio");
|
||||
}
|
||||
|
||||
runServer().catch(console.error);
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
{
|
||||
"name": "@modelcontextprotocol/server-everart",
|
||||
"version": "0.6.2",
|
||||
"description": "MCP server for EverArt API integration",
|
||||
"license": "MIT",
|
||||
"author": "Anthropic, PBC (https://anthropic.com)",
|
||||
"homepage": "https://modelcontextprotocol.io",
|
||||
"bugs": "https://github.com/modelcontextprotocol/servers/issues",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"mcp-server-everart": "dist/index.js"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc && shx chmod +x dist/*.js",
|
||||
"prepare": "npm run build",
|
||||
"watch": "tsc --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "0.5.0",
|
||||
"everart": "^1.0.0",
|
||||
"node-fetch": "^3.3.2",
|
||||
"open": "^9.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22",
|
||||
"shx": "^0.3.4",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": "."
|
||||
},
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
]
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
"start:streamableHttp": "node dist/streamableHttp.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.11.0",
|
||||
"@modelcontextprotocol/sdk": "^1.12.0",
|
||||
"express": "^4.21.1",
|
||||
"zod": "^3.23.8",
|
||||
"zod-to-json-schema": "^3.23.5"
|
||||
|
|
|
|||
|
|
@ -6,36 +6,48 @@ console.error('Starting SSE server...');
|
|||
|
||||
const app = express();
|
||||
|
||||
const { server, cleanup } = createServer();
|
||||
|
||||
let transport: SSEServerTransport;
|
||||
const transports: Map<string, SSEServerTransport> = new Map<string, SSEServerTransport>();
|
||||
|
||||
app.get("/sse", async (req, res) => {
|
||||
console.error("Received connection");
|
||||
transport = new SSEServerTransport("/message", res);
|
||||
await server.connect(transport);
|
||||
let transport: SSEServerTransport;
|
||||
const { server, cleanup } = createServer();
|
||||
|
||||
server.onclose = async () => {
|
||||
await cleanup();
|
||||
await server.close();
|
||||
};
|
||||
if (req?.query?.sessionId) {
|
||||
const sessionId = (req?.query?.sessionId as string);
|
||||
transport = transports.get(sessionId) as SSEServerTransport;
|
||||
console.error("Client Reconnecting? This shouldn't happen; when client has a sessionId, GET /sse should not be called again.", transport.sessionId);
|
||||
} else {
|
||||
// Create and store transport for new session
|
||||
transport = new SSEServerTransport("/message", res);
|
||||
transports.set(transport.sessionId, transport);
|
||||
|
||||
// Connect server to transport
|
||||
await server.connect(transport);
|
||||
console.error("Client Connected: ", transport.sessionId);
|
||||
|
||||
// Handle close of connection
|
||||
server.onclose = async () => {
|
||||
console.error("Client Disconnected: ", transport.sessionId);
|
||||
transports.delete(transport.sessionId);
|
||||
await cleanup();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
app.post("/message", async (req, res) => {
|
||||
console.error("Received message");
|
||||
|
||||
await transport.handlePostMessage(req, res);
|
||||
});
|
||||
|
||||
process.on("SIGINT", async () => {
|
||||
await cleanup();
|
||||
await server.close();
|
||||
process.exit(0);
|
||||
const sessionId = (req?.query?.sessionId as string);
|
||||
const transport = transports.get(sessionId);
|
||||
if (transport) {
|
||||
console.error("Client Message from", sessionId);
|
||||
await transport.handlePostMessage(req, res);
|
||||
} else {
|
||||
console.error(`No transport found for sessionId ${sessionId}`)
|
||||
}
|
||||
});
|
||||
|
||||
const PORT = process.env.PORT || 3001;
|
||||
app.listen(PORT, () => {
|
||||
console.error(`Server is running on port ${PORT}`);
|
||||
});
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue