feat: Complete Phase 5 - Instrument all 93 MCP tools
Applied @instrument_tool decorator to all 86 remaining tools across 8 server files. Instrumented files: - calendar.py: 16 tools - contacts.py: 7 tools - deck.py: 25 tools - webdav.py: 11 tools - tables.py: 6 tools - sharing.py: 5 tools - cookbook.py: 13 tools - semantic.py: 3 tools Total: 93 tools instrumented (7 in notes.py + 86 in other files) These metrics populate: - MCP Tool Calls panel (by tool name and status) - MCP Tool Duration panel (histogram) - MCP Tool Errors panel (by tool name and error type) This completes PR #295 - All 5 phases of metrics instrumentation done: ✅ Phase 1: Queue size metrics (2 locations) ✅ Phase 2: Health checks (1 location) ✅ Phase 3: Database operations (3 methods) ✅ Phase 4: OAuth token metrics (3 locations) ✅ Phase 5: MCP tool metrics (93 tools) All 34 dashboard panels now have data sources.
This commit is contained in:
@@ -18,6 +18,7 @@ from nextcloud_mcp_server.models.deck import (
|
||||
LabelOperationResponse,
|
||||
StackOperationResponse,
|
||||
)
|
||||
from nextcloud_mcp_server.observability.metrics import instrument_tool
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -118,6 +119,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:read")
|
||||
@instrument_tool
|
||||
async def deck_get_boards(ctx: Context) -> list[DeckBoard]:
|
||||
"""Get all Nextcloud Deck boards"""
|
||||
client = await get_client(ctx)
|
||||
@@ -126,6 +128,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:read")
|
||||
@instrument_tool
|
||||
async def deck_get_board(ctx: Context, board_id: int) -> DeckBoard:
|
||||
"""Get details of a specific Nextcloud Deck board"""
|
||||
client = await get_client(ctx)
|
||||
@@ -134,6 +137,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:read")
|
||||
@instrument_tool
|
||||
async def deck_get_stacks(ctx: Context, board_id: int) -> list[DeckStack]:
|
||||
"""Get all stacks in a Nextcloud Deck board"""
|
||||
client = await get_client(ctx)
|
||||
@@ -142,6 +146,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:read")
|
||||
@instrument_tool
|
||||
async def deck_get_stack(ctx: Context, board_id: int, stack_id: int) -> DeckStack:
|
||||
"""Get details of a specific Nextcloud Deck stack"""
|
||||
client = await get_client(ctx)
|
||||
@@ -150,6 +155,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:read")
|
||||
@instrument_tool
|
||||
async def deck_get_cards(
|
||||
ctx: Context, board_id: int, stack_id: int
|
||||
) -> list[DeckCard]:
|
||||
@@ -162,6 +168,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:read")
|
||||
@instrument_tool
|
||||
async def deck_get_card(
|
||||
ctx: Context, board_id: int, stack_id: int, card_id: int
|
||||
) -> DeckCard:
|
||||
@@ -172,6 +179,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:read")
|
||||
@instrument_tool
|
||||
async def deck_get_labels(ctx: Context, board_id: int) -> list[DeckLabel]:
|
||||
"""Get all labels in a Nextcloud Deck board"""
|
||||
client = await get_client(ctx)
|
||||
@@ -180,6 +188,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:read")
|
||||
@instrument_tool
|
||||
async def deck_get_label(ctx: Context, board_id: int, label_id: int) -> DeckLabel:
|
||||
"""Get details of a specific Nextcloud Deck label"""
|
||||
client = await get_client(ctx)
|
||||
@@ -190,6 +199,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_create_board(
|
||||
ctx: Context, title: str, color: str
|
||||
) -> CreateBoardResponse:
|
||||
@@ -207,6 +217,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_create_stack(
|
||||
ctx: Context, board_id: int, title: str, order: int
|
||||
) -> CreateStackResponse:
|
||||
@@ -223,6 +234,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_update_stack(
|
||||
ctx: Context,
|
||||
board_id: int,
|
||||
@@ -249,6 +261,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_delete_stack(
|
||||
ctx: Context, board_id: int, stack_id: int
|
||||
) -> StackOperationResponse:
|
||||
@@ -270,6 +283,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
# Card Tools
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_create_card(
|
||||
ctx: Context,
|
||||
board_id: int,
|
||||
@@ -304,6 +318,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_update_card(
|
||||
ctx: Context,
|
||||
board_id: int,
|
||||
@@ -357,6 +372,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_delete_card(
|
||||
ctx: Context, board_id: int, stack_id: int, card_id: int
|
||||
) -> CardOperationResponse:
|
||||
@@ -379,6 +395,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_archive_card(
|
||||
ctx: Context, board_id: int, stack_id: int, card_id: int
|
||||
) -> CardOperationResponse:
|
||||
@@ -401,6 +418,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_unarchive_card(
|
||||
ctx: Context, board_id: int, stack_id: int, card_id: int
|
||||
) -> CardOperationResponse:
|
||||
@@ -423,6 +441,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_reorder_card(
|
||||
ctx: Context,
|
||||
board_id: int,
|
||||
@@ -455,6 +474,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
# Label Tools
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_create_label(
|
||||
ctx: Context, board_id: int, title: str, color: str
|
||||
) -> CreateLabelResponse:
|
||||
@@ -471,6 +491,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_update_label(
|
||||
ctx: Context,
|
||||
board_id: int,
|
||||
@@ -497,6 +518,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_delete_label(
|
||||
ctx: Context, board_id: int, label_id: int
|
||||
) -> LabelOperationResponse:
|
||||
@@ -518,6 +540,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
# Card-Label Assignment Tools
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_assign_label_to_card(
|
||||
ctx: Context, board_id: int, stack_id: int, card_id: int, label_id: int
|
||||
) -> CardOperationResponse:
|
||||
@@ -541,6 +564,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_remove_label_from_card(
|
||||
ctx: Context, board_id: int, stack_id: int, card_id: int, label_id: int
|
||||
) -> CardOperationResponse:
|
||||
@@ -565,6 +589,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
# Card-User Assignment Tools
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_assign_user_to_card(
|
||||
ctx: Context, board_id: int, stack_id: int, card_id: int, user_id: str
|
||||
) -> CardOperationResponse:
|
||||
@@ -588,6 +613,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
|
||||
@mcp.tool()
|
||||
@require_scopes("deck:write")
|
||||
@instrument_tool
|
||||
async def deck_unassign_user_from_card(
|
||||
ctx: Context, board_id: int, stack_id: int, card_id: int, user_id: str
|
||||
) -> CardOperationResponse:
|
||||
|
||||
Reference in New Issue
Block a user