netskope mcp
Provides tools for managing Netskope infrastructure, policies, and steering configurations via the Model Context Protocol.
Provides tools for managing Netskope infrastructure, policies, and steering configurations via the Model Context Protocol.
A Model Context Protocol (MCP) server for managing Netskope Network Private Access (NPA) infrastructure through Large Language Models (LLMs).
Still lots of work needs to be done for all 50 tools to be operational, i strongly advise against using this with any production environment
https://github.com/johnneerdael/netskope-mcp/raw/refs/heads/main/demo.mov
Install the package using npm:
npm install @johnneerdael/netskope-mcp
Clone the repository and install dependencies:
git clone https://github.com/johnneerdael/netskope-mcp.git
cd netskope-mcp
npm install
npm run build
Add the following configuration to your MCP settings file:
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"
]
}
}
}
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"
}
}
}
}
The Netskope NPA MCP Server requires the following environment variables to be configured for proper operation:
https://your-tenant.goskope.com
Note: Must be the complete tenant URL without any path components
NETSKOPE_API_KEY
030f31f7d57fd94834af57a3edc4bbda
export NETSKOPE_BASE_URL="https://dev-tenant.goskope.com"
export NETSKOPE_API_KEY="your-development-token"
export NETSKOPE_BASE_URL="https://prod-tenant.goskope.com"
export NETSKOPE_API_KEY="your-production-token"
{
adminUsers: string[], // Array of admin user emails to notify
eventTypes: string[], // Array of event types to monitor
selectedUsers: string // Additional users to notify
}
UPGRADE_WILL_START
: Notification before a publisher upgrade beginsUPGRADE_STARTED
: Notification when upgrade process initiatesUPGRADE_SUCCEEDED
: Notification upon successful upgrade completionUPGRADE_FAILED
: Notification if upgrade process failsCONNECTION_FAILED
: Notification when publisher connection issues occurUsage Examples:
getAlertConfig
to return the current list of admin users and their notification preferences."getAlertConfig
to ensure the right team members will be notified of upgrade events."getAlertConfig
to show which critical events are being tracked and who receives notifications."updateAlertConfig
{
adminUsers: string[], // Array of admin user emails to receive notifications
eventTypes: string[], // Array of event types to monitor
selectedUsers: string // Additional users to receive notifications
}
fields
: Array of specific fields to return in the response{
status: 'success' | 'not found',
total: number,
data: Array<{
id: number, // Unique identifier for the local broker
name: string, // Display name of the local broker
common_name: string, // Common name used for broker identification
registered: boolean // Registration status of the broker
}>
}
Usage Examples:
createLocalBroker
{
name: string // Name for the new local broker
}
{
status: 'success' | 'not found',
data: {
id: number, // Assigned unique identifier
name: string, // Configured broker name
common_name: string, // Assigned common name
registered: boolean // Initial registration status
}
}
Usage Examples:
getLocalBroker
id
: Numeric identifier of the local broker to retrieve{
status: 'success' | 'not found',
data: {
id: number, // Broker's unique identifier
name: string, // Broker's display name
common_name: string, // Broker's common name
registered: boolean // Current registration status
}
}
Usage Examples:
updateLocalBroker
{
id: number, // Identifier of broker to update
name: string // New name for the broker
}
{
status: 'success' | 'not found',
data: {
id: number, // Broker's identifier
name: string, // Updated broker name
common_name: string, // Broker's common name
registered: boolean // Current registration status
}
}
Usage Examples:
deleteLocalBroker
id
: Numeric identifier of the local broker to delete{
status: 'success' | 'not found'
}
Usage Examples:
getBrokerConfig
{
status: 'success' | 'not found',
data: {
hostname: string // Global hostname configuration
}
}
Usage Examples:
updateBrokerConfig
{
hostname: string // New hostname configuration
}
{
status: 'success' | 'not found',
data: {
hostname: string // Updated hostname configuration
}
}
Usage Examples:
generateLocalBrokerRegistrationToken
id
: Numeric identifier of the local broker{
status: 'success' | 'not found',
data: {
token: string // Generated registration token
}
}
fields
: Array of specific fields to returnfilter
: Filter criteria for the ruleslimit
: Maximum number of rules to returnoffset
: Number of rules to skipsortby
: Field to sort bysortorder
: Sort direction ('asc' or 'desc'){
data: {
rules: Array<{
id: number,
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 | string[] | number | number[]
}>,
created_at: string,
updated_at: string
}>
},
status: 'success' | 'error',
total: number
}
Usage Examples:
getRule
id
: Numeric identifier of the policy rulefields
: Array of specific fields to return{
data: {
id: number,
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 | string[] | number | number[]
}>,
created_at: string,
updated_at: string
},
status: 'success' | 'error'
}
Usage Examples:
createRule
{
name: string, // Rule name
description?: string, // Optional rule description
enabled: boolean, // Rule status
action: 'allow' | 'block', // Access action
policy_group_id: number, // Associated policy group
priority: number, // Rule priority
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 | string[] | number | number[]
}>
}
Usage Examples:
updateRule
id
: Numeric identifier of the rule to updatedata
: Updated rule configuration following the same schema as create_rule{
data: {
// Updated rule details (same as get_rule response)
},
status: 'success' | 'error'
}
Usage Examples:
deleteRule
id
: Numeric identifier of the rule to delete{
status: 'success' | 'error'
}
{
app_name: string, // Name of the private application
host: string, // Host address of the application
clientless_access: boolean, // Enable clientless access
is_user_portal_app: boolean, // Show in user portal
protocols: Array<{
port: string, // Port number
type: 'tcp' | 'udp' // Protocol type
}>,
publisher_tags?: Array<{ // Optional publisher tags
tag_name: string
}>,
publishers: Array<{ // Associated publishers
publisher_id: string,
publisher_name: string
}>,
trust_self_signed_certs: boolean, // Trust self-signed certificates
use_publisher_dns: boolean, // Use publisher DNS
allow_unauthenticated_cors?: boolean, // Optional CORS settings
allow_uri_bypass?: boolean, // Optional URI bypass
bypass_uris?: string[], // Optional bypass URIs
real_host?: string, // Optional real host
app_option?: Record<string, unknown> // Additional options
}
{
data: {
allow_unauthenticated_cors: boolean,
allow_uri_bypass: boolean,
uribypass_header_value: string,
bypass_uris: string[],
app_option: Record<string, unknown>,
clientless_access: boolean,
host: string,
id: number,
is_user_portal_app: boolean,
name: string,
protocols: Array<{
ports: string[],
type: string
}>,
real_host: string,
service_publisher_assignments: Array<{
primary: boolean,
publisher_id: number,
publisher_name: string,
reachability: {
error_code: number,
error_string: string,
reachable: boolean
},
service_id: number
}>,
tags: Array<{
tag_id: number,
tag_name: string
}>,
trust_self_signed_certs: boolean,
use_publisher_dns: boolean
},
status: 'success' | 'not found'
}
Usage Examples:
updatePrivateApp
{
id: number, // Application ID
// All other fields same as create_private_app
}
Usage Examples:
deletePrivateApp
id
: Numeric identifier of the private application{
status: number,
result: string
}
Usage Examples:
getPrivateApp
id
: Numeric identifier of the private applicationUsage Examples:
listPrivateApps
fields
: Specific fields to returnfilter
: Filter criteriaquery
: Search querylimit
: Maximum number of resultsoffset
: Number of results to skip{
data: Array<{
// Same fields as get_private_app response
}>,
status: 'success' | 'not found',
total: number
}
Usage Examples:
getPrivateAppTags
query
: Search query for tagslimit
: Maximum number of tagsoffset
: Number of tags to skip{
data: Array<{
tag_id: number,
tag_name: string
}>,
status: 'success' | 'not found'
}
Usage Examples:
createPrivateAppTags
id
: Application identifiertags
: Array of tag objectsUsage Examples:
updatePrivateAppTags
ids
: Array of application identifierstags
: Array of updated tag objectsUsage Examples:
updatePrivateAppPublishers
{
private_app_ids: string[], // Application IDs
publisher_ids: string[] // Publisher IDs
}
Usage Examples:
deletePrivateAppPublishers
{
private_app_ids: string[], // Application IDs
publisher_ids: string[] // Publisher IDs to remove
}
Usage Examples:
getDiscoverySettings
Usage Examples:
getPolicyInUse
ids
: Array of application identifiersfields
: Specific fields to return in the response{
data: {
publishers: Array<{
apps_count: number,
assessment: {
ca_certs_status: {
hashes: string[],
last_modified: number
},
eee_support: boolean,
hdd_free: string,
hdd_total: string,
ip_address: string,
latency: number,
version: string
},
capabilities: {
DTLS: boolean,
EEE: boolean,
auto_upgrade: boolean,
nwa_ba: boolean,
pull_nsconfig: {
orgkey_exist: boolean,
orguri_exist: boolean
}
},
common_name: string,
connected_apps: string[],
id: number,
lbrokerconnect: boolean,
name: string,
publisher_upgrade_profiles_id: number,
registered: boolean,
status: 'connected' | 'not registered',
stitcher_id: number,
sticher_pop: string,
upgrade_request: boolean,
upgrade_status: {
upstat: string
}
}>
},
status: 'success' | 'not found',
total: number
}
Usage Examples:
getPublisher
id
: Numeric identifier of the publisherUsage Examples:
createPublisher
{
name: string, // Publisher name
lbrokerconnect?: boolean, // Optional local broker connection
publisher_upgrade_profiles_id?: number // Optional upgrade profile assignment
}
Usage Examples:
patchPublisher
{
name: string, // Publisher name
id?: number, // Optional publisher ID
lbrokerconnect?: boolean, // Optional local broker connection
publisher_upgrade_profiles_id?: number // Optional upgrade profile assignment
}