(Klikk på bildet over for å se video av denne leksjonen)
Denne leksjonen fokuserer på hvordan man kan engasjere seg i MCP-fellesskapet, bidra til MCP-økosystemet og følge beste praksis for samarbeidende utvikling. Å forstå hvordan man deltar i åpen kildekode-prosjekter innen MCP er essensielt for de som ønsker å forme fremtiden for denne teknologien.
Ved slutten av denne leksjonen vil du kunne:
- Forstå strukturen i MCP-fellesskapet og økosystemet
- Delta effektivt i MCP-fellesskapets fora og diskusjoner
- Bidra til MCP åpne kildekode-repositorier
- Lage og dele egne MCP-verktøy og servere
- Følge beste praksis for MCP-utvikling og samarbeid
- Oppdage fellesskapsressurser og rammeverk for MCP-utvikling
MCP-økosystemet består av ulike komponenter og deltakere som samarbeider for å fremme protokollen.
- Kjerneprotokollvedlikeholdere: Den offisielle Model Context Protocol GitHub-organisasjonen vedlikeholder de grunnleggende MCP-spesifikasjonene og referanseimplementasjonene.
- Verktøyutviklere: Enkeltpersoner og team som lager MCP-verktøy og servere.
- Integrasjonsleverandører: Bedrifter som integrerer MCP i sine produkter og tjenester.
- Sluttbrukere: Utviklere og organisasjoner som bruker MCP i sine applikasjoner.
- Bidragsytere: Fellesskapsmedlemmer som bidrar med kode, dokumentasjon eller andre ressurser.
- MCP GitHub-organisasjon
- MCP Dokumentasjon
- MCP Spesifikasjon
- GitHub Diskusjoner
- MCP Eksempler & Servere Repository
- MCP Klienter - Liste over klienter som støtter MCP-integrasjoner
- Community MCP Servere - Voksende liste over MCP-servere utviklet av fellesskapet
- Awesome MCP Servere - Kvalitetskontrollert liste over MCP-servere
- PulseMCP - Fellesskapshub & nyhetsbrev for å oppdage MCP-ressurser
- Discord Server - Koble med MCP-utviklere
- Språkspesifikke SDK-implementeringer
- Blogginnlegg og veiledninger
MCP-økosystemet ønsker ulike typer bidrag velkommen:
-
Kodebidrag:
- Forbedringer av kjerneprotokollen
- Feilrettinger
- Verktøy- og serverimplementasjoner
- Klient-/server-biblioteker i forskjellige språk
-
Dokumentasjon:
- Forbedre eksisterende dokumentasjon
- Lage veiledninger og guider
- Oversette dokumentasjon
- Lage eksempler og prøveapplikasjoner
-
Fellesskapsstøtte:
- Svar på spørsmål i fora og diskusjoner
- Teste og rapportere problemer
- Organisere fellesskapsarrangementer
- Veilede nye bidragsytere
For å bidra til kjerneprotokollen eller offisielle implementasjoner, følg prinsippene i de offisielle retningslinjene for bidrag:
-
Enkelhet og minimalisme: MCP-spesifikasjonen har høye krav for å legge til nye konsepter. Det er lettere å legge til ting i en spesifikasjon enn å fjerne dem.
-
Konkret tilnærming: Endringer i spesifikasjonen bør baseres på konkrete implementeringsutfordringer, ikke spekulative ideer.
-
Faser av et forslag:
- Definer: Utforsk problemområdet, bekreft at andre MCP-brukere har et lignende problem
- Prototype: Bygg et eksempel på en løsning og demonstrer praktisk bruk
- Skriv: Basert på prototypen, skriv et spesifikasjonsforslag
# Forke depotet
git clone https://github.com/YOUR-USERNAME/modelcontextprotocol.git
cd modelcontextprotocol
# Installer avhengigheter
npm install
# For skjemaendringer, valider og generer schema.json:
npm run check:schema:ts
npm run generate:schema
# For dokumentasjonsendringer
npm run check:docs
npm run format
# Forhåndsvis dokumentasjonen lokalt (valgfritt):
npm run serve:docs// Originalkode med feil i typescript-sdk
export function validateResource(resource: unknown): resource is MCPResource {
if (!resource || typeof resource !== 'object') {
return false;
}
// Feil: Manglende egenskapsvalidering
// Nåværende implementering:
const hasName = 'name' in resource;
const hasSchema = 'schema' in resource;
return hasName && hasSchema;
}
// Fikset implementering i et bidrag
export function validateResource(resource: unknown): resource is MCPResource {
if (!resource || typeof resource !== 'object') {
return false;
}
// Forbedret validering
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;
}# Eksempelbidrag: Et verktøy for behandling av CSV-data for MCP-standardbiblioteket
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:
# Hent ut parametere
operation = request.parameters.get("operation")
output_format = request.parameters.get("outputFormat", "json")
# Hent CSV-data fra enten direkte data eller URL
df = await self._get_dataframe(request)
# Behandle basert på forespurt operasjon
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"""
# Implementeringen vil inkludere ulike transformasjoner
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}")For å lykkes med ditt bidrag til MCP-prosjekter:
- Start i det små: Begynn med dokumentasjon, feilrettinger eller små forbedringer
- Følg stilguiden: Hold deg til prosjektets kodingstil og konvensjoner
- Skriv tester: Inkluder enhetstester for dine kodebidrag
- Dokumenter arbeidet ditt: Legg til tydelig dokumentasjon for nye funksjoner eller endringer
- Send presise PR-er: Hold pull requests fokusert på ett enkelt problem eller funksjon
- Engasjer deg i tilbakemeldinger: Vær lydhør for tilbakemeldinger på dine bidrag
# Klon depotet
git clone https://github.com/modelcontextprotocol/typescript-sdk.git
cd typescript-sdk
# Opprett en ny gren for ditt bidrag
git checkout -b feature/my-contribution
# Gjør dine endringer
# ...
# Kjør tester for å sikre at endringene dine ikke bryter eksisterende funksjonalitet
npm test
# Committ endringene dine med en beskrivende melding
git commit -am "Fix validation in resource handler"
# Push grenen din til din fork
git push origin feature/my-contribution
# Opprett en pull request fra din gren til hoveddepotet
# Deretter engasjer deg med tilbakemeldinger og iterer på PR-en din etter behovEn av de mest verdifulle måtene å bidra til MCP-økosystemet på er ved å lage og dele egne MCP-servere. Fellesskapet har allerede utviklet hundrevis av servere for ulike tjenester og bruksområder.
Flere rammeverk finnes for å forenkle MCP-serverutvikling:
-
Offisielle SDK-er (i tråd med MCP Spesifikasjon 2025-11-25):
-
Fellesskapsrammeverk:
- MCP-Framework - Bygg MCP-servere med eleganse og fart i TypeScript
- MCP Declarative Java SDK - Annotationsdrevne MCP-servere med Java
- Quarkus MCP Server SDK - Java-rammeverk for MCP-servere
- Next.js MCP Server Template - Starter Next.js-prosjekt for MCP-servere
// 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// pom.xml-konfigurasjon for en delbar MCP-verktøypakke
<!--
<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/brukernavn/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<>();
// Skjemadefinisjon...
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;
// Kall vær-API
Map<String, Object> forecast = getForecast(location, days);
// Bygg respons
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) {
// Implementering ville kalle vær-API
// Forenklet eksempel
Map<String, Object> result = new HashMap<>();
// Legg til værmeldingsdata...
return result;
}
}
// Bygg og publiser med Maven
// mvn clean package
// mvn deploy# Katalogstruktur for en PyPI-pakke:
# mcp_nlp_tools/
# ├── LICENSE
# ├── README.md
# ├── setup.py
# ├── mcp_nlp_tools/
# │ ├── __init__.py
# │ ├── sentiment_tool.py
# │ └── translation_tool.py
# Eksempel 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",
)
"""
# Eksempel på implementering av NLP-verktøy (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"):
# Last inn sentimentanalysemodellen
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:
# Hent ut parametere
text = request.parameters.get("text")
include_score = request.parameters.get("includeScore", True)
# Analyser sentiment
sentiment_result = self.sentiment_analyzer(text)[0]
# Formater resultat
result = {
"sentiment": sentiment_result["label"],
"text": text
}
if include_score:
result["score"] = sentiment_result["score"]
# Returner resultat
return ToolResponse(result=result)
except Exception as e:
raise ToolExecutionException(f"Sentiment analysis failed: {str(e)}")
# For å publisere:
# python setup.py sdist bdist_wheel
# python -m twine upload dist/*Når du deler MCP-verktøy med fellesskapet:
-
Fullstendig dokumentasjon:
- Dokumenter formål, bruk og eksempler
- Forklar parametere og returverdier
- Dokumenter eventuelle eksterne avhengigheter
-
Feilhåndtering:
- Implementer robust feilhåndtering
- Gi nyttige feilmeldinger
- Håndter kanttilfeller elegant
-
Ytelsesbetraktninger:
- Optimaliser både for hastighet og ressursbruk
- Implementer caching når det er passende
- Tenk på skalerbarhet
-
Sikkerhet:
- Bruk sikre API-nøkler og autentisering
- Valider og rens input
- Implementer rate limiting for eksterne API-kall
-
Testing:
- Inkluder omfattende testdekning
- Test med ulike inputtyper og kanttilfeller
- Dokumenter testprosedyrer
Effektivt samarbeid er nøkkelen til et blomstrende MCP-økosystem.
- GitHub Issues og Diskusjoner
- Microsoft Tech Community
- Discord- og Slack-kanaler
- Stack Overflow (tagg:
model-context-protocolellermcp)
Ved gjennomgang av MCP-bidrag:
- Klarhet: Er koden klar og godt dokumentert?
- Riktighet: Fungerer den som forventet?
- Konsistens: Følger den prosjektets konvensjoner?
- Fullstendighet: Er tester og dokumentasjon inkludert?
- Sikkerhet: Er det noen sikkerhetsbekymringer?
Ved utvikling for MCP:
- Protokollversjonering: Følg MCP-protokollversjonen verktøyet ditt støtter
- Klientkompatibilitet: Vurder bakoverkompatibilitet
- Serverkompatibilitet: Følg serverimplementasjonsretningslinjer
- Bruddendringer: Dokumenter tydelig eventuelle bruddendringer
En viktig fellesskapsbidrag kan være å utvikle et offentlig register for MCP-verktøy.
# Eksempelskjema for et API for verktøyregister i fellesskapet
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel, Field, HttpUrl
from typing import List, Optional
import datetime
import uuid
# Modeller for verktøyregisteret
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-applikasjon for registeret
app = FastAPI(title="MCP Tool Registry")
# Minnebasert database for dette eksemplet
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-fellesskapet er mangfoldig og ønsker ulike typer bidrag velkommen
- Bidrag til MCP kan variere fra kjerneprotokollforbedringer til egendefinerte verktøy
- Å følge retningslinjene for bidrag øker sjansen for at PR-en din blir akseptert
- Å lage og dele MCP-verktøy er en verdifull måte å styrke økosystemet på
- Fellesskapssamarbeid er essensielt for vekst og forbedring av MCP
- Identifiser et område i MCP-økosystemet hvor du kan bidra basert på dine ferdigheter og interesser
- Fork MCP-repositoriet og sett opp et lokalt utviklingsmiljø
- Lag en liten forbedring, feilretting eller et verktøy som kan være til nytte for fellesskapet
- Dokumenter bidraget ditt med adekvate tester og dokumentasjon
- Send en pull request til det riktige repositoriet
Neste: Lessons from Early Adoption
Ansvarsfraskrivelse: Dette dokumentet er oversatt ved bruk av AI-oversettelsestjenesten Co-op Translator. Selv om vi streber etter nøyaktighet, vennligst vær oppmerksom på at automatiske oversettelser kan inneholde feil eller unøyaktigheter. Det opprinnelige dokumentet på dets originalspråk skal anses som den autoritative kilden. For kritisk informasjon anbefales profesjonell menneskelig oversettelse. Vi er ikke ansvarlige for eventuelle misforståelser eller feiltolkninger som oppstår ved bruk av denne oversettelsen.
