import { NetworkManager } from '../managers/network.js';
import { z } from 'zod';
export function getNetworkTools() {
return [
{
name: 'docker_list_networks',
description: 'List Docker networks',
inputSchema: {
type: 'object',
properties: {
filters: {
type: 'object',
description: 'Filter networks',
additionalProperties: {
type: 'array',
items: { type: 'string' },
},
},
},
},
},
{
name: 'docker_create_network',
description: 'Create a Docker network',
inputSchema: {
type: 'object',
properties: {
name: {
type: 'string',
description: 'Network name',
},
driver: {
type: 'string',
description: 'Network driver (bridge, host, overlay, etc.)',
},
labels: {
type: 'object',
description: 'Labels to apply to the network',
additionalProperties: { type: 'string' },
},
internal: {
type: 'boolean',
description: 'Restrict external access to the network',
},
attachable: {
type: 'boolean',
description: 'Enable manual container attachment',
},
},
required: ['name'],
},
},
{
name: 'docker_remove_network',
description: 'Remove a Docker network. Requires confirmation for safety. First call without confirm to see network details, then call again with confirm=true to proceed.',
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Network ID or name',
},
confirm: {
type: 'boolean',
description: 'Confirmation flag. Must be true to actually remove the network. First call without this to see network details.',
},
},
required: ['id'],
},
},
{
name: 'docker_inspect_network',
description: 'Get detailed information about a network',
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Network ID or name',
},
},
required: ['id'],
},
},
{
name: 'docker_connect_container',
description: 'Connect a container to a network',
inputSchema: {
type: 'object',
properties: {
networkId: {
type: 'string',
description: 'Network ID or name',
},
containerId: {
type: 'string',
description: 'Container ID or name',
},
},
required: ['networkId', 'containerId'],
},
},
{
name: 'docker_disconnect_container',
description: 'Disconnect a container from a network',
inputSchema: {
type: 'object',
properties: {
networkId: {
type: 'string',
description: 'Network ID or name',
},
containerId: {
type: 'string',
description: 'Container ID or name',
},
force: {
type: 'boolean',
description: 'Force disconnection',
},
},
required: ['networkId', 'containerId'],
},
},
];
}
export async function handleNetworkTool(
name: string,
args: any,
networkManager: NetworkManager
): Promise<any> {
try {
switch (name) {
case 'docker_list_networks': {
const parsed = z
.object({
filters: z.record(z.array(z.string())).optional(),
})
.parse(args);
const networks = await networkManager.listNetworks({
filters: parsed.filters,
});
return {
content: [
{
type: 'text',
text: JSON.stringify(networks, null, 2),
},
],
};
}
case 'docker_create_network': {
const parsed = z
.object({
name: z.string(),
driver: z.string().optional(),
labels: z.record(z.string()).optional(),
internal: z.boolean().optional(),
attachable: z.boolean().optional(),
})
.parse(args);
const network = await networkManager.createNetwork({
Name: parsed.name,
Driver: parsed.driver || 'bridge',
Labels: parsed.labels,
Internal: parsed.internal,
Attachable: parsed.attachable,
});
return {
content: [
{
type: 'text',
text: JSON.stringify({ id: network.id, message: 'Network created successfully' }, null, 2),
},
],
};
}
case 'docker_remove_network': {
const parsed = z
.object({
id: z.string(),
confirm: z.boolean().optional(),
})
.parse(args);
// First call: Show network details and request confirmation
if (!parsed.confirm) {
try {
const networkInfo = await networkManager.inspectNetwork(parsed.id);
return {
content: [
{
type: 'text',
text: JSON.stringify({
warning: '⚠️ CONFIRMATION REQUIRED: Network removal is a destructive operation',
network: {
id: networkInfo.Id,
name: networkInfo.Name,
driver: networkInfo.Driver,
scope: networkInfo.Scope,
containers: Object.keys(networkInfo.Containers || {}).length,
},
message: 'To proceed with removal, call this tool again with confirm=true',
example: {
name: 'docker_remove_network',
arguments: {
id: parsed.id,
confirm: true,
},
},
}, null, 2),
},
],
};
} catch (error: any) {
return {
content: [
{
type: 'text',
text: JSON.stringify({
error: `Network not found: ${parsed.id}`,
message: error.message,
}, null, 2),
},
],
isError: true,
};
}
}
// Second call with confirm=true: Actually remove the network
if (parsed.confirm === true) {
await networkManager.removeNetwork(parsed.id);
return {
content: [
{
type: 'text',
text: JSON.stringify({
message: '✅ Network removed successfully',
removed: parsed.id,
}, null, 2),
},
],
};
}
return {
content: [
{
type: 'text',
text: JSON.stringify({
error: 'Invalid confirmation state',
message: 'Please set confirm=true to proceed with network removal',
}, null, 2),
},
],
isError: true,
};
}
case 'docker_inspect_network': {
const parsed = z.object({ id: z.string() }).parse(args);
const info = await networkManager.inspectNetwork(parsed.id);
return {
content: [
{
type: 'text',
text: JSON.stringify(info, null, 2),
},
],
};
}
case 'docker_connect_container': {
const parsed = z
.object({
networkId: z.string(),
containerId: z.string(),
})
.parse(args);
await networkManager.connectContainer(parsed.networkId, parsed.containerId);
return {
content: [
{
type: 'text',
text: JSON.stringify({ message: 'Container connected to network successfully' }, null, 2),
},
],
};
}
case 'docker_disconnect_container': {
const parsed = z
.object({
networkId: z.string(),
containerId: z.string(),
force: z.boolean().optional(),
})
.parse(args);
await networkManager.disconnectContainer(parsed.networkId, parsed.containerId, parsed.force);
return {
content: [
{
type: 'text',
text: JSON.stringify({ message: 'Container disconnected from network successfully' }, null, 2),
},
],
};
}
default:
return null;
}
} catch (error: any) {
if (error.message?.includes('Unknown tool')) {
return null;
}
throw error;
}
}