VS Code Configuration
This guide shows you how to configure the Probo MCP Server with Visual Studio Code, enabling AI assistants like GitHub Copilot, Continue.dev, and other extensions to interact with your compliance data.
Prerequisites
Section titled “Prerequisites”- Visual Studio Code installed
- A running Probo instance with API access
- API token from your Probo instance
- An AI assistant extension (GitHub Copilot, Continue.dev, etc.)
Configuration Methods
Section titled “Configuration Methods”VS Code doesn’t natively support MCP, but you can integrate Probo through:
- Continue.dev Extension (Recommended) - Open-source AI assistant with MCP support
- GitHub Copilot with Custom Tools - Integration via custom endpoints
- Custom Extension - Build your own VS Code extension
Method 1: Continue.dev Extension
Section titled “Method 1: Continue.dev Extension”Continue.dev is an open-source AI coding assistant that supports MCP.
Installation
Section titled “Installation”- Install Continue.dev from VS Code Marketplace
- Open VS Code
- Press Ctrl+Shift+P (Cmd+Shift+P on macOS)
- Type “Continue: Install”
Configuration
Section titled “Configuration”-
Generate API Token from your Probo instance
-
Locate Continue Config File:
macOS/Linux:
Terminal window ~/.continue/config.jsonWindows:
Terminal window %USERPROFILE%\.continue\config.json -
Configure MCP Server:
{"models": [{"title": "Claude 3.5 Sonnet","provider": "anthropic","model": "claude-3-5-sonnet-20241022","apiKey": "your_anthropic_api_key"}],"mcpServers": {"probo": {"url": "https://your-probo-instance.com/api/mcp/v1","headers": {"Authorization": "Bearer your_api_token_here"}}},"embeddingsProvider": {"provider": "openai","model": "text-embedding-3-small","apiKey": "your_openai_api_key"}} -
Reload VS Code (Ctrl+Shift+P → “Developer: Reload Window”)
Usage with Continue.dev
Section titled “Usage with Continue.dev”Open Continue panel (Ctrl+L or Cmd+L) and interact with Probo:
You: "List all high-priority risks from Probo"
Continue: Let me fetch that from Probo.[Uses listRisks tool]
Here are the high-priority risks:1. Vendor data breach (Score: 20)2. Access control gaps (Score: 18)...Method 2: Custom VS Code Extension
Section titled “Method 2: Custom VS Code Extension”Create a custom extension to integrate Probo MCP.
Extension Setup
Section titled “Extension Setup”- Create Extension Scaffold:
npm install -g yo generator-codeyo code- Install Dependencies:
cd your-extensionnpm install @modelcontextprotocol/sdk axios- Create Probo Client (
src/proboClient.ts):
import * as vscode from 'vscode';import axios from 'axios';
export class ProboClient { private baseURL: string; private token: string;
constructor() { const config = vscode.workspace.getConfiguration('probo'); this.baseURL = config.get('apiUrl') || 'https://your-probo-instance.com/api/mcp'; this.token = config.get('apiToken') || ''; }
async callTool(toolName: string, params: any): Promise<any> { try { const response = await axios.post( `${this.baseURL}/tools/${toolName}`, params, { headers: { 'Authorization': `Bearer ${this.token}`, 'Content-Type': 'application/json' } } ); return response.data; } catch (error) { vscode.window.showErrorMessage(`Probo API error: ${error}`); throw error; } }
async listRisks(organizationId: string) { return this.callTool('listRisks', { organization_id: organizationId }); }
async listVendors(organizationId: string) { return this.callTool('listVendors', { organization_id: organizationId }); }
async addVendor(organizationId: string, name: string, description?: string) { return this.callTool('addVendor', { organization_id: organizationId, name, description }); }
// Add more methods for other tools...}- Create Commands (
src/extension.ts):
import * as vscode from 'vscode';import { ProboClient } from './proboClient';
export function activate(context: vscode.ExtensionContext) { const probo = new ProboClient();
// Command: List Risks let listRisks = vscode.commands.registerCommand('probo.listRisks', async () => { const orgId = await vscode.window.showInputBox({ prompt: 'Enter Organization ID', placeHolder: 'org_xxx' });
if (!orgId) return;
try { const risks = await probo.listRisks(orgId); const panel = vscode.window.createWebviewPanel( 'proboRisks', 'Probo Risks', vscode.ViewColumn.One, {} );
panel.webview.html = generateRisksHTML(risks); } catch (error) { vscode.window.showErrorMessage(`Failed to fetch risks: ${error}`); } });
// Command: Add Vendor let addVendor = vscode.commands.registerCommand('probo.addVendor', async () => { const orgId = await vscode.window.showInputBox({ prompt: 'Enter Organization ID' }); const name = await vscode.window.showInputBox({ prompt: 'Enter Vendor Name' }); const description = await vscode.window.showInputBox({ prompt: 'Enter Description (optional)' });
if (!orgId || !name) return;
try { await probo.addVendor(orgId, name, description); vscode.window.showInformationMessage(`Vendor "${name}" added successfully!`); } catch (error) { vscode.window.showErrorMessage(`Failed to add vendor: ${error}`); } });
context.subscriptions.push(listRisks, addVendor);}
function generateRisksHTML(risks: any): string { return ` <!DOCTYPE html> <html> <head> <style> body { font-family: var(--vscode-font-family); padding: 20px; } .risk { border: 1px solid var(--vscode-panel-border); padding: 10px; margin: 10px 0; border-radius: 5px; } .high-risk { border-left: 4px solid red; } </style> </head> <body> <h1>Risks</h1> ${risks.risks.map((risk: any) => ` <div class="risk ${risk.residual_risk_score > 15 ? 'high-risk' : ''}"> <h3>${risk.name}</h3> <p><strong>Score:</strong> ${risk.residual_risk_score}</p> <p><strong>Treatment:</strong> ${risk.treatment}</p> <p>${risk.description || 'No description'}</p> </div> `).join('')} </body> </html> `;}
export function deactivate() {}- Configure Settings (
package.json):
{ "name": "probo-vscode", "displayName": "Probo Compliance", "description": "Manage compliance data from VS Code", "version": "1.0.0", "engines": { "vscode": "^1.80.0" }, "categories": ["Other"], "activationEvents": ["onCommand:probo.listRisks"], "main": "./out/extension.js", "contributes": { "commands": [ { "command": "probo.listRisks", "title": "Probo: List Risks" }, { "command": "probo.listVendors", "title": "Probo: List Vendors" }, { "command": "probo.addVendor", "title": "Probo: Add Vendor" } ], "configuration": { "title": "Probo", "properties": { "probo.apiUrl": { "type": "string", "default": "https://your-probo-instance.com/api/mcp", "description": "Probo API URL" }, "probo.apiToken": { "type": "string", "default": "", "description": "Probo API Token" } } } }}- Build and Run:
npm installnpm run compile# Press F5 to run extension in debug modeMethod 3: GitHub Copilot Integration
Section titled “Method 3: GitHub Copilot Integration”While GitHub Copilot doesn’t directly support MCP, you can create a bridge.
Local API Bridge
Section titled “Local API Bridge”- Create a Local Server (
probo-bridge.js):
const express = require('express');const axios = require('axios');
const app = express();app.use(express.json());
const PROBO_URL = process.env.PROBO_URL || 'https://your-probo-instance.com/api/mcp';const PROBO_TOKEN = process.env.PROBO_TOKEN;
app.post('/api/:tool', async (req, res) => { try { const response = await axios.post( `${PROBO_URL}/tools/${req.params.tool}`, req.body, { headers: { 'Authorization': `Bearer ${PROBO_TOKEN}`, 'Content-Type': 'application/json' } } ); res.json(response.data); } catch (error) { res.status(500).json({ error: error.message }); }});
app.listen(3000, () => { console.log('Probo bridge running on http://localhost:3000');});- Start the Bridge:
export PROBO_URL=https://your-probo-instance.com/api/mcpexport PROBO_TOKEN=your_token_herenode probo-bridge.js- Use in VS Code:
Create helper functions that use the bridge:
async function getProboRisks(organizationId) { const response = await fetch('http://localhost:3000/api/listRisks', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ organization_id: organizationId }) }); return await response.json();}
// Use with Copilot chat// "Generate a dashboard using risks from Probo"Workspace Configuration
Section titled “Workspace Configuration”Create project-specific settings in .vscode/settings.json:
{ "probo.apiUrl": "${env:PROBO_PROJECT_URL}", "probo.apiToken": "${env:PROBO_PROJECT_TOKEN}", "probo.defaultOrganization": "org_xxx"}Set environment variables in .env:
PROBO_PROJECT_URL=https://project.probo.com/api/mcpPROBO_PROJECT_TOKEN=your_project_tokenCode Snippets
Section titled “Code Snippets”Create compliance-aware snippets in .vscode/probo.code-snippets:
{ "Probo Risk Comment": { "prefix": "probo-risk", "body": [ "// RISK: ${1:Risk Description}", "// Probo Risk ID: ${2:R-XXX}", "// Severity: ${3|LOW,MEDIUM,HIGH,CRITICAL|}", "// Mitigation: ${4:Control measures}", "$0" ], "description": "Add Probo risk annotation" }, "Fetch Probo Data": { "prefix": "probo-fetch", "body": [ "async function fetch${1:Entity}FromProbo(organizationId: string) {", " const response = await fetch('http://localhost:3000/api/list${1:Entity}', {", " method: 'POST',", " headers: { 'Content-Type': 'application/json' },", " body: JSON.stringify({ organization_id: organizationId })", " });", " return await response.json();", "}" ], "description": "Generate Probo data fetch function" }}Tasks and Automation
Section titled “Tasks and Automation”Define tasks in .vscode/tasks.json:
{ "version": "2.0.0", "tasks": [ { "label": "Fetch Compliance Status", "type": "shell", "command": "node", "args": ["scripts/fetch-compliance.js"], "problemMatcher": [], "presentation": { "reveal": "always", "panel": "new" } }, { "label": "Generate Compliance Report", "type": "shell", "command": "node", "args": ["scripts/compliance-report.js"], "problemMatcher": [] } ]}Keyboard Shortcuts
Section titled “Keyboard Shortcuts”Add custom keybindings in keybindings.json:
[ { "key": "ctrl+shift+p r", "command": "probo.listRisks", "when": "editorTextFocus" }, { "key": "ctrl+shift+p v", "command": "probo.listVendors", "when": "editorTextFocus" }]Example Scripts
Section titled “Example Scripts”Compliance Status Dashboard
Section titled “Compliance Status Dashboard”const { ProboClient } = require('./probo-client');
async function generateDashboard() { const probo = new ProboClient(); const orgId = process.env.PROBO_ORG_ID;
const [risks, measures, obligations] = await Promise.all([ probo.listRisks(orgId), probo.listMeasures(orgId), probo.listObligations(orgId) ]);
console.log('=== Compliance Dashboard ==='); console.log(`Total Risks: ${risks.risks.length}`); console.log(`High Priority: ${risks.risks.filter(r => r.residual_risk_score > 15).length}`); console.log(`Implemented Measures: ${measures.measures.filter(m => m.state === 'IMPLEMENTED').length}`); console.log(`Overdue Obligations: ${obligations.obligations.filter(o => new Date(o.due_date) < new Date()).length}`);}
generateDashboard().catch(console.error);Automated Vendor Review Check
Section titled “Automated Vendor Review Check”const { ProboClient } = require('./probo-client');
async function checkVendorReviews() { const probo = new ProboClient(); const orgId = process.env.PROBO_ORG_ID;
const vendors = await probo.listVendors(orgId); const overdueVendors = vendors.vendors.filter(v => { const lastReview = new Date(v.updated_at); const daysSinceReview = (Date.now() - lastReview.getTime()) / (1000 * 60 * 60 * 24); return daysSinceReview > 90; });
if (overdueVendors.length > 0) { console.log('⚠️ Vendors needing review:'); overdueVendors.forEach(v => { console.log(` - ${v.name} (last reviewed ${new Date(v.updated_at).toLocaleDateString()})`); }); } else { console.log('✅ All vendors have been reviewed recently'); }}
checkVendorReviews().catch(console.error);Troubleshooting
Section titled “Troubleshooting”Extension Not Loading
Section titled “Extension Not Loading”- Check VS Code Output panel (View → Output)
- Select your extension from the dropdown
- Look for error messages
API Connection Issues
Section titled “API Connection Issues”Test the connection:
curl -H "Authorization: Bearer YOUR_TOKEN" \ https://your-probo-instance.com/api/mcp/healthEnvironment Variables Not Loading
Section titled “Environment Variables Not Loading”Ensure .env file is in workspace root and install the DotEnv extension.
Security Best Practices
Section titled “Security Best Practices”- Use environment variables for tokens
- Never commit tokens to version control
- Set file permissions:
Terminal window chmod 600 .env - Use VS Code secrets for sensitive data:
await context.secrets.store('probo-token', token);
- Validate all inputs before sending to Probo
- Review generated code before execution
Next Steps
Section titled “Next Steps”- Explore all available MCP tools
- Check out Cursor configuration for similar IDE
- Try Continue.dev for AI assistance
- View the API specification
Support
Section titled “Support”Need help with VS Code integration?