Community Contributions

Module
Community Contributions
Progress
100%

Community and Contributions

Overview

This lesson focuses on how to engage with the MCP community, contribute to the MCP ecosystem, and follow best practices for collaborative development.

Understanding how to participate in open-source MCP projects is essential for those looking to shape the future of this technology.

Learning Objectives

By the end of this lesson, you will be able to:

  • Understand the structure of the MCP community and ecosystem
  • Participate effectively in MCP community forums and discussions
  • Contribute to MCP open-source repositories
  • Create and share custom MCP tools and servers
  • Follow best practices for MCP development and collaboration
  • Discover community resources and frameworks for MCP development
  • The MCP Community Ecosystem

    The MCP ecosystem consists of various components and participants that work together to advance the protocol.

    Key Community Components

    1. Core Protocol Maintainers: The official Model Context Protocol GitHub organization maintains the core MCP specifications and reference implementations

    2. Tool Developers: Individuals and teams that create MCP tools and servers

    3. Integration Providers: Companies that integrate MCP into their products and services

    4. End Users: Developers and organizations that use MCP in their applications

    5. Contributors: Community members who contribute code, documentation, or other resources

    Community Resources

    Official Channels
  • MCP GitHub Organization
  • MCP Documentation
  • MCP Specification
  • GitHub Discussions
  • MCP Examples & Servers Repository
  • Community-Driven Resources
  • MCP Clients - List of clients that support MCP integrations
  • Community MCP Servers - Growing list of community-developed MCP servers
  • Awesome MCP Servers - Curated list of MCP servers
  • PulseMCP - Community hub & newsletter for discovering MCP resources
  • Discord Server - Connect with MCP developers
  • Language-specific SDK implementations
  • Blog posts and tutorials
  • Contributing to MCP

    Types of Contributions

    The MCP ecosystem welcomes various types of contributions:

    1. Code Contributions:

    - Core protocol enhancements

    - Bug fixes

    - Tool and server implementations

    - Client/server libraries in different languages

    2. Documentation:

    - Improving existing documentation

    - Creating tutorials and guides

    - Translating documentation

    - Creating examples and sample applications

    3. Community Support:

    - Answering questions on forums and discussions

    - Testing and reporting issues

    - Organizing community events

    - Mentoring new contributors

    Contribution Process: Core Protocol

    To contribute to the core MCP protocol or official implementations, follow these principles from the official contributing guidelines:

    1. Simplicity and Minimalism: The MCP specification maintains a high bar for adding new concepts. It's easier to add things to a specification than to remove them.

    2. Concrete Approach: Specification changes should be based on specific implementation challenges, not speculative ideas.

    3. Stages of a Proposal:

    - Define: Explore the problem space, validate that other MCP users face a similar issue

    - Prototype: Build an example solution and demonstrate its practical application

    - Write: Based on the prototype, write a specification proposal

    Development Environment Setup

    
    # Fork the repository
    
    git clone https://github.com/YOUR-USERNAME/modelcontextprotocol.git
    
    cd modelcontextprotocol
    
    
    
    # Install dependencies
    
    npm install
    
    
    
    # For schema changes, validate and generate schema.json:
    
    npm run check:schema:ts
    
    npm run generate:schema
    
    
    
    # For documentation changes
    
    npm run check:docs
    
    npm run format
    
    
    
    # Preview documentation locally (optional):
    
    npm run serve:docs
    
    

    Example: Contributing a Bug Fix

    
    // Original code with bug in the typescript-sdk
    
    export function validateResource(resource: unknown): resource is MCPResource {
    
      if (!resource || typeof resource !== 'object') {
    
        return false;
    
      }
    
      
    
      // Bug: Missing property validation
    
      // Current implementation:
    
      const hasName = 'name' in resource;
    
      const hasSchema = 'schema' in resource;
    
      
    
      return hasName && hasSchema;
    
    }
    
    
    
    // Fixed implementation in a contribution
    
    export function validateResource(resource: unknown): resource is MCPResource {
    
      if (!resource || typeof resource !== 'object') {
    
        return false;
    
      }
    
      
    
      // Improved validation
    
      const hasName = 'name' in resource && typeof (resource as MCPResource).name === 'string';
    
      const hasSchema = 'schema' in resource && typeof (resource as MCPResource).schema === 'object';
    
      const hasDescription = !('description' in resource) || typeof (resource as MCPResource).description === 'string';
    
      
    
      return hasName && hasSchema && hasDescription;
    
    }
    
    

    Example: Contributing a New Tool to the Standard Library

    
    # Example contribution: A CSV data processing tool for the MCP standard library
    
    
    
    from mcp_tools import Tool, ToolRequest, ToolResponse, ToolExecutionException
    
    import pandas as pd
    
    import io
    
    import json
    
    from typing import Dict, Any, List, Optional
    
    
    
    class CsvProcessingTool(Tool):
    
        """
    
        Tool for processing and analyzing CSV data.
    
        
    
        This tool allows models to extract information from CSV files,
    
        run basic analysis, and convert data between formats.
    
        """
    
        
    
        def get_name(self):
    
            return "csvProcessor"
    
            
    
        def get_description(self):
    
            return "Processes and analyzes CSV data"
    
        
    
        def get_schema(self):
    
            return {
    
                "type": "object",
    
                "properties": {
    
                    "csvData": {
    
                        "type": "string", 
    
                        "description": "CSV data as a string"
    
                    },
    
                    "csvUrl": {
    
                        "type": "string",
    
                        "description": "URL to a CSV file (alternative to csvData)"
    
                    },
    
                    "operation": {
    
                        "type": "string",
    
                        "enum": ["summary", "filter", "transform", "convert"],
    
                        "description": "Operation to perform on the CSV data"
    
                    },
    
                    "filterColumn": {
    
                        "type": "string",
    
                        "description": "Column to filter by (for filter operation)"
    
                    },
    
                    "filterValue": {
    
                        "type": "string",
    
                        "description": "Value to filter for (for filter operation)"
    
                    },
    
                    "outputFormat": {
    
                        "type": "string",
    
                        "enum": ["json", "csv", "markdown"],
    
                        "default": "json",
    
                        "description": "Output format for the processed data"
    
                    }
    
                },
    
                "oneOf": [
    
                    {"required": ["csvData", "operation"]},
    
                    {"required": ["csvUrl", "operation"]}
    
                ]
    
            }
    
        
    
        async def execute_async(self, request: ToolRequest) -> ToolResponse:
    
            try:
    
                # Extract parameters
    
                operation = request.parameters.get("operation")
    
                output_format = request.parameters.get("outputFormat", "json")
    
                
    
                # Get CSV data from either direct data or URL
    
                df = await self._get_dataframe(request)
    
                
    
                # Process based on requested operation
    
                result = {}
    
                
    
                if operation == "summary":
    
                    result = self._generate_summary(df)
    
                elif operation == "filter":
    
                    column = request.parameters.get("filterColumn")
    
                    value = request.parameters.get("filterValue")
    
                    if not column:
    
                        raise ToolExecutionException("filterColumn is required for filter operation")
    
                    result = self._filter_data(df, column, value)
    
                elif operation == "transform":
    
                    result = self._transform_data(df, request.parameters)
    
                elif operation == "convert":
    
                    result = self._convert_format(df, output_format)
    
                else:
    
                    raise ToolExecutionException(f"Unknown operation: {operation}")
    
                
    
                return ToolResponse(result=result)
    
            
    
            except Exception as e:
    
                raise ToolExecutionException(f"CSV processing failed: {str(e)}")
    
        
    
        async def _get_dataframe(self, request: ToolRequest) -> pd.DataFrame:
    
            """Gets a pandas DataFrame from either CSV data or URL"""
    
            if "csvData" in request.parameters:
    
                csv_data = request.parameters.get("csvData")
    
                return pd.read_csv(io.StringIO(csv_data))
    
            elif "csvUrl" in request.parameters:
    
                csv_url = request.parameters.get("csvUrl")
    
                return pd.read_csv(csv_url)
    
            else:
    
                raise ToolExecutionException("Either csvData or csvUrl must be provided")
    
        
    
        def _generate_summary(self, df: pd.DataFrame) -> Dict[str, Any]:
    
            """Generates a summary of the CSV data"""
    
            return {
    
                "columns": df.columns.tolist(),
    
                "rowCount": len(df),
    
                "columnCount": len(df.columns),
    
                "numericColumns": df.select_dtypes(include=['number']).columns.tolist(),
    
                "categoricalColumns": df.select_dtypes(include=['object']).columns.tolist(),
    
                "sampleRows": json.loads(df.head(5).to_json(orient="records")),
    
                "statistics": json.loads(df.describe().to_json())
    
            }
    
        
    
        def _filter_data(self, df: pd.DataFrame, column: str, value: str) -> Dict[str, Any]:
    
            """Filters the DataFrame by a column value"""
    
            if column not in df.columns:
    
                raise ToolExecutionException(f"Column '{column}' not found")
    
                
    
            filtered_df = df[df[column].astype(str).str.contains(value)]
    
            
    
            return {
    
                "originalRowCount": len(df),
    
                "filteredRowCount": len(filtered_df),
    
                "data": json.loads(filtered_df.to_json(orient="records"))
    
            }
    
        
    
        def _transform_data(self, df: pd.DataFrame, params: Dict[str, Any]) -> Dict[str, Any]:
    
            """Transforms the data based on parameters"""
    
            # Implementation would include various transformations
    
            return {
    
                "status": "success",
    
                "message": "Transformation applied"
    
            }
    
        
    
        def _convert_format(self, df: pd.DataFrame, format: str) -> Dict[str, Any]:
    
            """Converts the DataFrame to different formats"""
    
            if format == "json":
    
                return {
    
                    "data": json.loads(df.to_json(orient="records")),
    
                    "format": "json"
    
                }
    
            elif format == "csv":
    
                return {
    
                    "data": df.to_csv(index=False),
    
                    "format": "csv"
    
                }
    
            elif format == "markdown":
    
                return {
    
                    "data": df.to_markdown(),
    
                    "format": "markdown"
    
                }
    
            else:
    
                raise ToolExecutionException(f"Unsupported output format: {format}")
    
    

    Contribution Guidelines

    To make a successful contribution to MCP projects:

    1. Start Small: Begin with documentation, bug fixes, or small enhancements

    2. Follow the Style Guide: Adhere to the coding style and conventions of the project

    3. Write Tests: Include unit tests for your code contributions

    4. Document Your Work: Add clear documentation for new features or changes

    5. Submit Targeted PRs: Keep pull requests focused on a single issue or feature

    6. Engage with Feedback: Be responsive to feedback on your contributions

    Example Contribution Workflow

    
    # Clone the repository
    
    git clone https://github.com/modelcontextprotocol/typescript-sdk.git
    
    cd typescript-sdk
    
    
    
    # Create a new branch for your contribution
    
    git checkout -b feature/my-contribution
    
    
    
    # Make your changes
    
    # ...
    
    
    
    # Run tests to ensure your changes don't break existing functionality
    
    npm test
    
    
    
    # Commit your changes with a descriptive message
    
    git commit -am "Fix validation in resource handler"
    
    
    
    # Push your branch to your fork
    
    git push origin feature/my-contribution
    
    
    
    # Create a pull request from your branch to the main repository
    
    # Then engage with feedback and iterate on your PR as needed
    
    

    Creating and Sharing MCP Servers

    One of the most valuable ways to contribute to the MCP ecosystem is by creating and sharing custom MCP servers. The community has already developed hundreds of servers for various services and use cases.

    MCP Server Development Frameworks

    Several frameworks are available to simplify MCP server development:

    1. Official SDKs (aligned with MCP Specification 2025-11-25):

    - TypeScript SDK

    - Python SDK

    - C# SDK

    - Go SDK

    - Java SDK

    - Kotlin SDK

    - Swift SDK

    - Rust SDK

    2. Community Frameworks:

    - MCP-Framework - Build MCP servers with elegance and speed in TypeScript

    - MCP Declarative Java SDK - Annotation-driven MCP servers with Java

    - Quarkus MCP Server SDK - Java framework for MCP servers

    - Next.js MCP Server Template - Starter Next.js project for MCP servers

    Developing Shareable Tools

    .NET Example: Creating a Shareable Tool Package
    
    // Create a new .NET library project
    
    // dotnet new classlib -n McpFinanceTools
    
    
    
    using Microsoft.Mcp.Tools;
    
    using System.Threading.Tasks;
    
    using System.Net.Http;
    
    using System.Text.Json;
    
    
    
    namespace McpFinanceTools
    
    {
    
        // Stock quote tool
    
        public class StockQuoteTool : IMcpTool
    
        {
    
            private readonly HttpClient _httpClient;
    
            
    
            public StockQuoteTool(HttpClient httpClient = null)
    
            {
    
                _httpClient = httpClient ?? new HttpClient();
    
            }
    
            
    
            public string Name => "stockQuote";
    
            public string Description => "Gets current stock quotes for specified symbols";
    
            
    
            public object GetSchema()
    
            {
    
                return new {
    
                    type = "object",
    
                    properties = new {
    
                        symbol = new { 
    
                            type = "string",
    
                            description = "Stock symbol (e.g., MSFT, AAPL)" 
    
                        },
    
                        includeHistory = new { 
    
                            type = "boolean",
    
                            description = "Whether to include historical data",
    
                            default = false
    
                        }
    
                    },
    
                    required = new[] { "symbol" }
    
                };
    
            }
    
            
    
            public async Task<ToolResponse> ExecuteAsync(ToolRequest request)
    
            {
    
                // Extract parameters
    
                string symbol = request.Parameters.GetProperty("symbol").GetString();
    
                bool includeHistory = false;
    
                
    
                if (request.Parameters.TryGetProperty("includeHistory", out var historyProp))
    
                {
    
                    includeHistory = historyProp.GetBoolean();
    
                }
    
                
    
                // Call external API (example)
    
                var quoteResult = await GetStockQuoteAsync(symbol);
    
                
    
                // Add historical data if requested
    
                if (includeHistory)
    
                {
    
                    var historyData = await GetStockHistoryAsync(symbol);
    
                    quoteResult.Add("history", historyData);
    
                }
    
                
    
                // Return formatted result
    
                return new ToolResponse {
    
                    Result = JsonSerializer.SerializeToElement(quoteResult)
    
                };
    
            }
    
            
    
            private async Task<Dictionary<string, object>> GetStockQuoteAsync(string symbol)
    
            {
    
                // Implementation would call a real stock API
    
                // This is a simplified example
    
                return new Dictionary<string, object>
    
                {
    
                    ["symbol"] = symbol,
    
                    ["price"] = 123.45,
    
                    ["change"] = 2.5,
    
                    ["percentChange"] = 1.2,
    
                    ["lastUpdated"] = DateTime.UtcNow
    
                };
    
            }
    
            
    
            private async Task<object> GetStockHistoryAsync(string symbol)
    
            {
    
                // Implementation would get historical data
    
                // Simplified example
    
                return new[]
    
                {
    
                    new { date = DateTime.Now.AddDays(-7).Date, price = 120.25 },
    
                    new { date = DateTime.Now.AddDays(-6).Date, price = 122.50 },
    
                    new { date = DateTime.Now.AddDays(-5).Date, price = 121.75 }
    
                    // More historical data...
    
                };
    
            }
    
        }
    
    }
    
    
    
    // Create package and publish to NuGet
    
    // dotnet pack -c Release
    
    // dotnet nuget push bin/Release/McpFinanceTools.1.0.0.nupkg -s https://api.nuget.org/v3/index.json -k YOUR_API_KEY
    
    
    Java Example: Creating a Maven Package for Tools
    
    // pom.xml configuration for a shareable MCP tool package
    
    <!-- 
    
    <project>
    
        <groupId>com.example</groupId>
    
        <artifactId>mcp-weather-tools</artifactId>
    
        <version>1.0.0</version>
    
        
    
        <dependencies>
    
            <dependency>
    
                <groupId>com.mcp</groupId>
    
                <artifactId>mcp-server</artifactId>
    
                <version>1.0.0</version>
    
            </dependency>
    
        </dependencies>
    
        
    
        <distributionManagement>
    
            <repository>
    
                <id>github</id>
    
                <name>GitHub Packages</name>
    
                <url>https://maven.pkg.github.com/username/mcp-weather-tools</url>
    
            </repository>
    
        </distributionManagement>
    
    </project>
    
    -->
    
    
    
    package com.example.mcp.weather;
    
    
    
    import com.mcp.tools.Tool;
    
    import com.mcp.tools.ToolRequest;
    
    import com.mcp.tools.ToolResponse;
    
    import com.mcp.tools.ToolExecutionException;
    
    
    
    import java.net.http.HttpClient;
    
    import java.net.http.HttpRequest;
    
    import java.net.http.HttpResponse;
    
    import java.net.URI;
    
    import java.util.HashMap;
    
    import java.util.Map;
    
    
    
    public class WeatherForecastTool implements Tool {
    
        private final HttpClient httpClient;
    
        private final String apiKey;
    
        
    
        public WeatherForecastTool(String apiKey) {
    
            this.httpClient = HttpClient.newHttpClient();
    
            this.apiKey = apiKey;
    
        }
    
        
    
        @Override
    
        public String getName() {
    
            return "weatherForecast";
    
        }
    
        
    
        @Override
    
        public String getDescription() {
    
            return "Gets weather forecast for a specified location";
    
        }
    
        
    
        @Override
    
        public Object getSchema() {
    
            Map<String, Object> schema = new HashMap<>();
    
            // Schema definition...
    
            return schema;
    
        }
    
        
    
        @Override
    
        public ToolResponse execute(ToolRequest request) {
    
            try {
    
                String location = request.getParameters().get("location").asText();
    
                int days = request.getParameters().has("days") ? 
    
                    request.getParameters().get("days").asInt() : 3;
    
                
    
                // Call weather API
    
                Map<String, Object> forecast = getForecast(location, days);
    
                
    
                // Build response
    
                return new ToolResponse.Builder()
    
                    .setResult(forecast)
    
                    .build();
    
            } catch (Exception ex) {
    
                throw new ToolExecutionException("Weather forecast failed: " + ex.getMessage(), ex);
    
            }
    
        }
    
        
    
        private Map<String, Object> getForecast(String location, int days) {
    
            // Implementation would call weather API
    
            // Simplified example
    
            Map<String, Object> result = new HashMap<>();
    
            // Add forecast data...
    
            return result;
    
        }
    
    }
    
    
    
    // Build and publish using Maven
    
    // mvn clean package
    
    // mvn deploy
    
    
    Python Example: Publishing a PyPI Package
    
    # Directory structure for a PyPI package:
    
    # mcp_nlp_tools/
    
    # ├── LICENSE
    
    # ├── README.md
    
    # ├── setup.py
    
    # ├── mcp_nlp_tools/
    
    # │   ├── __init__.py
    
    # │   ├── sentiment_tool.py
    
    # │   └── translation_tool.py
    
    
    
    # Example setup.py
    
    """
    
    from setuptools import setup, find_packages
    
    
    
    setup(
    
        name="mcp_nlp_tools",
    
        version="0.1.0",
    
        packages=find_packages(),
    
        install_requires=[
    
            "mcp_server>=1.0.0",
    
            "transformers>=4.0.0",
    
            "torch>=1.8.0"
    
        ],
    
        author="Your Name",
    
        author_email="your.email@example.com",
    
        description="MCP tools for natural language processing tasks",
    
        long_description=open("README.md").read(),
    
        long_description_content_type="text/markdown",
    
        url="https://github.com/username/mcp_nlp_tools",
    
        classifiers=[
    
            "Programming Language :: Python :: 3",
    
            "License :: OSI Approved :: MIT License",
    
            "Operating System :: OS Independent",
    
        ],
    
        python_requires=">=3.8",
    
    )
    
    """
    
    
    
    # Example NLP tool implementation (sentiment_tool.py)
    
    from mcp_tools import Tool, ToolRequest, ToolResponse, ToolExecutionException
    
    from transformers import pipeline
    
    import torch
    
    
    
    class SentimentAnalysisTool(Tool):
    
        """MCP tool for sentiment analysis of text"""
    
        
    
        def __init__(self, model_name="distilbert-base-uncased-finetuned-sst-2-english"):
    
            # Load the sentiment analysis model
    
            self.sentiment_analyzer = pipeline("sentiment-analysis", model=model_name)
    
        
    
        def get_name(self):
    
            return "sentimentAnalysis"
    
            
    
        def get_description(self):
    
            return "Analyzes the sentiment of text, classifying it as positive or negative"
    
        
    
        def get_schema(self):
    
            return {
    
                "type": "object",
    
                "properties": {
    
                    "text": {
    
                        "type": "string", 
    
                        "description": "The text to analyze for sentiment"
    
                    },
    
                    "includeScore": {
    
                        "type": "boolean",
    
                        "description": "Whether to include confidence scores",
    
                        "default": True
    
                    }
    
                },
    
                "required": ["text"]
    
            }
    
        
    
        async def execute_async(self, request: ToolRequest) -> ToolResponse:
    
            try:
    
                # Extract parameters
    
                text = request.parameters.get("text")
    
                include_score = request.parameters.get("includeScore", True)
    
                
    
                # Analyze sentiment
    
                sentiment_result = self.sentiment_analyzer(text)[0]
    
                
    
                # Format result
    
                result = {
    
                    "sentiment": sentiment_result["label"],
    
                    "text": text
    
                }
    
                
    
                if include_score:
    
                    result["score"] = sentiment_result["score"]
    
                
    
                # Return result
    
                return ToolResponse(result=result)
    
                
    
            except Exception as e:
    
                raise ToolExecutionException(f"Sentiment analysis failed: {str(e)}")
    
    
    
    # To publish:
    
    # python setup.py sdist bdist_wheel
    
    # python -m twine upload dist/*
    
    

    Sharing Best Practices

    When sharing MCP tools with the community:

    1. Complete Documentation:

    - Document purpose, usage, and examples

    - Explain parameters and return values

    - Document any external dependencies

    2. Error Handling:

    - Implement robust error handling

    - Provide useful error messages

    - Handle edge cases gracefully

    3. Performance Considerations:

    - Optimize for both speed and resource usage

    - Implement caching when appropriate

    - Consider scalability

    4. Security:

    - Use secure API keys and authentication

    - Validate and sanitize inputs

    - Implement rate limiting for external API calls

    5. Testing:

    - Include comprehensive test coverage

    - Test with different input types and edge cases

    - Document test procedures

    Community Collaboration and Best Practices

    Effective collaboration is key to a thriving MCP ecosystem.

    Communication Channels

  • GitHub Issues and Discussions
  • Microsoft Tech Community
  • Discord and Slack channels
  • Stack Overflow (tag: model-context-protocol or mcp)
  • Code Reviews

    When reviewing MCP contributions:

    1. Clarity: Is the code clear and well-documented?

    2. Correctness: Does it work as expected?

    3. Consistency: Does it follow project conventions?

    4. Completeness: Are tests and documentation included?

    5. Security: Are there any security concerns?

    Version Compatibility

    When developing for MCP:

    1. Protocol Versioning: Adhere to the MCP protocol version your tool supports

    2. Client Compatibility: Consider backward compatibility

    3. Server Compatibility: Follow server implementation guidelines

    4. Breaking Changes: Clearly document any breaking changes

    Example Community Project: MCP Tool Registry

    An important community contribution could be developing a public registry for MCP tools.

    
    # Example schema for a community tool registry API
    
    
    
    from fastapi import FastAPI, HTTPException, Depends
    
    from pydantic import BaseModel, Field, HttpUrl
    
    from typing import List, Optional
    
    import datetime
    
    import uuid
    
    
    
    # Models for the tool registry
    
    class ToolSchema(BaseModel):
    
        """JSON Schema for a tool"""
    
        type: str
    
        properties: dict
    
        required: List[str] = []
    
    
    
    class ToolRegistration(BaseModel):
    
        """Information for registering a tool"""
    
        name: str = Field(..., description="Unique name for the tool")
    
        description: str = Field(..., description="Description of what the tool does")
    
        version: str = Field(..., description="Semantic version of the tool")
    
        schema: ToolSchema = Field(..., description="JSON Schema for tool parameters")
    
        author: str = Field(..., description="Author of the tool")
    
        repository: Optional[HttpUrl] = Field(None, description="Repository URL")
    
        documentation: Optional[HttpUrl] = Field(None, description="Documentation URL")
    
        package: Optional[HttpUrl] = Field(None, description="Package URL")
    
        tags: List[str] = Field(default_factory=list, description="Tags for categorization")
    
        examples: List[dict] = Field(default_factory=list, description="Example usage")
    
    
    
    class Tool(ToolRegistration):
    
        """Tool with registry metadata"""
    
        id: uuid.UUID = Field(default_factory=uuid.uuid4)
    
        created_at: datetime.datetime = Field(default_factory=datetime.datetime.now)
    
        updated_at: datetime.datetime = Field(default_factory=datetime.datetime.now)
    
        downloads: int = Field(default=0)
    
        rating: float = Field(default=0.0)
    
        ratings_count: int = Field(default=0)
    
    
    
    # FastAPI application for the registry
    
    app = FastAPI(title="MCP Tool Registry")
    
    
    
    # In-memory database for this example
    
    tools_db = {}
    
    
    
    @app.post("/tools", response_model=Tool)
    
    async def register_tool(tool: ToolRegistration):
    
        """Register a new tool in the registry"""
    
        if tool.name in tools_db:
    
            raise HTTPException(status_code=400, detail=f"Tool '{tool.name}' already exists")
    
        
    
        new_tool = Tool(**tool.dict())
    
        tools_db[tool.name] = new_tool
    
        return new_tool
    
    
    
    @app.get("/tools", response_model=List[Tool])
    
    async def list_tools(tag: Optional[str] = None):
    
        """List all registered tools, optionally filtered by tag"""
    
        if tag:
    
            return [tool for tool in tools_db.values() if tag in tool.tags]
    
        return list(tools_db.values())
    
    
    
    @app.get("/tools/{tool_name}", response_model=Tool)
    
    async def get_tool(tool_name: str):
    
        """Get information about a specific tool"""
    
        if tool_name not in tools_db:
    
            raise HTTPException(status_code=404, detail=f"Tool '{tool_name}' not found")
    
        return tools_db[tool_name]
    
    
    
    @app.delete("/tools/{tool_name}")
    
    async def delete_tool(tool_name: str):
    
        """Delete a tool from the registry"""
    
        if tool_name not in tools_db:
    
            raise HTTPException(status_code=404, detail=f"Tool '{tool_name}' not found")
    
        del tools_db[tool_name]
    
        return {"message": f"Tool '{tool_name}' deleted"}
    
    

    Key Takeaways

  • The MCP community is diverse and welcomes various types of contributions
  • Contributing to MCP can range from core protocol enhancements to custom tools
  • Following contribution guidelines improves the chances of your PR being accepted
  • Creating and sharing MCP tools is a valuable way to enhance the ecosystem
  • Community collaboration is essential for the growth and improvement of MCP
  • Exercise

    1. Identify an area in the MCP ecosystem where you could make a contribution based on your skills and interests

    2. Fork the MCP repository and set up a local development environment

    3. Create a small enhancement, bug fix, or tool that would benefit the community

    4. Document your contribution with proper tests and documentation

    5. Submit a pull request to the appropriate repository

    Additional Resources

  • MCP Community Projects
  • ---

    What's Next

    Next: Lessons from Early Adoption

    커뮤니티 및 기여

    _(위 이미지를 클릭하여 이 수업의 영상을 시청하세요)_

    개요

    이 수업은 MCP 커뮤니티와 소통하는 방법, MCP 생태계에 기여하는 방법, 그리고 협업 개발을 위한 모범 사례를 다룹니다. 오픈 소스 MCP 프로젝트에 참여하는 방법을 이해하는 것은 이 기술의 미래를 형성하려는 분들에게 필수적입니다.

    학습 목표

    이 수업을 마치면 다음을 할 수 있습니다:

  • MCP 커뮤니티 및 생태계 구조 이해
  • MCP 커뮤니티 포럼과 토론에 효과적으로 참여
  • MCP 오픈 소스 저장소에 기여
  • 맞춤형 MCP 도구 및 서버 생성 및 공유
  • MCP 개발 및 협업을 위한 모범 사례 준수
  • MCP 개발을 위한 커뮤니티 리소스 및 프레임워크 발견
  • MCP 커뮤니티 생태계

    MCP 생태계는 프로토콜을 발전시키기 위해 함께 일하는 다양한 구성 요소와 참여자로 이루어져 있습니다.

    주요 커뮤니티 구성 요소

    1. 핵심 프로토콜 유지 관리자: 공식 Model Context Protocol GitHub 조직은 핵심 MCP 명세와 참조 구현을 유지합니다

    2. 도구 개발자: MCP 도구와 서버를 만드는 개인 및 팀

    3. 통합 제공자: 자사의 제품과 서비스에 MCP를 통합하는 회사들

    4. 최종 사용자: 애플리케이션에서 MCP를 사용하는 개발자와 조직

    5. 기여자: 코드, 문서 또는 기타 리소스를 기여하는 커뮤니티 멤버

    커뮤니티 리소스

    공식 채널
  • MCP GitHub 조직
  • MCP 문서
  • MCP 명세
  • GitHub 토론
  • MCP 예제 및 서버 저장소
  • 커뮤니티 주도 리소스
  • MCP 클라이언트 - MCP 통합을 지원하는 클라이언트 목록
  • 커뮤니티 MCP 서버 - 커뮤니티에서 개발한 MCP 서버 목록 증가 중
  • Awesome MCP 서버 - 엄선된 MCP 서버 목록
  • PulseMCP - MCP 리소스를 발견할 수 있는 커뮤니티 허브 및 뉴스레터
  • Discord 서버 - MCP 개발자와 연결
  • 언어별 SDK 구현체
  • 블로그 게시물 및 튜토리얼
  • MCP에 기여하기

    기여 유형

    MCP 생태계는 다양한 유형의 기여를 환영합니다:

    1. 코드 기여:

    - 핵심 프로토콜 개선

    - 버그 수정

    - 도구 및 서버 구현

    - 다양한 언어의 클라이언트/서버 라이브러리

    2. 문서화:

    - 기존 문서 개선

    - 튜토리얼 및 가이드 작성

    - 문서 번역

    - 예제 및 샘플 애플리케이션 작성

    3. 커뮤니티 지원:

    - 포럼 및 토론에서 질문에 답변

    - 테스트 및 이슈 보고

    - 커뮤니티 이벤트 조직

    - 신규 기여자 멘토링

    기여 프로세스: 핵심 프로토콜

    핵심 MCP 프로토콜 또는 공식 구현에 기여하려면, 공식 기여 가이드라인의 원칙을 따르세요:

    1. 단순함과 최소주의: MCP 명세는 새 개념 추가에 높은 기준을 유지합니다. 명세에 항목을 추가하는 것보다 삭제하는 것이 더 어렵습니다.

    2. 구체적 접근법: 명세 변경은 투기적 아이디어가 아니라 구체적 구현 문제에 기반해야 합니다.

    3. 제안 단계:

    - 정의: 문제 영역 탐색, 다른 MCP 사용자도 유사한 문제를 겪는지 검증

    - 프로토타입: 예제 솔루션 구축 및 실용성 시연

    - 작성: 프로토타입을 바탕으로 명세 제안서 작성

    개발 환경 설정

    
    # 저장소를 포크하세요
    
    git clone https://github.com/YOUR-USERNAME/modelcontextprotocol.git
    
    cd modelcontextprotocol
    
    
    
    # 의존성을 설치하세요
    
    npm install
    
    
    
    # 스키마 변경의 경우, 검증하고 schema.json을 생성하세요:
    
    npm run check:schema:ts
    
    npm run generate:schema
    
    
    
    # 문서 변경의 경우
    
    npm run check:docs
    
    npm run format
    
    
    
    # 문서를 로컬에서 미리보기 (선택 사항):
    
    npm run serve:docs
    
    

    예제: 버그 수정 기여하기

    
    // 타입스크립트 SDK의 버그가 있는 원본 코드
    
    export function validateResource(resource: unknown): resource is MCPResource {
    
      if (!resource || typeof resource !== 'object') {
    
        return false;
    
      }
    
      
    
      // 버그: 누락된 속성 검증
    
      // 현재 구현:
    
      const hasName = 'name' in resource;
    
      const hasSchema = 'schema' in resource;
    
      
    
      return hasName && hasSchema;
    
    }
    
    
    
    // 기여로 수정된 구현
    
    export function validateResource(resource: unknown): resource is MCPResource {
    
      if (!resource || typeof resource !== 'object') {
    
        return false;
    
      }
    
      
    
      // 개선된 검증
    
      const hasName = 'name' in resource && typeof (resource as MCPResource).name === 'string';
    
      const hasSchema = 'schema' in resource && typeof (resource as MCPResource).schema === 'object';
    
      const hasDescription = !('description' in resource) || typeof (resource as MCPResource).description === 'string';
    
      
    
      return hasName && hasSchema && hasDescription;
    
    }
    
    

    예제: 표준 라이브러리에 새 도구 기여하기

    
    # 예제 기여: MCP 표준 라이브러리를 위한 CSV 데이터 처리 도구
    
    
    
    from mcp_tools import Tool, ToolRequest, ToolResponse, ToolExecutionException
    
    import pandas as pd
    
    import io
    
    import json
    
    from typing import Dict, Any, List, Optional
    
    
    
    class CsvProcessingTool(Tool):
    
        """
    
        Tool for processing and analyzing CSV data.
    
        
    
        This tool allows models to extract information from CSV files,
    
        run basic analysis, and convert data between formats.
    
        """
    
        
    
        def get_name(self):
    
            return "csvProcessor"
    
            
    
        def get_description(self):
    
            return "Processes and analyzes CSV data"
    
        
    
        def get_schema(self):
    
            return {
    
                "type": "object",
    
                "properties": {
    
                    "csvData": {
    
                        "type": "string", 
    
                        "description": "CSV data as a string"
    
                    },
    
                    "csvUrl": {
    
                        "type": "string",
    
                        "description": "URL to a CSV file (alternative to csvData)"
    
                    },
    
                    "operation": {
    
                        "type": "string",
    
                        "enum": ["summary", "filter", "transform", "convert"],
    
                        "description": "Operation to perform on the CSV data"
    
                    },
    
                    "filterColumn": {
    
                        "type": "string",
    
                        "description": "Column to filter by (for filter operation)"
    
                    },
    
                    "filterValue": {
    
                        "type": "string",
    
                        "description": "Value to filter for (for filter operation)"
    
                    },
    
                    "outputFormat": {
    
                        "type": "string",
    
                        "enum": ["json", "csv", "markdown"],
    
                        "default": "json",
    
                        "description": "Output format for the processed data"
    
                    }
    
                },
    
                "oneOf": [
    
                    {"required": ["csvData", "operation"]},
    
                    {"required": ["csvUrl", "operation"]}
    
                ]
    
            }
    
        
    
        async def execute_async(self, request: ToolRequest) -> ToolResponse:
    
            try:
    
                # 매개변수 추출
    
                operation = request.parameters.get("operation")
    
                output_format = request.parameters.get("outputFormat", "json")
    
                
    
                # 직접 데이터 또는 URL에서 CSV 데이터 가져오기
    
                df = await self._get_dataframe(request)
    
                
    
                # 요청된 작업에 따라 처리
    
                result = {}
    
                
    
                if operation == "summary":
    
                    result = self._generate_summary(df)
    
                elif operation == "filter":
    
                    column = request.parameters.get("filterColumn")
    
                    value = request.parameters.get("filterValue")
    
                    if not column:
    
                        raise ToolExecutionException("filterColumn is required for filter operation")
    
                    result = self._filter_data(df, column, value)
    
                elif operation == "transform":
    
                    result = self._transform_data(df, request.parameters)
    
                elif operation == "convert":
    
                    result = self._convert_format(df, output_format)
    
                else:
    
                    raise ToolExecutionException(f"Unknown operation: {operation}")
    
                
    
                return ToolResponse(result=result)
    
            
    
            except Exception as e:
    
                raise ToolExecutionException(f"CSV processing failed: {str(e)}")
    
        
    
        async def _get_dataframe(self, request: ToolRequest) -> pd.DataFrame:
    
            """Gets a pandas DataFrame from either CSV data or URL"""
    
            if "csvData" in request.parameters:
    
                csv_data = request.parameters.get("csvData")
    
                return pd.read_csv(io.StringIO(csv_data))
    
            elif "csvUrl" in request.parameters:
    
                csv_url = request.parameters.get("csvUrl")
    
                return pd.read_csv(csv_url)
    
            else:
    
                raise ToolExecutionException("Either csvData or csvUrl must be provided")
    
        
    
        def _generate_summary(self, df: pd.DataFrame) -> Dict[str, Any]:
    
            """Generates a summary of the CSV data"""
    
            return {
    
                "columns": df.columns.tolist(),
    
                "rowCount": len(df),
    
                "columnCount": len(df.columns),
    
                "numericColumns": df.select_dtypes(include=['number']).columns.tolist(),
    
                "categoricalColumns": df.select_dtypes(include=['object']).columns.tolist(),
    
                "sampleRows": json.loads(df.head(5).to_json(orient="records")),
    
                "statistics": json.loads(df.describe().to_json())
    
            }
    
        
    
        def _filter_data(self, df: pd.DataFrame, column: str, value: str) -> Dict[str, Any]:
    
            """Filters the DataFrame by a column value"""
    
            if column not in df.columns:
    
                raise ToolExecutionException(f"Column '{column}' not found")
    
                
    
            filtered_df = df[df[column].astype(str).str.contains(value)]
    
            
    
            return {
    
                "originalRowCount": len(df),
    
                "filteredRowCount": len(filtered_df),
    
                "data": json.loads(filtered_df.to_json(orient="records"))
    
            }
    
        
    
        def _transform_data(self, df: pd.DataFrame, params: Dict[str, Any]) -> Dict[str, Any]:
    
            """Transforms the data based on parameters"""
    
            # 구현에는 다양한 변환이 포함될 것입니다
    
            return {
    
                "status": "success",
    
                "message": "Transformation applied"
    
            }
    
        
    
        def _convert_format(self, df: pd.DataFrame, format: str) -> Dict[str, Any]:
    
            """Converts the DataFrame to different formats"""
    
            if format == "json":
    
                return {
    
                    "data": json.loads(df.to_json(orient="records")),
    
                    "format": "json"
    
                }
    
            elif format == "csv":
    
                return {
    
                    "data": df.to_csv(index=False),
    
                    "format": "csv"
    
                }
    
            elif format == "markdown":
    
                return {
    
                    "data": df.to_markdown(),
    
                    "format": "markdown"
    
                }
    
            else:
    
                raise ToolExecutionException(f"Unsupported output format: {format}")
    
    

    기여 가이드라인

    MCP 프로젝트에 성공적으로 기여하려면:

    1. 작게 시작: 문서, 버그 수정 또는 작은 향상부터 시작하세요

    2. 스타일 가이드 준수: 프로젝트의 코드 스타일과 규칙을 따르세요

    3. 테스트 작성: 코드 기여에 단위 테스트 포함

    4. 작업 문서화: 새로운 기능이나 변경 사항에 대해 명확한 문서 추가

    5. 타겟 PR 제출: 하나의 문제 또는 기능에 집중한 풀 리퀘스트 유지

    6. 피드백 참여: 기여에 대한 피드백에 적극적으로 응답

    예제 기여 워크플로우

    
    # 저장소를 복제하세요
    
    git clone https://github.com/modelcontextprotocol/typescript-sdk.git
    
    cd typescript-sdk
    
    
    
    # 기여를 위해 새 브랜치를 만드세요
    
    git checkout -b feature/my-contribution
    
    
    
    # 변경사항을 만드세요
    
    # ...
    
    
    
    # 변경사항이 기존 기능을 깨뜨리지 않는지 테스트를 실행하세요
    
    npm test
    
    
    
    # 설명이 포함된 메시지와 함께 변경사항을 커밋하세요
    
    git commit -am "Fix validation in resource handler"
    
    
    
    # 브랜치를 자신의 포크에 푸시하세요
    
    git push origin feature/my-contribution
    
    
    
    # 브랜치에서 메인 저장소로 풀 리퀘스트를 만드세요
    
    # 그 후 피드백에 참여하고 필요에 따라 PR을 반복하세요
    
    

    MCP 서버 생성 및 공유

    MCP 생태계에 기여하는 가장 가치 있는 방법 중 하나는 맞춤형 MCP 서버를 생성하고 공유하는 것입니다. 커뮤니티는 이미 다양한 서비스와 사용 사례를 위한 수백 개의 서버를 개발했습니다.

    MCP 서버 개발 프레임워크

    MCP 서버 개발을 단순화하는 다양한 프레임워크가 있습니다:

    1. 공식 SDK (MCP 명세 2025-11-25에 맞춤):

    - TypeScript SDK

    - Python SDK

    - C# SDK

    - Go SDK

    - Java SDK

    - Kotlin SDK

    - Swift SDK

    - Rust SDK

    2. 커뮤니티 프레임워크:

    - MCP-Framework - TypeScript로 우아하고 빠르게 MCP 서버 구축

    - MCP 선언적 Java SDK - Java로 주석 기반 MCP 서버 개발

    - Quarkus MCP 서버 SDK - MCP 서버용 Java 프레임워크

    - Next.js MCP 서버 템플릿 - MCP 서버를 위한 Next.js 스타터 프로젝트

    공유 가능한 도구 개발

    .NET 예제: 공유 가능한 도구 패키지 생성
    
    // Create a new .NET library project
    
    // dotnet new classlib -n McpFinanceTools
    
    
    
    using Microsoft.Mcp.Tools;
    
    using System.Threading.Tasks;
    
    using System.Net.Http;
    
    using System.Text.Json;
    
    
    
    namespace McpFinanceTools
    
    {
    
        // Stock quote tool
    
        public class StockQuoteTool : IMcpTool
    
        {
    
            private readonly HttpClient _httpClient;
    
            
    
            public StockQuoteTool(HttpClient httpClient = null)
    
            {
    
                _httpClient = httpClient ?? new HttpClient();
    
            }
    
            
    
            public string Name => "stockQuote";
    
            public string Description => "Gets current stock quotes for specified symbols";
    
            
    
            public object GetSchema()
    
            {
    
                return new {
    
                    type = "object",
    
                    properties = new {
    
                        symbol = new { 
    
                            type = "string",
    
                            description = "Stock symbol (e.g., MSFT, AAPL)" 
    
                        },
    
                        includeHistory = new { 
    
                            type = "boolean",
    
                            description = "Whether to include historical data",
    
                            default = false
    
                        }
    
                    },
    
                    required = new[] { "symbol" }
    
                };
    
            }
    
            
    
            public async Task<ToolResponse> ExecuteAsync(ToolRequest request)
    
            {
    
                // Extract parameters
    
                string symbol = request.Parameters.GetProperty("symbol").GetString();
    
                bool includeHistory = false;
    
                
    
                if (request.Parameters.TryGetProperty("includeHistory", out var historyProp))
    
                {
    
                    includeHistory = historyProp.GetBoolean();
    
                }
    
                
    
                // Call external API (example)
    
                var quoteResult = await GetStockQuoteAsync(symbol);
    
                
    
                // Add historical data if requested
    
                if (includeHistory)
    
                {
    
                    var historyData = await GetStockHistoryAsync(symbol);
    
                    quoteResult.Add("history", historyData);
    
                }
    
                
    
                // Return formatted result
    
                return new ToolResponse {
    
                    Result = JsonSerializer.SerializeToElement(quoteResult)
    
                };
    
            }
    
            
    
            private async Task<Dictionary<string, object>> GetStockQuoteAsync(string symbol)
    
            {
    
                // Implementation would call a real stock API
    
                // This is a simplified example
    
                return new Dictionary<string, object>
    
                {
    
                    ["symbol"] = symbol,
    
                    ["price"] = 123.45,
    
                    ["change"] = 2.5,
    
                    ["percentChange"] = 1.2,
    
                    ["lastUpdated"] = DateTime.UtcNow
    
                };
    
            }
    
            
    
            private async Task<object> GetStockHistoryAsync(string symbol)
    
            {
    
                // Implementation would get historical data
    
                // Simplified example
    
                return new[]
    
                {
    
                    new { date = DateTime.Now.AddDays(-7).Date, price = 120.25 },
    
                    new { date = DateTime.Now.AddDays(-6).Date, price = 122.50 },
    
                    new { date = DateTime.Now.AddDays(-5).Date, price = 121.75 }
    
                    // More historical data...
    
                };
    
            }
    
        }
    
    }
    
    
    
    // Create package and publish to NuGet
    
    // dotnet pack -c Release
    
    // dotnet nuget push bin/Release/McpFinanceTools.1.0.0.nupkg -s https://api.nuget.org/v3/index.json -k YOUR_API_KEY
    
    
    Java 예제: 도구용 Maven 패키지 생성
    
    // 공유 가능한 MCP 도구 패키지를 위한 pom.xml 구성
    
    <!-- 
    
    <project>
    
        <groupId>com.example</groupId>
    
        <artifactId>mcp-weather-tools</artifactId>
    
        <version>1.0.0</version>
    
        
    
        <dependencies>
    
            <dependency>
    
                <groupId>com.mcp</groupId>
    
                <artifactId>mcp-server</artifactId>
    
                <version>1.0.0</version>
    
            </dependency>
    
        </dependencies>
    
        
    
        <distributionManagement>
    
            <repository>
    
                <id>github</id>
    
                <name>GitHub Packages</name>
    
                <url>https://maven.pkg.github.com/username/mcp-weather-tools</url>
    
            </repository>
    
        </distributionManagement>
    
    </project>
    
    -->
    
    
    
    package com.example.mcp.weather;
    
    
    
    import com.mcp.tools.Tool;
    
    import com.mcp.tools.ToolRequest;
    
    import com.mcp.tools.ToolResponse;
    
    import com.mcp.tools.ToolExecutionException;
    
    
    
    import java.net.http.HttpClient;
    
    import java.net.http.HttpRequest;
    
    import java.net.http.HttpResponse;
    
    import java.net.URI;
    
    import java.util.HashMap;
    
    import java.util.Map;
    
    
    
    public class WeatherForecastTool implements Tool {
    
        private final HttpClient httpClient;
    
        private final String apiKey;
    
        
    
        public WeatherForecastTool(String apiKey) {
    
            this.httpClient = HttpClient.newHttpClient();
    
            this.apiKey = apiKey;
    
        }
    
        
    
        @Override
    
        public String getName() {
    
            return "weatherForecast";
    
        }
    
        
    
        @Override
    
        public String getDescription() {
    
            return "Gets weather forecast for a specified location";
    
        }
    
        
    
        @Override
    
        public Object getSchema() {
    
            Map<String, Object> schema = new HashMap<>();
    
            // 스키마 정의...
    
            return schema;
    
        }
    
        
    
        @Override
    
        public ToolResponse execute(ToolRequest request) {
    
            try {
    
                String location = request.getParameters().get("location").asText();
    
                int days = request.getParameters().has("days") ? 
    
                    request.getParameters().get("days").asInt() : 3;
    
                
    
                // 날씨 API 호출
    
                Map<String, Object> forecast = getForecast(location, days);
    
                
    
                // 응답 생성
    
                return new ToolResponse.Builder()
    
                    .setResult(forecast)
    
                    .build();
    
            } catch (Exception ex) {
    
                throw new ToolExecutionException("Weather forecast failed: " + ex.getMessage(), ex);
    
            }
    
        }
    
        
    
        private Map<String, Object> getForecast(String location, int days) {
    
            // 구현에서는 날씨 API를 호출합니다
    
            // 단순화된 예제
    
            Map<String, Object> result = new HashMap<>();
    
            // 예보 데이터 추가...
    
            return result;
    
        }
    
    }
    
    
    
    // Maven을 사용하여 빌드 및 배포
    
    // mvn clean package
    
    // mvn deploy
    
    
    Python 예제: PyPI 패키지 배포
    
    # PyPI 패키지의 디렉토리 구조:
    
    # mcp_nlp_tools/
    
    # ├── LICENSE
    
    # ├── README.md
    
    # ├── setup.py
    
    # ├── mcp_nlp_tools/
    
    # │   ├── __init__.py
    
    # │   ├── sentiment_tool.py
    
    # │   └── translation_tool.py
    
    
    
    # setup.py 예제
    
    """
    
    from setuptools import setup, find_packages
    
    
    
    setup(
    
        name="mcp_nlp_tools",
    
        version="0.1.0",
    
        packages=find_packages(),
    
        install_requires=[
    
            "mcp_server>=1.0.0",
    
            "transformers>=4.0.0",
    
            "torch>=1.8.0"
    
        ],
    
        author="Your Name",
    
        author_email="your.email@example.com",
    
        description="MCP tools for natural language processing tasks",
    
        long_description=open("README.md").read(),
    
        long_description_content_type="text/markdown",
    
        url="https://github.com/username/mcp_nlp_tools",
    
        classifiers=[
    
            "Programming Language :: Python :: 3",
    
            "License :: OSI Approved :: MIT License",
    
            "Operating System :: OS Independent",
    
        ],
    
        python_requires=">=3.8",
    
    )
    
    """
    
    
    
    # NLP 도구 구현 예제 (sentiment_tool.py)
    
    from mcp_tools import Tool, ToolRequest, ToolResponse, ToolExecutionException
    
    from transformers import pipeline
    
    import torch
    
    
    
    class SentimentAnalysisTool(Tool):
    
        """MCP tool for sentiment analysis of text"""
    
        
    
        def __init__(self, model_name="distilbert-base-uncased-finetuned-sst-2-english"):
    
            # 감정 분석 모델 로드
    
            self.sentiment_analyzer = pipeline("sentiment-analysis", model=model_name)
    
        
    
        def get_name(self):
    
            return "sentimentAnalysis"
    
            
    
        def get_description(self):
    
            return "Analyzes the sentiment of text, classifying it as positive or negative"
    
        
    
        def get_schema(self):
    
            return {
    
                "type": "object",
    
                "properties": {
    
                    "text": {
    
                        "type": "string", 
    
                        "description": "The text to analyze for sentiment"
    
                    },
    
                    "includeScore": {
    
                        "type": "boolean",
    
                        "description": "Whether to include confidence scores",
    
                        "default": True
    
                    }
    
                },
    
                "required": ["text"]
    
            }
    
        
    
        async def execute_async(self, request: ToolRequest) -> ToolResponse:
    
            try:
    
                # 파라미터 추출
    
                text = request.parameters.get("text")
    
                include_score = request.parameters.get("includeScore", True)
    
                
    
                # 감정 분석 수행
    
                sentiment_result = self.sentiment_analyzer(text)[0]
    
                
    
                # 결과 형식화
    
                result = {
    
                    "sentiment": sentiment_result["label"],
    
                    "text": text
    
                }
    
                
    
                if include_score:
    
                    result["score"] = sentiment_result["score"]
    
                
    
                # 결과 반환
    
                return ToolResponse(result=result)
    
                
    
            except Exception as e:
    
                raise ToolExecutionException(f"Sentiment analysis failed: {str(e)}")
    
    
    
    # 배포를 위해:
    
    # python setup.py sdist bdist_wheel
    
    # python -m twine upload dist/*
    
    

    공유 시 모범 사례

    MCP 도구를 커뮤니티와 공유할 때:

    1. 완전한 문서화:

    - 목적, 사용법 및 예제 문서화

    - 매개변수 및 반환값 설명

    - 외부 종속성 문서화

    2. 오류 처리:

    - 견고한 오류 처리 구현

    - 유용한 오류 메시지 제공

    - 가장자리 케이스 우아하게 처리

    3. 성능 고려:

    - 속도와 자원 사용 최적화

    - 적절할 때 캐싱 구현

    - 확장성 고려

    4. 보안:

    - 안전한 API 키 및 인증 사용

    - 입력값 검증 및 정제

    - 외부 API 호출에 대한 속도 제한 구현

    5. 테스트:

    - 포괄적인 테스트 커버리지 포함

    - 다양한 입력 유형 및 가장자리 케이스 테스트

    - 테스트 절차 문서화

    커뮤니티 협업 및 모범 사례

    효과적인 협업은 번창하는 MCP 생태계의 핵심입니다.

    소통 채널

  • GitHub 이슈 및 토론
  • Microsoft Tech Community
  • Discord 및 Slack 채널
  • Stack Overflow (태그: model-context-protocol 또는 mcp)
  • 코드 리뷰

    MCP 기여를 검토할 때:

    1. 명확성: 코드가 명확하고 잘 문서화되었나?

    2. 정확성: 기대대로 작동하는가?

    3. 일관성: 프로젝트 규칙을 따르는가?

    4. 완성도: 테스트와 문서가 포함되었나?

    5. 보안: 보안 문제가 있는가?

    버전 호환성

    MCP용 개발 시:

    1. 프로토콜 버전 관리: 도구가 지원하는 MCP 프로토콜 버전 준수

    2. 클라이언트 호환성: 이전 버전과의 호환성 고려

    3. 서버 호환성: 서버 구현 가이드라인 준수

    4. 파괴적 변경: 파괴적 변경 사항을 명확히 문서화

    예제 커뮤니티 프로젝트: MCP 도구 레지스트리

    중요한 커뮤니티 기여로 MCP 도구를 위한 공개 레지스트리를 개발할 수 있습니다.

    
    # 커뮤니티 도구 등록 API 예제 스키마
    
    
    
    from fastapi import FastAPI, HTTPException, Depends
    
    from pydantic import BaseModel, Field, HttpUrl
    
    from typing import List, Optional
    
    import datetime
    
    import uuid
    
    
    
    # 도구 등록을 위한 모델
    
    class ToolSchema(BaseModel):
    
        """JSON Schema for a tool"""
    
        type: str
    
        properties: dict
    
        required: List[str] = []
    
    
    
    class ToolRegistration(BaseModel):
    
        """Information for registering a tool"""
    
        name: str = Field(..., description="Unique name for the tool")
    
        description: str = Field(..., description="Description of what the tool does")
    
        version: str = Field(..., description="Semantic version of the tool")
    
        schema: ToolSchema = Field(..., description="JSON Schema for tool parameters")
    
        author: str = Field(..., description="Author of the tool")
    
        repository: Optional[HttpUrl] = Field(None, description="Repository URL")
    
        documentation: Optional[HttpUrl] = Field(None, description="Documentation URL")
    
        package: Optional[HttpUrl] = Field(None, description="Package URL")
    
        tags: List[str] = Field(default_factory=list, description="Tags for categorization")
    
        examples: List[dict] = Field(default_factory=list, description="Example usage")
    
    
    
    class Tool(ToolRegistration):
    
        """Tool with registry metadata"""
    
        id: uuid.UUID = Field(default_factory=uuid.uuid4)
    
        created_at: datetime.datetime = Field(default_factory=datetime.datetime.now)
    
        updated_at: datetime.datetime = Field(default_factory=datetime.datetime.now)
    
        downloads: int = Field(default=0)
    
        rating: float = Field(default=0.0)
    
        ratings_count: int = Field(default=0)
    
    
    
    # 등록을 위한 FastAPI 애플리케이션
    
    app = FastAPI(title="MCP Tool Registry")
    
    
    
    # 이 예제를 위한 메모리 내 데이터베이스
    
    tools_db = {}
    
    
    
    @app.post("/tools", response_model=Tool)
    
    async def register_tool(tool: ToolRegistration):
    
        """Register a new tool in the registry"""
    
        if tool.name in tools_db:
    
            raise HTTPException(status_code=400, detail=f"Tool '{tool.name}' already exists")
    
        
    
        new_tool = Tool(**tool.dict())
    
        tools_db[tool.name] = new_tool
    
        return new_tool
    
    
    
    @app.get("/tools", response_model=List[Tool])
    
    async def list_tools(tag: Optional[str] = None):
    
        """List all registered tools, optionally filtered by tag"""
    
        if tag:
    
            return [tool for tool in tools_db.values() if tag in tool.tags]
    
        return list(tools_db.values())
    
    
    
    @app.get("/tools/{tool_name}", response_model=Tool)
    
    async def get_tool(tool_name: str):
    
        """Get information about a specific tool"""
    
        if tool_name not in tools_db:
    
            raise HTTPException(status_code=404, detail=f"Tool '{tool_name}' not found")
    
        return tools_db[tool_name]
    
    
    
    @app.delete("/tools/{tool_name}")
    
    async def delete_tool(tool_name: str):
    
        """Delete a tool from the registry"""
    
        if tool_name not in tools_db:
    
            raise HTTPException(status_code=404, detail=f"Tool '{tool_name}' not found")
    
        del tools_db[tool_name]
    
        return {"message": f"Tool '{tool_name}' deleted"}
    
    

    주요 요점

  • MCP 커뮤니티는 다양하며 여러 유형의 기여를 환영합니다
  • MCP에 기여는 핵심 프로토콜 개선부터 맞춤 도구 개발까지 다양합니다
  • 기여 가이드라인 준수는 PR 수용 가능성을 높입니다
  • MCP 도구를 만들고 공유하는 것은 생태계 향상의 가치 있는 방법입니다
  • 커뮤니티 협업은 MCP 성장과 개선의 필수 요소입니다
  • 연습 문제

    1. 본인의 역량과 관심사에 기반해 MCP 생태계에서 기여할 영역을 찾아보세요

    2. MCP 저장소를 포크하고 로컬 개발 환경을 설정하세요

    3. 커뮤니티에 도움이 될 작은 향상, 버그 수정 또는 도구를 만드세요

    4. 적절한 테스트와 문서화로 기여 내용을 문서화하세요

    5. 적절한 저장소에 풀 리퀘스트를 제출하세요

    추가 리소스

  • MCP 커뮤니티 프로젝트
  • ---

    다음 내용

    다음: 초기 도입의 교훈

    ---

    면책 조항:

    이 문서는 AI 번역 서비스 Co-op Translator를 사용하여 번역되었습니다.

    정확성을 위해 노력하고 있으나, 자동 번역에는 오류나 부정확성이 포함될 수 있음을 유의하시기 바랍니다.

    원본 문서의 원어 버전이 권위 있는 출처로 간주되어야 합니다.

    중요한 정보의 경우 전문 인력에 의한 번역을 권장합니다.

    이 번역의 사용으로 인해 발생하는 오해나 잘못된 해석에 대해 당사는 책임을 지지 않습니다.

    MCP Academy — microsoft/mcp-for-beginners