Netskope NPA MCP Server
A Model Context Protocol (MCP) server for managing Netskope Network Private Access (NPA) infrastructure through Large Language Models (LLMs).
Installation
Option 1: NPM Package
Install the package using npm:
npm install @johnneerdael/netskope-mcp
Option 2: Local Development
Clone the repository and install dependencies:
git clone https://github.com/johnneerdael/netskope-mcp.git
cd netskope-mcp
npm install
npm run build
MCP Configuration
Add the following configuration to your MCP settings file:
Windows with WSL
For NPM installation:
{
"mcpServers": {
"netskope-mcp": {
"command": "wsl.exe",
"args": [
"bash",
"-c",
"source ~/.nvm/nvm.sh && NETSKOPE_BASE_URL=https://your-tenant.goskope.com NETSKOPE_API_KEY=your-token npx -y @johnneerdael/netskope-mcp"
]
}
}
}
For local development:
{
"mcpServers": {
"netskope-mcp": {
"command": "wsl.exe",
"args": [
"bash",
"-c",
"cd /path/to/netskope-mcp && NETSKOPE_BASE_URL=https://your-tenant.goskope.com NETSKOPE_API_KEY=your-token node dist/cli.js"
]
}
}
}
Linux and macOS
For NPM installation:
{
"mcpServers": {
"netskope-mcp": {
"command": "npx",
"args": ["-y", "@johnneerdael/netskope-mcp"],
"env": {
"NETSKOPE_BASE_URL": "https://your-tenant.goskope.com",
"NETSKOPE_API_KEY": "your-token"
}
}
}
}
For local development:
{
"mcpServers": {
"netskope-mcp": {
"command": "node",
"args": ["dist/cli.js"],
"cwd": "/path/to/netskope-mcp",
"env": {
"NETSKOPE_BASE_URL": "https://your-tenant.goskope.com",
"NETSKOPE_API_KEY": "your-token"
}
}
}
}
Environment Variables
NETSKOPE_BASE_URL
: Your Netskope tenant URL (e.g., https://your-tenant.goskope.com)NETSKOPE_API_KEY
: Your Netskope API token
Available Tools and Example Usage
Command Usage Examples
// For NPM package installation
import { NetskopeClient } from '@johnneerdael/netskope-mcp';
// For local development
// import { NetskopeClient } from './dist/mcp.js';
async function examples() {
const mcp = new NetskopeClient({});
try {
// Publishers
const publisherResult = await mcp.createPublisher("web-publisher");
const publisher = JSON.parse(publisherResult.content[0].text).data;
const updatedPublisherResult = await mcp.updatePublisher(publisher.id, "web-publisher-updated", true);
const publisherDetails = await mcp.getPublisher(publisher.id);
const allPublishers = await mcp.listPublishers();
const regToken = await mcp.generateRegistrationToken(publisher.id);
// Local Brokers
const brokerResult = await mcp.createLocalBroker("edge-broker");
const broker = JSON.parse(brokerResult.content[0].text).data;
const brokerDetails = await mcp.getLocalBroker(broker.id);
await mcp.updateLocalBroker(broker.id, "edge-broker-updated");
const allBrokers = await mcp.listLocalBrokers();
const brokerConfig = await mcp.getLocalBrokerConfig();
await mcp.updateLocalBrokerConfig({
hostname: "edge.internal"
});
// Private Apps
const app = await mcp.createPrivateApp("internal-web", "web.internal", [
{ type: 'tcp', port: 80 },
{ type: 'udp', port: 53 }
]);
// Policy Rules
const rule = await mcp.createPolicyRule("allow-internal", "default-group");
// Complex Workflow: Publisher with Scheduled Updates
// 1. Create publisher
const prodPublisherResult = await mcp.createPublisher("prod-publisher");
const prodPublisher = JSON.parse(prodPublisherResult.content[0].text).data;
// 2. Create upgrade profile for Sunday night beta updates
const upgradeProfileResult = await mcp.createUpgradeProfile("weekend-beta-updates", {
enabled: true,
frequency: "0 0 * * 0", // Every Sunday at midnight
timezone: "US/Pacific",
release_type: "Beta"
});
const upgradeProfile = JSON.parse(upgradeProfileResult.content[0].text).data;
// 3. Link publisher to upgrade profile
await mcp.updatePublisher(
prodPublisher.id,
prodPublisher.name,
true,
upgradeProfile.id
);
} catch (error) {
console.error('Error:', error);
throw error;
}
}
Publisher Management
Tools for managing NPA publishers that handle private application access.
Schema Reference
// Create Publisher
{
name: string,
lbrokerconnect?: boolean,
publisher_upgrade_profiles_id?: number
}
// Update Publisher
{
id: number,
name: string,
lbrokerconnect?: boolean,
publisher_upgrade_profiles_id?: number
}
Local Broker Configuration
Tools for managing local broker settings for improved connectivity.
Schema Reference
// Create Local Broker
{
name: string
}
// Update Local Broker Config
{
hostname: string
}
Private Apps Management
Tools for managing private applications published through NPA.
Schema Reference
// Create Private App
{
app_name: string,
host: string,
clientless_access: boolean,
is_user_portal_app: boolean,
protocols: Array<{
port: string,
type: 'tcp' | 'udp'
}>,
publishers: Array<{
publisher_id: string,
publisher_name: string
}>,
trust_self_signed_certs: boolean,
use_publisher_dns: boolean,
allow_unauthenticated_cors?: boolean,
allow_uri_bypass?: boolean,
bypass_uris?: string[],
real_host?: string,
app_option?: Record<string, unknown>
}
Policy Management
Tools for managing NPA access policies and policy groups.
Schema Reference
// Create Policy Rule
{
name: string,
description?: string,
enabled: boolean,
action: 'allow' | 'block',
policy_group_id: number,
priority: number,
conditions: Array<{
type: 'private_app' | 'user' | 'group' | 'organization_unit' | 'location' | 'device',
operator: 'in' | 'not_in' | 'equals' | 'not_equals' | 'contains' | 'not_contains' | 'starts_with' | 'ends_with',
value: string | number | string[] | number[]
}>
}
Upgrade Profile Management
Tools for managing automatic upgrade schedules for NPA publishers.
Schema Reference
// Create/Update Upgrade Profile
{
name: string,
enabled: boolean,
docker_tag: string,
frequency: string, // cron format (e.g., "0 0 * * 0" for Sunday midnight)
timezone: "US/Pacific" | "US/Eastern" | ... // See timezoneSchema for all options
release_type: "Beta" | "Latest" | "Latest-1" | "Latest-2"
}
Response Handling
All API responses follow this pattern:
{
content: [{
type: "text",
text: string // JSON stringified response
}]
}
To handle responses:
const result = await mcp.someOperation(params);
const data = JSON.parse(result.content[0].text);
if (data.status !== 'success') {
throw new Error(data.message || 'Operation failed');
}
return data.data; // The actual response data
Error Handling
The server provides detailed error messages in the response. Common error scenarios:
- Authentication failures (invalid API key)
- Invalid request parameters
- Resource not found
- Rate limiting
- Network connectivity issues
Example error handling:
try {
const result = await mcp.someOperation(params);
const data = JSON.parse(result.content[0].text);
if (data.status !== 'success') {
throw new Error(data.message || 'Operation failed');
}
return data.data;
} catch (error) {
if (error instanceof Error) {
throw new Error(`Operation failed: ${error.message}`);
}
throw error;
}
Best Practices
- Always parse and check response status
- Use proper error handling with try/catch blocks
- Follow the principle of least privilege when creating policies
- Document any custom configurations or policies
- Test changes in a non-production environment first
- Monitor publisher health and status regularly
- Keep registration tokens secure and rotate them periodically
Security Considerations
- Store API keys securely
- Use environment variables for sensitive configuration
- Implement proper access controls
- Monitor and audit policy changes
- Regularly review and update security policies
- Follow the principle of least privilege
- Keep the server and dependencies updated
Support
For issues and feature requests, please create an issue in the repository.