MCP Server Security & Integration

Security analysis and best practices for Model Context Protocol (MCP) servers with Cursor IDE.

Table of contents

  1. What is MCP?
    1. MCP Architecture
    2. Why MCP Matters for Security
  2. Available MCP Servers for Cursor
    1. GitHub MCP Server
    2. Azure DevOps MCP Server
    3. File System MCP Server
    4. Database MCP Server
  3. MCP Transport Security
    1. Transport Options
    2. Recommended: stdio Transport
    3. When to Use HTTP/SSE
  4. Custom MCP Server Development
    1. Security Checklist for Custom MCP Servers
    2. Example: Secure MCP Server Template
  5. MCP Server Approval Process
    1. Evaluation Checklist
  6. Monitoring MCP Server Usage
    1. Azure Monitor Integration
    2. Alerting Rules
  7. Best Practices Summary
    1. DO ✅
    2. DON’T ❌
  8. Next Steps

What is MCP?

Model Context Protocol (MCP) is an open protocol that allows AI assistants like Cursor to connect to external tools and data sources. Think of it as a secure API for AI agents.

MCP Architecture

graph LR
    A[Cursor IDE] -->|stdio/HTTP/SSE| B[MCP Server]
    B -->|API Calls| C[External Service]
    
    subgraph "Examples"
        C1[GitHub API]
        C2[Azure DevOps]
        C3[Database]
        C4[File System]
    end
    
    C --> C1
    C --> C2
    C --> C3
    C --> C4
    
    style B fill:#7c3aed,stroke:#5b21b6,color:#fff
    style C fill:#0066cc,stroke:#003d7a,color:#fff

Why MCP Matters for Security

Security Implication: MCP servers can access external systems on behalf of the AI. Misconfigured servers can lead to data leakage, unauthorized access, or privilege escalation.


Available MCP Servers for Cursor

GitHub MCP Server

Repository: avinashsvinu/mcp-for-github-using-cursor

Capabilities:

  • Create/update repositories
  • Search issues and pull requests
  • Manage branches
  • Create/review pull requests

Security Assessment:

Criteria Rating Notes
Authentication ⭐⭐⭐⭐ Uses GitHub PAT (Personal Access Token)
Authorization ⭐⭐⭐ Limited by token scope, but no fine-grained control
Audit Logging ⭐⭐⭐⭐ GitHub audit log captures all actions
Secret Management ⚠️ ⭐⭐ PAT must be securely stored
Network Security ⭐⭐⭐⭐⭐ HTTPS only, public GitHub endpoints

Recommended Configuration:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "mcpServers": {
    "github": {
      "command": "node",
      "args": ["/path/to/mcp-github-server.js"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_PAT}",  // From Key Vault
        "GITHUB_ORG": "your-org"
      },
      "transport": "stdio"
    }
  }
}

Security Hardening:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Create fine-grained GitHub PAT with minimal scope
# Navigate to: GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens

# Recommended scopes:
- repositories: read, write (specific repos only)
- metadata: read
- issues: read, write
- pull_requests: read, write

# Store in Key Vault
az keyvault secret set \
  --vault-name kv-cursor-secrets \
  --name github-mcp-token \
  --value "github_pat_..."

# Rotate token monthly

Azure DevOps MCP Server

Repository: maximtitovich/cursor-azure-devops-mcp

Capabilities:

  • Query work items
  • Create/update tasks
  • Access build pipelines
  • Manage repositories

Security Assessment:

Criteria Rating Notes
Authentication ⭐⭐⭐⭐⭐ Azure Entra ID or PAT
Authorization ⭐⭐⭐⭐ Azure RBAC integration
Audit Logging ⭐⭐⭐⭐⭐ Full Azure DevOps audit log
Secret Management ⭐⭐⭐⭐ Azure Key Vault integration
Network Security ⭐⭐⭐⭐⭐ Private endpoints supported

Recommended Configuration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "mcpServers": {
    "azure-devops": {
      "command": "node",
      "args": ["/path/to/azure-devops-mcp.js"],
      "env": {
        "AZURE_DEVOPS_ORG": "your-org",
        "AZURE_DEVOPS_PROJECT": "your-project",
        "AZURE_DEVOPS_PAT": "${AZURE_DEVOPS_PAT}"  // From Key Vault
      },
      "transport": "stdio"
    }
  }
}

Why Azure DevOps MCP is More Secure:

  • Native Azure integration
  • RBAC at resource level
  • Private endpoint support
  • Entra ID authentication option

File System MCP Server

Use Case: Allow Cursor AI to read project documentation, analyze logs

Security Assessment:

Criteria Rating Recommendation
Access Control ⚠️ ⭐⭐ Restrict to specific directories
Secret Exposure Risk ⚠️ ⭐ High risk if misconfigured
Audit Logging ⭐⭐ Limited native auditing

Secure Configuration Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "mcpServers": {
    "filesystem": {
      "command": "node",
      "args": ["/path/to/fs-mcp-server.js"],
      "env": {
        "ALLOWED_PATHS": "/workspace/docs,/workspace/public",  // Whitelist only
        "BLOCKED_PATTERNS": "*.env,*.key,*.pem,secrets/*"     // Explicit blocks
      },
      "transport": "stdio"
    }
  }
}

Risk: File system MCP servers can inadvertently expose secrets if not carefully configured. Always use explicit allowlists and blocklists.


Database MCP Server

Use Case: Query databases for data analysis, schema understanding

Security Assessment:

Criteria Rating Critical Concerns
Data Exposure ⚠️ ⭐ Can expose sensitive customer data
SQL Injection ⚠️ ⭐⭐ Risk if queries not parameterized
Audit Logging ⭐⭐⭐ Depends on database audit capabilities

Recommended Approach:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "mcpServers": {
    "database": {
      "command": "node",
      "args": ["/path/to/db-mcp-server.js"],
      "env": {
        "DB_TYPE": "read-replica",           // Read-only database
        "DB_CONNECTION_STRING": "${DB_RO}",  // From Key Vault
        "ALLOWED_SCHEMAS": "public,analytics",  // Limit schemas
        "MAX_ROWS": "100",                   // Limit result size
        "QUERY_TIMEOUT": "5000"              // 5 second timeout
      },
      "transport": "stdio"
    }
  }
}

NEVER connect MCP servers to production write databases. Use read-only replicas in non-production environments only.


MCP Transport Security

Transport Options

Transport Security Use Case
stdio ⭐⭐⭐⭐ Local process, no network exposure
SSE (Server-Sent Events) ⭐⭐⭐ HTTP-based, requires TLS
HTTP ⭐⭐⭐ Request/response, requires TLS + auth

Why stdio is Most Secure:

  • No network exposure
  • Process-level isolation
  • OS-level permissions apply
  • No authentication complexity

Example:

1
2
3
4
5
6
7
8
9
{
  "mcpServers": {
    "github": {
      "command": "node",
      "args": ["/usr/local/lib/mcp-servers/github-server.js"],
      "transport": "stdio"  // Most secure option
    }
  }
}

When to Use HTTP/SSE

Use HTTP/SSE only when:

  • MCP server must run on different machine
  • Need to share MCP server across team
  • Require load balancing

Secure HTTP Configuration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "mcpServers": {
    "shared-github": {
      "url": "https://mcp.yourcompany.com/github",
      "transport": "https",
      "authentication": {
        "type": "bearer",
        "token": "${MCP_AUTH_TOKEN}"  // From Key Vault
      },
      "tls": {
        "minVersion": "TLSv1.3",
        "certificate": "/path/to/client-cert.pem"
      }
    }
  }
}

Custom MCP Server Development

Security Checklist for Custom MCP Servers

When building your own MCP server:

  • Input Validation: Validate all AI requests
  • Output Sanitization: Remove sensitive data from responses
  • Authentication: Require authentication for all operations
  • Authorization: Implement least-privilege access
  • Rate Limiting: Prevent abuse
  • Audit Logging: Log all operations
  • Error Handling: Don’t leak sensitive info in errors
  • Secret Management: Never hardcode credentials
  • Dependency Security: Keep libraries updated

Example: Secure MCP Server Template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// secure-mcp-server.ts
import { MCPServer } from '@modelcontextprotocol/sdk';

const server = new MCPServer({
  name: 'secure-azure-mcp',
  version: '1.0.0'
});

// 1. Authentication middleware
server.use(async (req, res, next) => {
  const token = req.headers['authorization']?.replace('Bearer ', '');
  
  // Verify token with Azure Entra ID
  const isValid = await verifyEntraIDToken(token);
  if (!isValid) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  
  next();
});

// 2. Rate limiting
server.use(rateLimit({
  windowMs: 60 * 1000,  // 1 minute
  max: 100  // 100 requests per minute
}));

// 3. Audit logging
server.use(async (req, res, next) => {
  await logToAzureMonitor({
    operation: req.body.operation,
    user: req.user.id,
    timestamp: new Date().toISOString()
  });
  next();
});

// 4. Tool implementation with validation
server.addTool({
  name: 'query-database',
  description: 'Query read-only database',
  parameters: {
    query: { type: 'string', required: true }
  },
  handler: async (params) => {
    // Input validation
    if (!isValidSQL(params.query)) {
      throw new Error('Invalid SQL query');
    }
    
    // Execute with parameterization
    const result = await executeReadOnlyQuery(params.query);
    
    // Output sanitization
    return sanitizeOutput(result);
  }
});

server.listen(stdio());

MCP Server Approval Process

Evaluation Checklist

Before approving an MCP server for use:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
## MCP Server Security Review

**Server Name**: [name]
**Repository**: [URL]
**Version**: [version]
**Requested By**: [developer]
**Review Date**: [date]

### 1. Source Code Review
- [ ] Source code available and reviewed
- [ ] No obvious security vulnerabilities
- [ ] Dependencies scanned for CVEs
- [ ] Last updated within 6 months

### 2. Authentication & Authorization
- [ ] Requires authentication
- [ ] Supports least-privilege access
- [ ] Token/credential management documented
- [ ] No hardcoded secrets

### 3. Data Handling
- [ ] Input validation implemented
- [ ] Output sanitization implemented
- [ ] No sensitive data in logs
- [ ] Respects data classification

### 4. Network Security
- [ ] Transport encryption (TLS 1.3)
- [ ] No unnecessary network access
- [ ] Supports private endpoints (if applicable)
- [ ] Rate limiting implemented

### 5. Audit & Monitoring
- [ ] Operation logging implemented
- [ ] Logs sent to central SIEM
- [ ] Error handling doesn't leak info
- [ ] Supports Azure Monitor integration

### 6. Testing
- [ ] Tested in isolated environment
- [ ] Security testing performed
- [ ] No data leakage observed
- [ ] Performance acceptable

### Decision
- [ ] **APPROVED** - Deploy to pilot group
- [ ] **APPROVED WITH CONDITIONS** - [List conditions]
- [ ] **REJECTED** - [List reasons]

**Reviewer**: [name]
**Date**: [date]

Monitoring MCP Server Usage

Azure Monitor Integration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Create Log Analytics queries for MCP monitoring

# Query 1: MCP server usage by operation
MCPServerLogs
| where TimeGenerated > ago(24h)
| summarize Count = count() by Operation, ServerName
| order by Count desc

# Query 2: Failed MCP operations
MCPServerLogs
| where TimeGenerated > ago(24h)
| where ResultType != "Success"
| project TimeGenerated, ServerName, Operation, ErrorMessage, User
| order by TimeGenerated desc

# Query 3: Unusual MCP activity
MCPServerLogs
| where TimeGenerated > ago(7d)
| summarize RequestCount = count() by User, bin(TimeGenerated, 1h)
| where RequestCount > 100  // Threshold for unusual activity
| order by TimeGenerated desc

Alerting Rules

1
2
3
4
5
6
7
8
9
10
11
12
# Create alert for excessive MCP failures
az monitor scheduled-query create \
  --name alert-mcp-high-failure-rate \
  --resource-group rg-cursor-ai-research \
  --scopes /subscriptions/{sub-id}/resourceGroups/rg-cursor-ai-research/providers/Microsoft.OperationalInsights/workspaces/law-cursor-audit \
  --condition "count > 10" \
  --condition-query "MCPServerLogs | where ResultType != 'Success' | summarize count()" \
  --description "Alert when MCP server failure rate exceeds threshold" \
  --evaluation-frequency 5m \
  --window-size 15m \
  --severity 2 \
  --action-groups ag-cursor-security-team

Best Practices Summary

DO ✅

  • Use stdio transport when possible
  • Store MCP credentials in Key Vault
  • Implement comprehensive audit logging
  • Use read-only access where possible
  • Rate limit MCP operations
  • Regularly review MCP server access logs
  • Keep MCP server dependencies updated

DON’T ❌

  • Connect to production write databases
  • Hardcode credentials in MCP configurations
  • Allow unrestricted file system access
  • Use MCP servers from untrusted sources
  • Skip security reviews for custom servers
  • Expose MCP servers on public internet

Next Steps

Explore detailed MCP documentation:


Last Updated: October 10, 2025
Status: Security Reviewed


Table of contents