Skip to content

Commit f776668

Browse files
authored
Merge pull request #3 from permitio/raz/better-action-name-support
Refactor action assignment in PermitMcpMiddleware
2 parents 8d25d98 + c4c51c8 commit f776668

3 files changed

Lines changed: 61 additions & 1 deletion

File tree

permit_fastmcp/middleware/middleware.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import re
1010
import jwt
1111
from .config import SETTINGS
12+
from .utils import generate_action_from_tool_name
1213

1314
logger = logging.getLogger("permit_fastmcp.middleware")
1415

@@ -119,7 +120,7 @@ async def on_call_tool(self, context: MiddlewareContext, call_next):
119120
arguments = getattr(message, "arguments", {})
120121
# New mapping: resource = MCP_SERVER_NAME, action = tool_name (no prefix)
121122
resource = SETTINGS.mcp_server_name
122-
action = tool_name or "unknown_tool"
123+
action = generate_action_from_tool_name(tool_name)
123124

124125
# Build attributes based on configuration
125126
attributes = {

permit_fastmcp/middleware/utils.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
def generate_action_from_tool_name(tool_name: str) -> str:
2+
"""
3+
Generate an action string from a tool name for Permit.io action name standard by replacing special characters with hyphens.
4+
5+
Args:
6+
tool_name: The original tool name
7+
8+
Returns:
9+
The formatted action string with dots, slashes, and underscores replaced by hyphens
10+
"""
11+
if not tool_name:
12+
return "unknown-tool"
13+
14+
return tool_name.replace(".", "-").replace("/", "-").replace("_", "-")

tests/test_utils.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import pytest
2+
from permit_fastmcp.middleware.utils import generate_action_from_tool_name
3+
4+
5+
def test_generate_action_from_tool_name_basic():
6+
"""Test basic tool name conversion."""
7+
assert generate_action_from_tool_name("test_tool") == "test-tool"
8+
assert generate_action_from_tool_name("my.tool") == "my-tool"
9+
assert generate_action_from_tool_name("path/to/tool") == "path-to-tool"
10+
11+
12+
def test_generate_action_from_tool_name_multiple_replacements():
13+
"""Test tool names with multiple special characters."""
14+
assert generate_action_from_tool_name("test.tool_name") == "test-tool-name"
15+
assert generate_action_from_tool_name("path/to/my_tool") == "path-to-my-tool"
16+
assert (
17+
generate_action_from_tool_name("com.example.tool_name")
18+
== "com-example-tool-name"
19+
)
20+
21+
22+
def test_generate_action_from_tool_name_edge_cases():
23+
"""Test edge cases for tool name conversion."""
24+
# Empty string
25+
assert generate_action_from_tool_name("") == "unknown-tool"
26+
27+
# None value
28+
assert generate_action_from_tool_name(None) == "unknown-tool"
29+
30+
# Only special characters
31+
assert generate_action_from_tool_name("...") == "---"
32+
assert generate_action_from_tool_name("///") == "---"
33+
assert generate_action_from_tool_name("___") == "---"
34+
35+
# Mixed special characters
36+
assert (
37+
generate_action_from_tool_name("test.tool_name/path") == "test-tool-name-path"
38+
)
39+
40+
41+
def test_generate_action_from_tool_name_no_changes():
42+
"""Test tool names that don't need any replacements."""
43+
assert generate_action_from_tool_name("simpletool") == "simpletool"
44+
assert generate_action_from_tool_name("tool-name") == "tool-name"
45+
assert generate_action_from_tool_name("toolname") == "toolname"

0 commit comments

Comments
 (0)