Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ Official integrations are maintained by companies building production ready MCP
- <img height="12" width="12" src="https://www.comet.com/favicon.ico" alt="Comet Logo" /> **[Comet Opik](https://github.com/comet-ml/opik-mcp)** - Query and analyze your [Opik](https://github.com/comet-ml/opik) logs, traces, prompts and all other telemetry data from your LLMs in natural language.
- <img height="12" width="12" src="https://www.commercelayer.io/favicon.ico" alt="Commerce Layer Logo" /> **[Commerce Layer](https://github.com/commercelayer/mcp-server-metrics)** - Interact with Commerce Layer Metrics API.
- <img height="12" width="12" src="https://platform.composio.dev/favicon.ico" alt="Composio Logo" /> **[Composio](https://docs.composio.dev/docs/mcp-overview#-getting-started)** – Use [Composio](https://composio.dev) to connect 100+ tools. Zero setup. Auth built-in. Made for agents, works for humans.
- <img height="12" width="12" src="https://cdn.prod.website-files.com/6572bd8c27ee5db3eb91f4b3/6572bd8d27ee5db3eb91f55e_favicon-dashflow-webflow-template.svg" alt="OSS Conductor Logo" /> <img height="12" width="12" src="https://orkes.io/icons/icon-48x48.png" alt="Orkes Conductor Logo" />**[Conductor](https://github.com/conductor-oss/conductor-mcp)** - Interact with Conductor (OSS and Orkes) REST APIs.
- <img height="12" width="12" src="https://cdn.prod.website-files.com/6572bd8c27ee5db3eb91f4b3/6572bd8d27ee5db3eb91f55e_favicon-dashflow-webflow-template.svg" alt="OSS Conductor Logo" /> <img height="12" width="12" src="https://cdn.prod.website-files.com/68c3f472828bb14d0564ad4a/68c3f472828bb14d0564b0ab_Orkes%20Logo%20Symbol.svg" alt="Orkes Conductor Logo" />**[Conductor](https://github.com/conductor-oss/conductor-mcp)** - Interact with Conductor (OSS and Orkes) REST APIs.
- <img height="12" width="12" src="https://configcat.com/favicon.ico" alt="ConfigCat Logo" /> **[ConfigCat](https://github.com/configcat/mcp-server)** - Enables AI tools to interact with [ConfigCat](https://configcat.com), a feature flag service for teams. Supports managing ConfigCat feature flags, configs, environments, products and organizations. Helps to integrate ConfigCat SDK, implement feature flags and remove zombie (stale) flags.
- <img height="12" width="12" src="https://www.confluent.io/favicon.ico" alt="Confluent Logo" /> **[Confluent](https://github.com/confluentinc/mcp-confluent)** - Interact with Confluent Kafka and Confluent Cloud REST APIs.
- <img height="12" width="12" src="https://github.com/mattjoyce.png" alt="Construe Logo" /> **[Construe](https://github.com/mattjoyce/mcp-construe)** - FastMCP server for intelligent Obsidian vault context management with frontmatter filtering, automatic chunking, and secure bidirectional knowledge operations.
Expand Down Expand Up @@ -274,7 +274,7 @@ Official integrations are maintained by companies building production ready MCP
- <img height="12" width="12" src="https://improvedigital.com/favicon.ico" alt="Improve Digital Icon" /> **[Improve Digital Publisher MCP](https://github.com/azerion/improvedigital-publisher-mcp-server)** - An MCP server that enables publishers to integrate [Improve Digital’s](https://improvedigital.com/) inventory management system with their AI tools or agents.
- <img height="12" width="12" src="https://www.getinboxzero.com/icon.png" alt="Inbox Zero Logo" /> **[Inbox Zero](https://github.com/elie222/inbox-zero/tree/main/apps/mcp-server)** - AI personal assistant for email [Inbox Zero](https://www.getinboxzero.com)
- <img height="12" width="12" src="https://www.inflectra.com/Favicon.ico" alt="Inflectra Logo" /> **[Inflectra Spira](https://github.com/Inflectra/mcp-server-spira)** - Connect to your instance of the SpiraTest, SpiraTeam or SpiraPlan application lifecycle management platform by [Inflectra](https://www.inflectra.com)
- <img height="12" width="12" src="https://cdn-web.infobip.com/uploads/2025/05/infobip-symbol-orange.png" alt="Infobip Logo" /> **[Infobip](https://github.com/Inflectra/mcp-server-spira)** - MCP server for integrating [Infobip](https://www.infobip.com/) global cloud communication platform. It equips AI agents with communication superpowers, allowing them to send and receive SMS and RCS messages, interact with WhatsApp and Viber, automate communication workflows, and manage customer data, all in a production-ready environment.
- <img height="12" width="12" src="https://cdn-web.infobip.com/uploads/2025/05/infobip-symbol-orange.png" alt="Infobip Logo" /> **[Infobip](https://github.com/infobip/mcp)** - MCP server for integrating [Infobip](https://www.infobip.com/) global cloud communication platform. It equips AI agents with communication superpowers, allowing them to send and receive SMS and RCS messages, interact with WhatsApp and Viber, automate communication workflows, and manage customer data, all in a production-ready environment.
- <img height="12" width="12" src="https://inkeep.com/favicon.ico" alt="Inkeep Logo" /> **[Inkeep](https://github.com/inkeep/mcp-server-python)** - RAG Search over your content powered by [Inkeep](https://inkeep.com)
- <img height="12" width="12" src="https://integration.app/favicon.ico" alt="Integration App Icon" /> **[Integration App](https://github.com/integration-app/mcp-server)** - Interact with any other SaaS applications on behalf of your customers.
- <img height="12" width="12" src="https://www.ip2location.io/favicon.ico" alt="IP2Location.io Icon" /> **[IP2Location.io](https://github.com/ip2location/mcp-ip2location-io)** - Interact with IP2Location.io API to retrieve the geolocation information for an IP address.
Expand Down Expand Up @@ -382,7 +382,6 @@ Official integrations are maintained by companies building production ready MCP
- **[OMOP MCP](https://github.com/OHNLP/omop_mcp)** - Map clinical terminology to OMOP concepts using LLMs for healthcare data standardization.
- <img height="12" width="12" src="https://static.onlyoffice.com/images/favicon.ico" alt="ONLYOFFICE DocSpace" /> **[ONLYOFFICE DocSpace](https://github.com/ONLYOFFICE/docspace-mcp)** - Interact with [ONLYOFFICE DocSpace](https://www.onlyoffice.com/docspace.aspx) API to create rooms, manage files and folders.
- <img height="12" width="12" src="https://op.gg/favicon.ico" alt="OP.GG Logo" /> **[OP.GG](https://github.com/opgginc/opgg-mcp)** - Access real-time gaming data across popular titles like League of Legends, TFT, and Valorant, offering champion analytics, esports schedules, meta compositions, and character statistics.
- <img height="12" width="12" src="https://www.openfort.io/img/icon.svg" alt="Openfort" /> **[Openfort](https://github.com/openfort-xyz/mcp)** - Connect your AI to Openfort's smart wallet, auth, and project infrastructure.
- <img height="12" width="12" src="https://open-metadata.org/favicon.ico" alt="OpenMetadata" /> **[OpenMetadata](https://open-metadata.org/mcp)** - The first Enterprise-grade MCP server for metadata
- <img height="12" width="12" src="https://opensearch.org/wp-content/uploads/2025/01/opensearch_mark_default.svg" alt="OpenSearch Logo" /> **[OpenSearch](https://github.com/opensearch-project/opensearch-mcp-server-py)** - MCP server that enables AI agents to perform search and analytics use cases on data stored in [OpenSearch](https://opensearch.org/).
- <img height="12" width="12" src="https://app.opslevel.com/favicon.ico" alt="OpsLevel" /> **[OpsLevel](https://github.com/opslevel/opslevel-mcp)** - Official MCP Server for [OpsLevel](https://www.opslevel.com).
Expand Down Expand Up @@ -425,7 +424,7 @@ Official integrations are maintained by companies building production ready MCP
- <img height="12" width="12" src="https://powerdrill.ai/_next/static/media/powerdrill.0fa27d00.webp" alt="Powerdrill Logo" /> **[Powerdrill](https://github.com/powerdrillai/powerdrill-mcp)** - An MCP server that provides tools to interact with Powerdrill datasets, enabling smart AI data analysis and insights.
- <img height="12" width="12" src="https://www.pre.dev/predevlogowhitebackground.png" alt="pre.dev Logo" /> **[pre.dev Architect](https://docs.pre.dev/mcp-server)** - 10x your coding agent by keeping it on track with pre.dev.
- <img height="12" width="12" src="https://devdocs.prestashop-project.org/images/favicon.png" alt="PrestaShop Logo" /> **[PrestaShop.com](https://docs.mcp.prestashop.com/)** - Manage your PrestaShop store with AI Assistant by using the official PrestaShop MCP server.
- <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.prisma.io/images/favicon-32x32.png" alt="Prisma Logo" /> **[Prisma](https://www.prisma.io/docs/postgres/integrations/mcp-server)** - Create and manage Prisma Postgres databases
- <img height="12" width="12" src="https://probe.dev/favicon.ico" alt="Probe.dev Logo" /> **[Probe.dev](https://docs.probe.dev/guides/mcp-integration)** - Comprehensive media analysis and validation powered by [Probe.dev](https://probe.dev). Hosted MCP server with FFprobe, MediaInfo, and Probe Report analysis capabilities.
- <img height="12" width="12" src="https://framerusercontent.com/images/FGzpihs4MxmSJhyGZ6n7f2Xj0.png" alt="Prode.ai Logo" /> **[ProdE](https://github.com/CuriousBox-AI/ProdE-mcp)** - Your 24/7 production engineer that preserves context across multiple codebases.
- <img height="12" width="12" src="https://programintegrity.org/wp-content/uploads/2024/07/PIA-Favicon.svg" alt="Program Integrity Alliance (PIA) Logo" /> **[Program Integrity Alliance (PIA)](https://github.com/Program-Integrity-Alliance/pia-mcp-local)** - Local and Hosted MCP servers providing AI-friendly access to U.S. Government Open Datasets. Also available on [Docker MCP Catalog](https://hub.docker.com/mcp/explore?search=PIA). See [our website](https://programintegrity.org) for more details.
Expand Down Expand Up @@ -648,7 +647,7 @@ A growing set of community-developed and maintained servers demonstrates various
- **[BigQuery](https://github.com/ergut/mcp-bigquery-server)** (by ergut) - Server implementation for Google BigQuery integration that enables direct BigQuery database access and querying capabilities
- **[Bilibili](https://github.com/wangshunnn/bilibili-mcp-server)** - This MCP server provides tools to fetch Bilibili user profiles, video metadata, search videos, and more.
- **[Binance](https://github.com/ethancod1ng/binance-mcp-server)** - Cryptocurrency trading and market data access through Binance API integration.
- **[Binance](https://github.com/AnalyticAce/BinanceMCPServer)** (by dosseh shalom) - Unofficial tools and server implementation for Binance's Model Context Protocol (MCP). Designed to support developers building crypto trading AI Agents.
- **[Binance](https://github.com/AnalyticAce/binance-mcp-server)** (by dosseh shalom) - Unofficial tools and server implementation for Binance's Model Context Protocol (MCP). Designed to support developers building crypto trading AI Agents.
- **[Bing Web Search API](https://github.com/leehanchung/bing-search-mcp)** (by hanchunglee) - Server implementation for Microsoft Bing Web Search API.
- **[BioMCP](https://github.com/genomoncology/biomcp)** (by imaurer) - Biomedical research assistant server providing access to PubMed, ClinicalTrials.gov, and MyVariant.info.
- **[bioRxiv](https://github.com/JackKuo666/bioRxiv-MCP-Server)** - 🔍 Enable AI assistants to search and access bioRxiv papers through a simple MCP interface.
Expand Down Expand Up @@ -1654,4 +1653,3 @@ If you find MCP servers useful, please consider starring the repository and cont
---

Managed by Anthropic, but built together with the community. The Model Context Protocol is open source and we encourage everyone to contribute their own servers and improvements!

158 changes: 158 additions & 0 deletions src/filesystem/__tests__/structured-content.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import * as fs from 'fs/promises';
import * as path from 'path';
import * as os from 'os';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { spawn } from 'child_process';

/**
* Integration tests to verify that tool handlers return structuredContent
* that matches the declared outputSchema.
*
* These tests address issues #3110, #3106, #3093 where tools were returning
* structuredContent: { content: [contentBlock] } (array) instead of
* structuredContent: { content: string } as declared in outputSchema.
*/
describe('structuredContent schema compliance', () => {
let client: Client;
let transport: StdioClientTransport;
let testDir: string;

beforeEach(async () => {
// Create a temp directory for testing
testDir = await fs.mkdtemp(path.join(os.tmpdir(), 'mcp-fs-test-'));

// Create test files
await fs.writeFile(path.join(testDir, 'test.txt'), 'test content');
await fs.mkdir(path.join(testDir, 'subdir'));
await fs.writeFile(path.join(testDir, 'subdir', 'nested.txt'), 'nested content');

// Start the MCP server
const serverPath = path.resolve(__dirname, '../dist/index.js');
transport = new StdioClientTransport({
command: 'node',
args: [serverPath, testDir],
});

client = new Client({
name: 'test-client',
version: '1.0.0',
}, {
capabilities: {}
});

await client.connect(transport);
});

afterEach(async () => {
await client?.close();
await fs.rm(testDir, { recursive: true, force: true });
});

describe('directory_tree', () => {
it('should return structuredContent.content as a string, not an array', async () => {
const result = await client.callTool({
name: 'directory_tree',
arguments: { path: testDir }
});

// The result should have structuredContent
expect(result.structuredContent).toBeDefined();

// structuredContent.content should be a string (matching outputSchema: { content: z.string() })
const structuredContent = result.structuredContent as { content: unknown };
expect(typeof structuredContent.content).toBe('string');

// It should NOT be an array
expect(Array.isArray(structuredContent.content)).toBe(false);

// The content should be valid JSON representing the tree
const treeData = JSON.parse(structuredContent.content as string);
expect(Array.isArray(treeData)).toBe(true);
});
});

describe('list_directory_with_sizes', () => {
it('should return structuredContent.content as a string, not an array', async () => {
const result = await client.callTool({
name: 'list_directory_with_sizes',
arguments: { path: testDir }
});

// The result should have structuredContent
expect(result.structuredContent).toBeDefined();

// structuredContent.content should be a string (matching outputSchema: { content: z.string() })
const structuredContent = result.structuredContent as { content: unknown };
expect(typeof structuredContent.content).toBe('string');

// It should NOT be an array
expect(Array.isArray(structuredContent.content)).toBe(false);

// The content should contain directory listing info
expect(structuredContent.content).toContain('[FILE]');
});
});

describe('move_file', () => {
it('should return structuredContent.content as a string, not an array', async () => {
const sourcePath = path.join(testDir, 'test.txt');
const destPath = path.join(testDir, 'moved.txt');

const result = await client.callTool({
name: 'move_file',
arguments: {
source: sourcePath,
destination: destPath
}
});

// The result should have structuredContent
expect(result.structuredContent).toBeDefined();

// structuredContent.content should be a string (matching outputSchema: { content: z.string() })
const structuredContent = result.structuredContent as { content: unknown };
expect(typeof structuredContent.content).toBe('string');

// It should NOT be an array
expect(Array.isArray(structuredContent.content)).toBe(false);

// The content should contain success message
expect(structuredContent.content).toContain('Successfully moved');
});
});

describe('list_directory (control - already working)', () => {
it('should return structuredContent.content as a string', async () => {
const result = await client.callTool({
name: 'list_directory',
arguments: { path: testDir }
});

expect(result.structuredContent).toBeDefined();

const structuredContent = result.structuredContent as { content: unknown };
expect(typeof structuredContent.content).toBe('string');
expect(Array.isArray(structuredContent.content)).toBe(false);
});
});

describe('search_files (control - already working)', () => {
it('should return structuredContent.content as a string', async () => {
const result = await client.callTool({
name: 'search_files',
arguments: {
path: testDir,
pattern: '*.txt'
}
});

expect(result.structuredContent).toBeDefined();

const structuredContent = result.structuredContent as { content: unknown };
expect(typeof structuredContent.content).toBe('string');
expect(Array.isArray(structuredContent.content)).toBe(false);
});
});
});
6 changes: 3 additions & 3 deletions src/filesystem/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ server.registerTool(
const contentBlock = { type: "text" as const, text };
return {
content: [contentBlock],
structuredContent: { content: [contentBlock] }
structuredContent: { content: text }
};
}
);
Expand Down Expand Up @@ -570,7 +570,7 @@ server.registerTool(
const contentBlock = { type: "text" as const, text };
return {
content: [contentBlock],
structuredContent: { content: [contentBlock] }
structuredContent: { content: text }
};
}
);
Expand Down Expand Up @@ -599,7 +599,7 @@ server.registerTool(
const contentBlock = { type: "text" as const, text };
return {
content: [contentBlock],
structuredContent: { content: [contentBlock] }
structuredContent: { content: text }
};
}
);
Expand Down