Skip to content

Commit eba3e6f

Browse files
authored
feat: add get_instances_by_security_group prompt (#103)
* feat: add get_instances_by_security_group prompt Add a prompt that guides LLM to find compute instances associated with a specific security group using existing tools. Closes #101 * refactor: rename prompt from get_instances to get_servers Align naming with compute_tools convention (server over instance) as suggested in code review. * style: align prompt test structure with tools test convention Wrap test functions in TestPrompts class and move imports to module level, matching the pattern used in tests/tools/. * refactor: rename test file to test_network_prompts.py Align test file naming with tools convention (e.g. test_network_tools.py) since security group is a network domain feature.
1 parent 5a1df75 commit eba3e6f

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from fastmcp import FastMCP
2+
3+
4+
def register_prompt(mcp: FastMCP):
5+
"""
6+
Register Openstack MCP prompts.
7+
"""
8+
9+
@mcp.prompt()
10+
def get_servers_by_security_group(security_group_name: str) -> str:
11+
"""
12+
Get servers associated with a specific security group.
13+
14+
:param security_group_name: The name of the security group to filter servers by.
15+
"""
16+
return (
17+
f"Find all compute servers that have the security group "
18+
f"'{security_group_name}' attached.\n\n"
19+
f"Steps:\n"
20+
f"1. Call get_servers to list all servers.\n"
21+
f"2. Check each server's security_groups field.\n"
22+
f"3. Return only the servers where security_groups contains "
23+
f"an entry with name '{security_group_name}'.\n"
24+
f"4. For each matching server, show the server name, ID, "
25+
f"status, and the full list of its security groups."
26+
)

src/openstack_mcp_server/server.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from fastmcp.server.middleware.error_handling import ErrorHandlingMiddleware
33
from fastmcp.server.middleware.logging import LoggingMiddleware
44

5+
from openstack_mcp_server.prompts import register_prompt
56
from openstack_mcp_server.tools import register_tool
67

78

@@ -13,7 +14,7 @@ def serve(transport: str, **kwargs):
1314

1415
register_tool(mcp)
1516
# resister_resources(mcp)
16-
# register_prompt(mcp)
17+
register_prompt(mcp)
1718

1819
# Add middlewares
1920
mcp.add_middleware(ErrorHandlingMiddleware())
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from unittest.mock import MagicMock
2+
3+
from fastmcp import FastMCP
4+
5+
from openstack_mcp_server.prompts import register_prompt
6+
7+
8+
class TestPrompts:
9+
"""Test cases for MCP prompts."""
10+
11+
def test_get_servers_by_security_group_prompt_registered(self):
12+
"""Test that the prompt is registered with the MCP instance."""
13+
mcp = MagicMock()
14+
register_prompt(mcp)
15+
mcp.prompt.assert_called()
16+
17+
def test_get_servers_by_security_group_prompt_content(self):
18+
"""Test that the prompt returns expected content."""
19+
mcp = FastMCP("test")
20+
register_prompt(mcp)
21+
22+
prompts = mcp._prompt_manager._prompts
23+
assert "get_servers_by_security_group" in prompts
24+
25+
prompt_obj = prompts["get_servers_by_security_group"]
26+
assert prompt_obj.fn is not None
27+
28+
result = prompt_obj.fn(security_group_name="my-sg")
29+
assert "my-sg" in result
30+
assert "get_servers" in result
31+
assert "security_groups" in result

0 commit comments

Comments
 (0)