Skip to content

Commit ccf6ee2

Browse files
shopewfgebhardtr
authored andcommitted
[CHORE] Implement basic NLB server
1 parent 73899ec commit ccf6ee2

File tree

8 files changed

+1189
-0
lines changed

8 files changed

+1189
-0
lines changed

mcphost.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@
8989
"run",
9090
"oracle.oci-migration-mcp-server"
9191
]
92+
},
93+
"oracle-oci-network-load-balancer-mcp-server": {
94+
"type": "local",
95+
"command": "uv",
96+
"args": [
97+
"run",
98+
"oracle.oci-network-load-balancer-mcp-server"
99+
]
92100
}
93101
}
94102
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# OCI Network Load Balancer MCP server

src/oci-network-load-balancer-mcp-server/oracle/__init__.py

Whitespace-only changes.

src/oci-network-load-balancer-mcp-server/oracle/oci_network_load_balancer_mcp_server/__init__.py

Whitespace-only changes.
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import os
2+
from logging import Logger
3+
4+
import oci
5+
from fastmcp import FastMCP
6+
7+
logger = Logger(__name__, level="INFO")
8+
9+
mcp = FastMCP(name="oracle.oci-compute-mcp-server")
10+
11+
12+
def get_network_load_balancer_client():
13+
logger.info("entering get_network_load_balancer_client")
14+
config = oci.config.from_file(
15+
profile_name=os.getenv("OCI_CONFIG_PROFILE", oci.config.DEFAULT_PROFILE)
16+
)
17+
18+
private_key = oci.signer.load_private_key_from_file(config["key_file"])
19+
token_file = config["security_token_file"]
20+
token = None
21+
with open(token_file, "r") as f:
22+
token = f.read()
23+
signer = oci.auth.signers.SecurityTokenSigner(token, private_key)
24+
return oci.network_load_balancer.NetworkLoadBalancerClient(config, signer=signer)
25+
26+
27+
@mcp.tool
28+
def list_network_load_balancers(compartment_id: str):
29+
"""Lists the network load balancers from the given compartment"""
30+
nlb_client = get_network_load_balancer_client()
31+
nlbs = nlb_client.list_network_load_balancers(compartment_id).data.items
32+
return [
33+
{
34+
"nlb_id": nlb.id,
35+
"display_name": nlb.display_name,
36+
"lifecycle_state": nlb.lifecycle_state,
37+
"public_ips": [ip.ip_address for ip in nlb.ip_addresses if ip.is_public],
38+
"private_ips": [
39+
ip.ip_address for ip in nlb.ip_addresses if not ip.is_public
40+
],
41+
}
42+
for nlb in nlbs
43+
]
44+
45+
46+
@mcp.tool
47+
def get_network_load_balancer(network_load_balancer_id: str):
48+
"""Gets the network load balancer with the given ocid"""
49+
nlb_client = get_network_load_balancer_client()
50+
return nlb_client.get_network_load_balancer(network_load_balancer_id).data
51+
52+
53+
@mcp.tool(name="list_network_load_balancer_listeners")
54+
def list_listeners(network_load_balancer_id: str):
55+
"""Lists the listeners from the given network load balancer"""
56+
nlb_client = get_network_load_balancer_client()
57+
listeners = nlb_client.list_listeners(network_load_balancer_id).data.items
58+
return [
59+
{
60+
"name": listener.name,
61+
"ip_version": listener.ip_version,
62+
"protocol": listener.protocol,
63+
"port": listener.port,
64+
"is_ppv2_enabled": listener.is_ppv2_enabled,
65+
}
66+
for listener in listeners
67+
]
68+
69+
70+
@mcp.tool(name="get_network_load_balancer_listener")
71+
def get_listener(
72+
network_load_balancer_id: str,
73+
listener_name: str,
74+
):
75+
"""Gets the listener with the given listener name
76+
from the given network load balancer"""
77+
nlb_client = get_network_load_balancer_client()
78+
return nlb_client.get_listener(network_load_balancer_id, listener_name).data
79+
80+
81+
@mcp.tool(name="list_network_load_balancer_backend_sets")
82+
def list_backend_sets(network_load_balancer_id: str):
83+
"""Lists the backend sets from the given network load balancer"""
84+
nlb_client = get_network_load_balancer_client()
85+
backend_sets = nlb_client.list_backend_sets(network_load_balancer_id).data.items
86+
return [
87+
{
88+
"name": backend_set.name,
89+
"ip_version": backend_set.ip_version,
90+
"is_preemptive": backend_set.are_operationally_active_backends_preferred,
91+
"load_balancing_policy": backend_set.policy,
92+
"number_of_backends": len(backend_set.backends),
93+
}
94+
for backend_set in backend_sets
95+
]
96+
97+
98+
@mcp.tool(name="get_network_load_balancer_backend_set")
99+
def get_backend_set(
100+
network_load_balancer_id: str,
101+
backend_set_name: str,
102+
):
103+
"""Gets the backend set with the given backend set name
104+
from the given network load balancer"""
105+
nlb_client = get_network_load_balancer_client()
106+
return nlb_client.get_backend_set(network_load_balancer_id, backend_set_name).data
107+
108+
109+
@mcp.tool(name="list_network_load_balancer_backends")
110+
def list_backends(
111+
network_load_balancer_id: str,
112+
backend_set_name: str,
113+
):
114+
"""Lists the backends from the given backend set and network load balancer"""
115+
nlb_client = get_network_load_balancer_client()
116+
backends = nlb_client.list_backends(
117+
network_load_balancer_id, backend_set_name
118+
).data.items
119+
return [
120+
{
121+
"name": backend.name,
122+
"ip_address": backend.ip_address,
123+
"port": backend.port,
124+
"weight": backend.weight,
125+
"is_drain": backend.is_drain,
126+
"is_backup": backend.is_backup,
127+
"is_offline": backend.is_offline,
128+
}
129+
for backend in backends
130+
]
131+
132+
133+
@mcp.tool(name="get_network_load_balancer_backend")
134+
def get_backend(
135+
network_load_balancer_id: str,
136+
backend_set_name: str,
137+
backend_name: str,
138+
):
139+
"""Gets the backend with the given backend name
140+
from the given backend set and network load balancer"""
141+
nlb_client = get_network_load_balancer_client()
142+
return nlb_client.get_backend(
143+
network_load_balancer_id, backend_set_name, backend_name
144+
).data
145+
146+
147+
def main():
148+
mcp.run()
149+
150+
151+
if __name__ == "__main__":
152+
main()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[project]
2+
name = "oracle.oci-network-load-balancer-mcp-server"
3+
version = "0.1.0"
4+
description = "OCI Network Load Balancer MCP server"
5+
readme = "README.md"
6+
authors = [
7+
{ name = "Will Shope", email = "[email protected]" }
8+
]
9+
requires-python = ">=3.13"
10+
dependencies = [
11+
"fastmcp==2.12.2",
12+
"oci==2.160.0"
13+
]
14+
15+
[project.scripts]
16+
"oracle.oci-network-load-balancer-mcp-server" = "oracle.oci_network_load_balancer_mcp_server.server:main"
17+
18+
[build-system]
19+
requires = ["hatchling"]
20+
build-backend = "hatchling.build"
21+
22+
[tool.hatch.build.targets.wheel]
23+
packages = ["oracle"]

0 commit comments

Comments
 (0)