MCP Server
Introduction
Tuanjie AI MCP Server is an extension server built on the Model Context Protocol (MCP), designed to provide Codely CLI with the capability to integrate with external systems and services. Through MCP Server, Tuanjie AI can access databases, APIs, file systems, and other third-party services, thereby greatly expanding its functional boundaries.
What Is an MCP Server?
An MCP Server is an independently running application that exposes tools, resources, and prompts to Codely CLI through the standardized MCP protocol. Codely CLI communicates with MCP Servers through three transport mechanisms:
- Stdio transport: Communicates with local subprocesses through standard input/output
- SSE transport: Communicates with remote servers through Server-Sent Events
- Streamable HTTP transport: Communicates with remote servers through HTTP streaming
Advantages of Tuanjie AI MCP Server
- Modular extension: Package complex functionality as independent servers, keeping the core codebase clean
- Secure isolation: Sensitive credentials and service logic isolated from Tuanjie AI main process
- Flexible deployment: Supports multiple deployment methods including local processes, Docker containers, or remote services
- Unified interface: All external services accessed through unified MCP protocol
- Dynamic discovery: Tuanjie AI automatically discovers tools provided by servers without manual configuration
Typical Application Scenarios
- Code repository integration: Access Git hosting services like GitHub, GitLab
- Database operations: Query and manipulate databases such as PostgreSQL, MySQL, MongoDB
- Cloud service access: Interact with cloud platforms like AWS, Google Cloud, Azure
- Team collaboration: Integrate collaboration tools like Slack, Jira, Notion
- File processing: Access network storage, S3, Google Drive, and other file services
Managing MCP Server via GUI
- Type '/' in the dialog box and select "Manage Mcp Servers" from the dropdown menu. Or directly type "/MCP".
- Create your own Mcp Server in the opened dialog.
- After creating a new Mcp Server, start a new conversation session. The newly added Mcp Server will complete its loading when the new session starts.
- Type '@' in the conversation window to quickly select your newly added Mcp Server.
Difference between Types when creating Mcp Server:
- STDIO: Standard Input/Output. Communicates between local processes through standard input/output streams, suitable for local tool invocation.
- SSE: Server-Sent Events. Server push technology based on HTTP, suitable for continuous data streaming from server to client.
- Streamable HTTP: Streamable HTTP (an HTTP protocol variant that supports data streaming). Compatible with HTTP and supports streaming responses, balancing compatibility and real-time data transmission.
Comparison table of communication methods use cases
| Communication Method | Full Name | Core Features | Use Cases | Advantages | Disadvantages |
|---|---|---|---|---|---|
| STDIO | Standard Input/Output | Local communication based on process standard input/output streams | ✅ Local tool/script invocation ✅ Desktop local MCP services ✅ Offline scenarios without network dependency | 🔹 Low latency, high performance 🔹 No network configuration needed 🔹 Simple deployment, secure isolation | 🔸 Only supports local inter-process communication 🔸 Cannot be used across machines/networks |
| SSE | Server-Sent Events | Unidirectional server push stream based on HTTP | ✅ Cloud MCP services ✅ Real-time data push (such as logs, progress) ✅ Browser/client long connections | 🔹 Compatible with HTTP standards 🔹 Automatic reconnection mechanism 🔹 Server-side active push | 🔸 Only unidirectional communication (server→client) 🔸 Does not support binary data 🔸 Limited by browser connection limits |
| Streamable HTTP | Streamable HTTP | Bidirectional streaming communication compatible with HTTP protocol | ✅ Cross-network/cloud service deployment ✅ Real-time scenarios requiring bidirectional interaction ✅ Compatible with existing HTTP infrastructure | 🔹 Bidirectional streaming data transmission 🔹 Compatible with standard HTTP/HTTPS 🔹 Supports binary/text mixed streams | 🔸 Implementation complexity slightly higher than SSE 🔸 Some older proxies may not be compatible |
Quick selection recommendations
- Local development/offline tools → Choose STDIO, simple and efficient, no network needed.
- Cloud services + unidirectional push → Choose SSE, suitable for scenarios like logs, notifications.
- Cross-network + bidirectional real-time interaction → Choose Streamable HTTP, best balance between compatibility and real-time performance.
Managing MCP Server via CLI
Prerequisites
Before you begin, ensure you meet the following prerequisites:
- Codely CLI installed: Ensure the latest version of Codely CLI is installed on your system
- Docker (optional): Some MCP Servers run as Docker containers
- Necessary credentials: Prepare corresponding API keys or access tokens based on the services to be connected
- Network connection: Ensure access to the service address where the MCP Server is located
Preparing Credentials
Most MCP Servers require authentication to access protected resources. Secure management of credentials is crucial.
Credential Management Best Practices
- Use environment variables: Store sensitive credentials in environment variables rather than hardcoding them in configuration files
- Principle of least privilege: Assign to credentials the minimum permissions needed to complete tasks
- Regular rotation: Regularly update access tokens and keys
- Secure storage: Use the system's secure credential storage mechanism
Example: Preparing GitHub Credentials
If you want to use GitHub MCP Server, you need to create a Personal Access Token (PAT):
- Log in to GitHub, go to Settings → Developer settings → Personal access tokens → Tokens (classic)
- Create a new token and grant the following permissions:
- repo: Full repository access
- read:org: Read organization information (if needed)
- Securely store the token in an environment variable
macOS/Linux:
export GITHUB_PERSONAL_ACCESS_TOKEN="github_pat_..."
Windows (PowerShell):
$env:GITHUB_PERSONAL_ACCESS_TOKEN="github_pat_..."
Configuring Codely CLI
Codely CLI discovers and connects to MCP Servers through the settings.json file. You can configure global servers (user level) or project-specific servers (project level).
Configuration File Location
- User-level configuration: ~/.codely-cli/settings.json
- Project-level configuration:
<project directory>/.codely-cli/settings.json
Project-level configuration overrides servers with the same name in user-level configuration.
Basic Configuration Structure
Add mcpServers object to settings.json:
{
"mcpServers": {
"serverName": {
"command": "path/to/executable",
"args": ["--arg1", "value1"],
"env": {
"API_KEY": "$API_KEY"
},
"cwd": "./working/directory",
"timeout": 30000,
"trust": false
}
}
}
Configuration Property Descriptions
| Property | Type | Required | Description |
|---|---|---|---|
| command | string | One of | Executable file path for Stdio transport |
| url | string | One of | Endpoint URL for SSE transport |
| httpUrl | string | One of | Endpoint URL for HTTP streaming transport |
| args | string[] | No | Command line arguments (for Stdio only) |
| headers | object | No | HTTP request headers (for SSE/HTTP) |
| env | object | No | Environment variables (supports $VAR syntax expansion) |
| cwd | string | No | Working directory (for Stdio only) |
| timeout | number | No | Request timeout (milliseconds, default 600000) |
| trust | boolean | No | Whether to skip tool call confirmation (default false) |
| includeTools | string[] | No | Whitelist of tools to include |
| excludeTools | string[] | No | Blacklist of tools to exclude |
Configuration Examples
1. GitHub MCP Server (Docker)
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:latest"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
}
}
}
}
2. PostgreSQL MCP Server (Python)
{
"mcpServers": {
"postgres": {
"command": "python",
"args": ["-m", "postgres_mcp_server"],
"cwd": "./mcp-servers/postgres",
"env": {
"DATABASE_URL": "$DATABASE_URL",
"DB_HOST": "${DB_HOST}",
"DB_PORT": "${DB_PORT:-5432}"
},
"timeout": 15000
}
}
}
3. Custom Node.js MCP Server
{
"mcpServers": {
"my-custom-server": {
"command": "node",
"args": ["dist/server.js", "--verbose"],
"cwd": "./my-mcp-server",
"trust": true
}
}
}
4. Remote HTTP MCP Server
{
"mcpServers": {
"remote-api": {
"httpUrl": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer ${API_TOKEN}",
"X-Custom-Header": "custom-value"
},
"timeout": 5000
}
}
}
Verifying Connection
After configuration is complete, restart Codely CLI to load the new MCP Server configuration.
Checking Server Status
Use the /mcp or /mcp list command to view the connection status of all MCP Servers:
/mcp list
Expected output example:
✓ github: docker run -i --rm ... - Connected
✓ postgres: python -m postgres_mcp_server - Connected
✗ remote-api: https://api.example.com/mcp - Disconnected
Error: Connection timeout
Status Descriptions
- Connected: Server has successfully connected and registered tools
- Connecting: Attempting to connect
- Disconnected: Connection failed or not connected
- Disabled: Server has been manually disabled
Troubleshooting
If the server shows as Disconnected:
- Check if Docker is running (for Docker servers)
docker ps
- Verify the command is available
python --version
node --version
- Check if environment variables are set
echo $GITHUB_PERSONAL_ACCESS_TOKEN
- View detailed error logs
/mcp list
- Force reload
/mcp reload
Using New Tools
Once the MCP Server is successfully connected, Tuanjie AI can automatically use all tools provided by the server. You don't need to learn special commands—just describe your needs in natural language.
Automatic Tool Discovery
Tuanjie AI will automatically:
- Enumerate tools: Get all available tools and their definitions from the server
- Schema validation: Validate tool input/output schemas
- Namespace handling: Add mcp_{serverName}_ prefix to tools to avoid conflicts
- Register to tool library: Make tools visible to the model
Usage Scenario Examples
Scenario 1: List Pull Requests from GitHub Repository
User input:
List all open PRs in the google/gemini-cli repository, sorted by creation time
Steps automatically executed by Tuanjie AI:
- Identify that the request involves GitHub repository operations
- Select the mcp_github_list_pull_requests tool
- Request user confirmation for tool call (unless server is marked as trusted)
- Execute tool with parameters:
{
"owner": "google",
"repo": "gemini-cli",
"state": "open"
}
- Parse returned PR data and present results in a readable format
Scenario 2: Create GitHub Issue
User input:
Create an issue in my repository with title "Bug: Login failed" and description "Please check the attached log"
Tuanjie AI executes:
- Identify that a GitHub Issue needs to be created
- Call the mcp_github_create_issue tool
- Use the following parameters:
{
"title": "Bug: Login failed",
"body": "Please check the attached log",
"labels": ["bug"]
}
- Return the created issue link and details
Scenario 3: Query PostgreSQL Database
User input:
Query the 10 most recently registered users from the users table
Tuanjie AI executes:
- Identify that a database query is needed
- Call the mcp_postgres_query tool
- Use parameters:
{
"query": "SELECT * FROM users ORDER BY created_at DESC LIMIT 10"
}
- Display query results in table format
Scenario 4: Read MCP Resources
If the MCP Server exposes resources, you can use @ syntax to reference them:
Please analyze the content of @github://repo/contents/README.md
Tuanjie AI will automatically:
- Identify the @github:// resource reference
- Call the server's resources/read method
- Inject the resource content into the conversation context
Troubleshooting
Common Issues
Issue 1: Server Cannot Start
Symptom: /mcp list shows Disconnected
Solution:
- Manually run the server command to view error messages
docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN ghcr.io/github/github-mcp-server:latest
- Check if the port is occupied
netstat -an | grep 8080
- Verify dependencies are installed
pip list | grep mcp
npm list | grep @modelcontextprotocol
Issue 2: Tools Not Discovered
Symptom: Server is connected but tool list is empty
Solution:
- Force reload:
/mcp reload
- Check if there are errors in server logs
- Verify that the server correctly implements the MCP protocol's tool list endpoint
Issue 3: Tool Execution Failed
Symptom: Error returned when calling tool
Solution:
- Check if parameters conform to the tool's schema definition
- Verify credentials are valid and have sufficient permissions
- Increase timeout
- View server's stderr output
Issue 4: Environment Variables Not Expanded
Symptom: Server cannot access environment variables
Solution:
- Confirm environment variables are set in the shell
- Use correct syntax:
${VAR_NAME}or$VAR_NAME(all platforms)- %VAR_NAME% (Windows only)
- Verify variable name spelling is correct
How to Create a Tuanjie AI MCP Server
Understanding the MCP Protocol
MCP is an open standard protocol that defines communication specifications between AI assistants and external services. Core concepts include:
MCP Core Components
- Tools: Executable functions that accept input parameters and return results
- Resources: Readable data entities (files, documents, records, etc.)
- Prompts: Predefined prompt templates that can be called as slash commands
MCP Message Types
| Method | Direction | Description |
|---|---|---|
| tools/list | Client → Server | List all available tools |
| tools/call | Client → Server | Call a specific tool |
| resources/list | Client → Server | List all available resources |
| resources/read | Client → Server | Read a specific resource |
| prompts/list | Client → Server | List all available prompts |
| prompts/get | Client → Server | Get a specific prompt |
Creating Project Structure
Project Directory Layout
codely-mcp-server/
├── package.json # Node.js project configuration
├── tsconfig.json # TypeScript configuration
├── src/
│ ├── index.ts # Server entry point
│ ├── tools/ # Tool implementations
│ │ ├── calculator.ts
│ │ └── data-processor.ts
│ ├── resources/ # Resource implementations
│ │ └── file-reader.ts
│ └── prompts/ # Prompt implementations
│ └── code-review.ts
├── dist/ # Compiled output (auto-generated)
└── README.md # Project documentation
Initializing Project
# Create project directory
mkdir codely-mcp-server
cd codely-mcp-server
# Initialize Node.js project
npm init -y
# Install dependencies
npm install @modelcontextprotocol/sdk zod
# Install development dependencies
npm install -D typescript @types/node ts-node
Configuring TypeScript
Create tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "Node16",
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Update package.json:
{
"name": "codely-mcp-server",
"version": "1.0.0",
"description": "Tuanjie AI MCP Server for custom integrations",
"type": "module",
"main": "dist/index.js",
"bin": {
"codely-mcp": "./dist/index.js"
},
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "ts-node src/index.ts",
"watch": "tsc --watch"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.4",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/node": "^20.0.0",
"ts-node": "^10.9.0",
"typescript": "^5.0.0"
}
}
Implementing Server Logic
Basic Server Implementation
Create src/index.ts:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
// Create MCP server instance
const server = new McpServer({
name: 'codely-mcp-server',
version: '1.0.0',
});
// Register tools, resources, and prompts here
// Start server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('Tuanjie AI MCP Server running on stdio');
}
main().catch((error) => {
console.error('Fatal error in main():', error);
process.exit(1);
});
Registering Tools
Tools are the core functionality of an MCP Server. Each tool has a name, description, and input schema.
Example 1: Calculator Tool
Create src/tools/calculator.ts:
import { z } from 'zod';
export const calculatorTool = {
name: 'calculate',
description: 'Perform basic mathematical operations (add, subtract, multiply, divide)',
inputSchema: z.object({
operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
a: z.number().describe('First operand'),
b: z.number().describe('Second operand')
}),
handler: async ({ operation, a, b }) => {
let result: number;
switch (operation) {
case 'add':
result = a + b;
break;
case 'subtract':
result = a - b;
break;
case 'multiply':
result = a * b;
break;
case 'divide':
if (b === 0) {
throw new Error('Divisor cannot be zero');
}
result = a / b;
break;
default:
throw new Error(`Unknown operation: ${operation}`);
}
return {
content: [
{
type: 'text',
text: `${operation}(${a}, ${b}) = ${result}`
}
]
};
}
};
Register the tool in src/index.ts:
import { calculatorTool } from './tools/calculator.js';
// Register calculator tool
server.registerTool(
calculatorTool.name,
calculatorTool.description,
calculatorTool.inputSchema.shape,
calculatorTool.handler
);
Example 2: Data Processing Tool
Create src/tools/data-processor.ts:
import { z } from 'zod';
export const dataProcessorTool = {
name: 'process_data',
description: 'Process and analyze JSON data arrays',
inputSchema: z.object({
data: z.array(z.record(z.any())).describe('Data array to process'),
operation: z.enum(['sum', 'average', 'max', 'min', 'count']),
field: z.string().optional().describe('Field name to operate on')
}),
handler: async ({ data, operation, field }) => {
if (data.length === 0) {
return {
content: [
{
type: 'text',
text: 'Data array is empty'
}
]
};
}
let result: number | string;
if (field) {
const values = data.map(item => item[field]).filter(v => typeof v === 'number') as number[];
if (values.length === 0) {
return {
content: [
{
type: 'text',
text: `Field "${field}" does not exist or has no numeric data`
}
]
};
}
switch (operation) {
case 'sum':
result = values.reduce((sum, v) => sum + v, 0);
break;
case 'average':
result = values.reduce((sum, v) => sum + v, 0) / values.length;
break;
case 'max':
result = Math.max(...values);
break;
case 'min':
result = Math.min(...values);
break;
case 'count':
result = values.length;
break;
}
} else {
result = data.length;
}
return {
content: [
{
type: 'text',
text: `${operation} result: ${result}`
}
]
};
}
};
Register in src/index.ts:
import { dataProcessorTool } from './tools/data-processor.js';
server.registerTool(
dataProcessorTool.name,
dataProcessorTool.description,
dataProcessorTool.inputSchema.shape,
dataProcessorTool.handler
);
Handling Resources
Resources represent readable data entities exposed by the server.
Example: File Reader Resource
Create src/resources/file-reader.ts:
import { z } from 'zod';
import { promises as fs } from 'fs';
import * as path from 'path';
export const fileReaderResource = {
uri: 'file://workspace',
name: 'workspace-files',
description: 'Read files in the workspace',
mimeType: 'text/plain',
handler: async (uri: string) => {
// Parse URI, for example file://workspace/path/to/file.txt
const filePath = uri.replace('file://workspace', '');
const fullPath = path.resolve(process.cwd(), filePath);
try {
const content = await fs.readFile(fullPath, 'utf-8');
return {
contents: [
{
uri,
mimeType: 'text/plain',
text: content
}
]
};
} catch (error) {
return {
contents: [
{
uri,
mimeType: 'text/plain',
text: `Cannot read file: ${error instanceof Error ? error.message : String(error)}`
}
]
};
}
}
};
Register the resource in src/index.ts:
import { fileReaderResource } from './resources/file-reader.js';
// Register file reader resource
server.registerResource(
fileReaderResource.uri,
{
name: fileReaderResource.name,
description: fileReaderResource.description,
mimeType: fileReaderResource.mimeType
},
fileReaderResource.handler
);
Adding Prompts
Prompts are predefined templates that can be quickly called as slash commands.
Example: Code Review Prompt
Create src/prompts/code-review.ts:
import { z } from 'zod';
export const codeReviewPrompt = {
name: 'code-review',
description: 'Perform comprehensive code review',
arguments: {
filePath: z.string().describe('File path to review'),
focus: z.enum(['security', 'performance', 'style', 'all']).optional().describe('Review focus')
},
handler: async ({ filePath, focus = 'all' }) => {
const focusText = focus === 'all' ? 'comprehensive' : focus;
return {
messages: [
{
role: 'user',
content: {
type: 'text',
text: `Please perform ${focusText} code review on file ${filePath}. Please check the following aspects:
${focus === 'all' || focus === 'security' ? '- Security vulnerabilities and potential risks\n' : ''}
${focus === 'all' || focus === 'performance' ? '- Performance optimization opportunities\n' : ''}
${focus === 'all' || focus === 'style' ? '- Code style and best practices\n' : ''}
${focus === 'all' ? '- Error handling and edge cases\n- Code readability and maintainability\n' : ''}
Please provide specific improvement suggestions and code examples.`
}
}
]
};
}
};
Register the prompt in src/index.ts:
import { codeReviewPrompt } from './prompts/code-review.js';
// Register code review prompt
server.registerPrompt(
codeReviewPrompt.name,
{
title: 'Code Review',
description: codeReviewPrompt.description,
arguments: codeReviewPrompt.arguments
},
codeReviewPrompt.handler
);
Building and Packaging
Building Project
npm run build
This will generate compiled JavaScript files in the dist/ directory.
Testing Local Server
# Run directly with ts-node
npm run dev
# Or build then run
npm run build
npm start
Creating Docker Image (Optional)
Create Dockerfile:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist ./dist
CMD ["node", "dist/index.js"]
Build and push image:
# Build image
docker build -t codely-mcp-server:latest .
# Run container for testing
docker run -i --rm codely-mcp-server:latest
# Push to image registry
docker tag codely-mcp-server:latest your-registry/codely-mcp-server:latest
docker push your-registry/codely-mcp-server:latest
Testing Server
Manual Testing
Test using mcp-client-cli or directly via stdin/stdout:
# Send request
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/index.js
Testing via Codely CLI
Add the server to settings.json:
{
"mcpServers": {
"codely": {
"command": "node",
"args": ["/path/to/codely-mcp-server/dist/index.js"],
"trust": true
}
}
}
- Restart Codely CLI
- Verify connection:
/mcp list
- Test tools:
Calculate the sum of 123 and 456
Deployment Options
Option 1: Local Installation
Install the server to user's system:
# Global installation
npm install -g /path/to/codely-mcp-server
# Or use npm link for development
cd /path/to/codely-mcp-server
npm link
Configure in settings.json:
{
"mcpServers": {
"codely": {
"command": "codely-mcp"
}
}
}
Option 2: Docker Deployment
{
"mcpServers": {
"codely": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"your-registry/codely-mcp-server:latest"
]
}
}
}
Option 3: Remote HTTP/SSE Service
Deploy the server to cloud services and expose via HTTP or SSE:
{
"mcpServers": {
"codely": {
"httpUrl": "https://mcp.your-domain.com/codely",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}
Appendix
Complete Example Server
Below is a complete example of the src/index.ts file:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
import { calculatorTool } from './tools/calculator.js';
import { dataProcessorTool } from './tools/data-processor.js';
import { fileReaderResource } from './resources/file-reader.js';
import { codeReviewPrompt } from './prompts/code-review.js';
// Create server instance
const server = new McpServer({
name: 'codely-mcp-server',
version: '1.0.0',
});
// Register tools
server.registerTool(
calculatorTool.name,
calculatorTool.description,
calculatorTool.inputSchema.shape,
calculatorTool.handler
);
server.registerTool(
dataProcessorTool.name,
dataProcessorTool.description,
dataProcessorTool.inputSchema.shape,
dataProcessorTool.handler
);
// Register resources
server.registerResource(
fileReaderResource.uri,
{
name: fileReaderResource.name,
description: fileReaderResource.description,
mimeType: fileReaderResource.mimeType
},
fileReaderResource.handler
);
// Register prompts
server.registerPrompt(
codeReviewPrompt.name,
{
title: 'Code Review',
description: codeReviewPrompt.description,
arguments: codeReviewPrompt.arguments
},
codeReviewPrompt.handler
);
// Start server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('Tuanjie AI MCP Server running on stdio');
}
main().catch((error) => {
console.error('Fatal error in main():', error);
process.exit(1);
});
Best Practices
- Error handling: Always provide clear error messages
- Input validation: Use Zod schema to strictly validate input
- Logging: Use console.error to log debug information
- Timeout handling: Set reasonable timeouts for long operations
- Security considerations: Never output sensitive information in logs
- Comprehensive documentation: Provide clear descriptions for each tool, resource, and prompt
Document Version: 1.0.0 Last Updated: March 24, 2026