Archive unmaintained servers

Removed the following servers from main branch:
- aws-kb-retrieval-server
- brave-search
- everart
- gdrive
- git
- github
- gitlab
- google-maps
- postgres
- puppeteer
- redis
- sentry
- slack
- sqlite

These servers remain maintained:
- sequentialthinking
- time
- memory
- fetch
- filesystem
- everything

Full history preserved in archive-servers branch

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
David Soria Parra 2025-05-28 14:03:44 +01:00
commit d53d6cc75c
No known key found for this signature in database
95 changed files with 0 additions and 12352 deletions

View file

@ -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"]

View file

@ -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...
[![Install with NPX in VS Code](https://img.shields.io/badge/VS_Code-NPM-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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) [![Install with NPX in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-NPM-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install with Docker in VS Code](https://img.shields.io/badge/VS_Code-Docker-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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) [![Install with Docker in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Docker-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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.

View file

@ -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);
});

View file

@ -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"
}
}

View file

@ -1,17 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": ".",
"composite": true,
"incremental": true,
"tsBuildInfoFile": "./dist/.tsbuildinfo"
},
"include": [
"./**/*.ts"
],
"exclude": [
"node_modules",
"dist"
]
}

View file

@ -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"]

View file

@ -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...
[![Install with NPX in VS Code](https://img.shields.io/badge/VS_Code-NPM-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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) [![Install with NPX in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-NPM-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install with Docker in VS Code](https://img.shields.io/badge/VS_Code-Docker-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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) [![Install with Docker in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Docker-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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.

View file

@ -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);
});

View file

@ -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"
}
}

View file

@ -1,10 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "."
},
"include": [
"./**/*.ts"
]
}

View file

@ -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"]

View file

@ -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...
[![Install with NPX in VS Code](https://img.shields.io/badge/VS_Code-NPM-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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) [![Install with NPX in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-NPM-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install with Docker in VS Code](https://img.shields.io/badge/VS_Code-Docker-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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) [![Install with Docker in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Docker-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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 .
```

View file

@ -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);

View file

@ -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"
}
}

View file

@ -1,10 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "."
},
"include": [
"./**/*.ts"
]
}

View file

@ -1,29 +0,0 @@
FROM node:22.12-alpine AS builder
COPY src/gdrive /app
COPY tsconfig.json /tsconfig.json
WORKDIR /app
RUN --mount=type=cache,target=/root/.npm npm install
RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev
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
COPY src/gdrive/replace_open.sh /replace_open.sh
ENV NODE_ENV=production
RUN npm ci --ignore-scripts --omit-dev
RUN sh /replace_open.sh
RUN rm /replace_open.sh
ENTRYPOINT ["node", "dist/index.js"]

View file

@ -1,157 +0,0 @@
# Google Drive server
This MCP server integrates with Google Drive to allow listing, reading, and searching over files.
## Components
### Tools
- **search**
- Search for files in Google Drive
- Input: `query` (string): Search query
- Returns file names and MIME types of matching files
### Resources
The server provides access to Google Drive files:
- **Files** (`gdrive:///<file_id>`)
- Supports all file types
- Google Workspace files are automatically exported:
- Docs → Markdown
- Sheets → CSV
- Presentations → Plain text
- Drawings → PNG
- Other files are provided in their native format
## Getting started
1. [Create a new Google Cloud project](https://console.cloud.google.com/projectcreate)
2. [Enable the Google Drive API](https://console.cloud.google.com/workspace-api/products)
3. [Configure an OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent) ("internal" is fine for testing)
4. Add OAuth scope `https://www.googleapis.com/auth/drive.readonly`
5. [Create an OAuth Client ID](https://console.cloud.google.com/apis/credentials/oauthclient) for application type "Desktop App"
6. Download the JSON file of your client's OAuth keys
7. Rename the key file to `gcp-oauth.keys.json` and place into the root of this repo (i.e. `servers/gcp-oauth.keys.json`)
Make sure to build the server with either `npm run build` or `npm run watch`.
### Authentication
To authenticate and save credentials:
1. Run the server with the `auth` argument: `node ./dist auth`
2. This will open an authentication flow in your system browser
3. Complete the authentication process
4. Credentials will be saved in the root of this repo (i.e. `servers/.gdrive-server-credentials.json`)
### Usage with Desktop App
To integrate this server with the desktop app, add the following to your app's server configuration:
#### Docker
Authentication:
Assuming you have completed setting up the OAuth application on Google Cloud, you can now auth the server with the following command, replacing `/path/to/gcp-oauth.keys.json` with the path to your OAuth keys file:
```bash
docker run -i --rm --mount type=bind,source=/path/to/gcp-oauth.keys.json,target=/gcp-oauth.keys.json -v mcp-gdrive:/gdrive-server -e GDRIVE_OAUTH_PATH=/gcp-oauth.keys.json -e "GDRIVE_CREDENTIALS_PATH=/gdrive-server/credentials.json" -p 3000:3000 mcp/gdrive auth
```
The command will print the URL to open in your browser. Open this URL in your browser and complete the authentication process. The credentials will be saved in the `mcp-gdrive` volume.
Once authenticated, you can use the server in your app's server configuration:
```json
{
"mcpServers": {
"gdrive": {
"command": "docker",
"args": ["run", "-i", "--rm", "-v", "mcp-gdrive:/gdrive-server", "-e", "GDRIVE_CREDENTIALS_PATH=/gdrive-server/credentials.json", "mcp/gdrive"]
}
}
}
```
#### NPX
```json
{
"mcpServers": {
"gdrive": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-gdrive"
],
"env": {
"GDRIVE_CREDENTIALS_PATH": "/path/to/.gdrive-server-credentials.json"
}
}
}
}
```
### Usage with VS Code
For quick installation, use one of the one-click install buttons below..
[![Install with NPX in VS Code](https://img.shields.io/badge/VS_Code-NPM-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=gdrive&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22credentials_path%22%2C%22description%22%3A%22Path%20to%20.gdrive-server-credentials.json%20file%22%7D%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-gdrive%22%5D%2C%22env%22%3A%7B%22GDRIVE_CREDENTIALS_PATH%22%3A%22%24%7Binput%3Acredentials_path%7D%22%7D%7D) [![Install with NPX in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-NPM-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=gdrive&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22credentials_path%22%2C%22description%22%3A%22Path%20to%20.gdrive-server-credentials.json%20file%22%7D%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-gdrive%22%5D%2C%22env%22%3A%7B%22GDRIVE_CREDENTIALS_PATH%22%3A%22%24%7Binput%3Acredentials_path%7D%22%7D%7D&quality=insiders)
[![Install with Docker in VS Code](https://img.shields.io/badge/VS_Code-Docker-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=gdrive&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22-v%22%2C%22mcp-gdrive%3A%2Fgdrive-server%22%2C%22-e%22%2C%22GDRIVE_CREDENTIALS_PATH%3D%2Fgdrive-server%2Fcredentials.json%22%2C%22mcp%2Fgdrive%22%5D%7D) [![Install with Docker in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Docker-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=gdrive&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22-v%22%2C%22mcp-gdrive%3A%2Fgdrive-server%22%2C%22-e%22%2C%22GDRIVE_CREDENTIALS_PATH%3D%2Fgdrive-server%2Fcredentials.json%22%2C%22mcp%2Fgdrive%22%5D%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.
#### NPX
```json
{
"mcp": {
"servers": {
"gdrive": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-gdrive"
],
"env": {
"GDRIVE_CREDENTIALS_PATH": "/path/to/.gdrive-server-credentials.json"
}
}
}
}
}
```
#### Docker
```json
{
"mcp": {
"servers": {
"gdrive": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-v",
"mcp-gdrive:/gdrive-server",
"-e",
"GDRIVE_CREDENTIALS_PATH=/gdrive-server/credentials.json",
"mcp/gdrive"
]
}
}
}
}
```
## 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.

View file

@ -1,219 +0,0 @@
#!/usr/bin/env node
import { authenticate } from "@google-cloud/local-auth";
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListResourcesRequestSchema,
ListToolsRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import fs from "fs";
import { google } from "googleapis";
import path from "path";
import { fileURLToPath } from 'url';
const drive = google.drive("v3");
const server = new Server(
{
name: "example-servers/gdrive",
version: "0.1.0",
},
{
capabilities: {
resources: {},
tools: {},
},
},
);
server.setRequestHandler(ListResourcesRequestSchema, async (request) => {
const pageSize = 10;
const params: any = {
pageSize,
fields: "nextPageToken, files(id, name, mimeType)",
};
if (request.params?.cursor) {
params.pageToken = request.params.cursor;
}
const res = await drive.files.list(params);
const files = res.data.files!;
return {
resources: files.map((file) => ({
uri: `gdrive:///${file.id}`,
mimeType: file.mimeType,
name: file.name,
})),
nextCursor: res.data.nextPageToken,
};
});
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const fileId = request.params.uri.replace("gdrive:///", "");
// First get file metadata to check mime type
const file = await drive.files.get({
fileId,
fields: "mimeType",
});
// For Google Docs/Sheets/etc we need to export
if (file.data.mimeType?.startsWith("application/vnd.google-apps")) {
let exportMimeType: string;
switch (file.data.mimeType) {
case "application/vnd.google-apps.document":
exportMimeType = "text/markdown";
break;
case "application/vnd.google-apps.spreadsheet":
exportMimeType = "text/csv";
break;
case "application/vnd.google-apps.presentation":
exportMimeType = "text/plain";
break;
case "application/vnd.google-apps.drawing":
exportMimeType = "image/png";
break;
default:
exportMimeType = "text/plain";
}
const res = await drive.files.export(
{ fileId, mimeType: exportMimeType },
{ responseType: "text" },
);
return {
contents: [
{
uri: request.params.uri,
mimeType: exportMimeType,
text: res.data,
},
],
};
}
// For regular files download content
const res = await drive.files.get(
{ fileId, alt: "media" },
{ responseType: "arraybuffer" },
);
const mimeType = file.data.mimeType || "application/octet-stream";
if (mimeType.startsWith("text/") || mimeType === "application/json") {
return {
contents: [
{
uri: request.params.uri,
mimeType: mimeType,
text: Buffer.from(res.data as ArrayBuffer).toString("utf-8"),
},
],
};
} else {
return {
contents: [
{
uri: request.params.uri,
mimeType: mimeType,
blob: Buffer.from(res.data as ArrayBuffer).toString("base64"),
},
],
};
}
});
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "search",
description: "Search for files in Google Drive",
inputSchema: {
type: "object",
properties: {
query: {
type: "string",
description: "Search query",
},
},
required: ["query"],
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "search") {
const userQuery = request.params.arguments?.query as string;
const escapedQuery = userQuery.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
const formattedQuery = `fullText contains '${escapedQuery}'`;
const res = await drive.files.list({
q: formattedQuery,
pageSize: 10,
fields: "files(id, name, mimeType, modifiedTime, size)",
});
const fileList = res.data.files
?.map((file: any) => `${file.name} (${file.mimeType})`)
.join("\n");
return {
content: [
{
type: "text",
text: `Found ${res.data.files?.length ?? 0} files:\n${fileList}`,
},
],
isError: false,
};
}
throw new Error("Tool not found");
});
const credentialsPath = process.env.GDRIVE_CREDENTIALS_PATH || path.join(
path.dirname(fileURLToPath(import.meta.url)),
"../../../.gdrive-server-credentials.json",
);
async function authenticateAndSaveCredentials() {
console.log("Launching auth flow…");
const auth = await authenticate({
keyfilePath: process.env.GDRIVE_OAUTH_PATH || path.join(
path.dirname(fileURLToPath(import.meta.url)),
"../../../gcp-oauth.keys.json",
),
scopes: ["https://www.googleapis.com/auth/drive.readonly"],
});
fs.writeFileSync(credentialsPath, JSON.stringify(auth.credentials));
console.log("Credentials saved. You can now run the server.");
}
async function loadCredentialsAndRunServer() {
if (!fs.existsSync(credentialsPath)) {
console.error(
"Credentials not found. Please run with 'auth' argument first.",
);
process.exit(1);
}
const credentials = JSON.parse(fs.readFileSync(credentialsPath, "utf-8"));
const auth = new google.auth.OAuth2();
auth.setCredentials(credentials);
google.options({ auth });
console.error("Credentials loaded. Starting server.");
const transport = new StdioServerTransport();
await server.connect(transport);
}
if (process.argv[2] === "auth") {
authenticateAndSaveCredentials().catch(console.error);
} else {
loadCredentialsAndRunServer().catch(console.error);
}

View file

@ -1,31 +0,0 @@
{
"name": "@modelcontextprotocol/server-gdrive",
"version": "0.6.2",
"description": "MCP server for interacting with Google Drive",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
"homepage": "https://modelcontextprotocol.io",
"bugs": "https://github.com/modelcontextprotocol/servers/issues",
"type": "module",
"bin": {
"mcp-server-gdrive": "dist/index.js"
},
"files": [
"dist"
],
"scripts": {
"build": "tsc && shx chmod +x dist/*.js",
"prepare": "npm run build",
"watch": "tsc --watch"
},
"dependencies": {
"@google-cloud/local-auth": "^3.0.1",
"@modelcontextprotocol/sdk": "1.0.1",
"googleapis": "^144.0.0"
},
"devDependencies": {
"@types/node": "^22",
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
}

View file

@ -1,5 +0,0 @@
#! /bin/bash
# Basic script to replace opn(authorizeUrl, { wait: false }).then(cp => cp.unref()); with process.stdout.write(`Open this URL in your browser: ${authorizeUrl}`);
sed -i 's/opn(authorizeUrl, { wait: false }).then(cp => cp.unref());/process.stderr.write(`Open this URL in your browser: ${authorizeUrl}\n`);/' node_modules/@google-cloud/local-auth/build/src/index.js

Some files were not shown because too many files have changed in this diff Show more