Skip to content

feat: modular architecture — 115 tools consolidated to 21 + Assets/CMDB support + Change planning fixes#25

Open
ecthelion77 wants to merge 4 commits intoeffytech:mainfrom
ecthelion77:main
Open

feat: modular architecture — 115 tools consolidated to 21 + Assets/CMDB support + Change planning fixes#25
ecthelion77 wants to merge 4 commits intoeffytech:mainfrom
ecthelion77:main

Conversation

@ecthelion77
Copy link
Copy Markdown

Problem

VS Code Copilot enforces a hard limit of 128 tools across all MCP servers combined. With 115 @mcp.tool() decorators in a single monolithic server.py (3200+ lines), the Freshservice MCP nearly exhausted the entire budget on its own — triggering VS Code's "Virtual Tools" mechanism which groups tools into activate_* categories and disables individual tools, effectively breaking the AI agent workflow.

Solution

1. Full modularization — 115 tools → 21

The monolithic server.py is split into focused modules. Each consolidated tool uses an action parameter (e.g. manage_ticket(action='create|update|delete|get|list|filter|get_fields')) instead of exposing separate functions.

Module Original tools Consolidated tools
tools/tickets.py 11 3
tools/changes.py 33 5
tools/assets.py 22 3
tools/agents.py 10 2
tools/requesters.py 12 2
tools/solutions.py 13 1
tools/products.py 4 1
tools/misc.py 6 2
discovery.py 2
Total 115 21

2. Assets/CMDB support

  • Full CRUD on assets, asset types, and relationships (bulk create/delete)
  • Asset sub-resources: components, assignment history, requests, contracts
  • Asset movement across workspaces
  • Search & filter with Freshservice query syntax
  • Async job status tracking for bulk operations

3. Change management fixes

  • update_change refactored from opaque Dict parameter to explicit typed fields
  • Planning fields (reason_for_change, change_impact, rollout_plan, backout_plan) now properly wrapped in {"description": ...} structure as required by the Freshservice API
  • close_change simplified with keyword args instead of fragile dict mutation
  • Added assets, category, sub_category, item_category fields support

New features

  • --scope CLI flag / FRESHSERVICE_SCOPES env-var — load only selected tool modules:
    freshservice-mcp --scope tickets changes  # only 8 tools loaded
  • Dynamic form-field discoverydiscover_form_fields(entity='change') queries the org's actual field templates instead of relying on hard-coded parameters
  • 2-level TTL cache — in-memory + on-disk (~/.cache/freshservice_mcp/), configurable via FRESHSERVICE_CACHE_TTL env-var (default 1h)
  • Shared HTTP client (http_client.py) — consistent error handling, auth, and pagination parsing across all modules
  • Centralized config (config.py) — all enums, constants, and env-var loading in one place

Architecture

src/freshservice_mcp/
├── server.py          # slim entrypoint (~90 lines)
├── config.py          # enums, constants, env config
├── http_client.py     # api_get/post/put/delete helpers
├── discovery.py       # dynamic field discovery + cache
└── tools/
    ├── __init__.py    # SCOPE_REGISTRY mapping
    ├── tickets.py     # manage_ticket, manage_ticket_conversation, manage_service_catalog
    ├── changes.py     # manage_change, manage_change_{note,task,time_entry,approval}
    ├── assets.py      # manage_asset, manage_asset_details, manage_asset_relationship
    ├── agents.py      # manage_agent, manage_agent_group
    ├── requesters.py  # manage_requester, manage_requester_group
    ├── solutions.py   # manage_solution
    ├── products.py    # manage_product
    └── misc.py        # manage_canned_response, manage_workspace

Commits

  1. 56c8656 — feat: add Assets/CMDB, Relationships and Asset Types management tools
  2. c49e9eb — fix: correct relationship endpoints and add job status tracking
  3. c187b51 — fix: refactor update_change with explicit parameters for planning fields, assets, and categories
  4. 18866bd — refactor: modularize server — 115 tools consolidated to 21

Stats

16 files changed, 7368 insertions(+), 3322 deletions(-)

Olivier Gintrand added 4 commits February 12, 2026 10:41
Add 22 new MCP tools for Freshservice Asset/CMDB management:

Assets:
- get_assets, get_asset_by_id, create_asset, update_asset
- delete_asset, delete_asset_permanently, restore_asset
- search_assets, filter_assets, move_asset
- get_asset_components, get_asset_assignment_history
- get_asset_requests, get_asset_contracts

Relationships:
- get_asset_relationships, get_all_relationships
- get_relationship_by_id, create_asset_relationships
- delete_asset_relationships, get_relationship_types

Asset Types:
- get_asset_types, get_asset_type_by_id

Updated README with new modules, tools tables and examples.
- Fix create_asset_relationships: use /api/v2/relationships/bulk-create (async job)
- Fix delete_asset_relationships: use query params ?ids=x,y instead of JSON body
- Add get_job_status tool to track async bulk operations
- Support all entity types: asset, requester, agent, department, software
…lds, assets, and categories

BREAKING CHANGE: update_change signature changed from generic Dict to explicit params

Problems fixed:
- update_change used a generic Dict parameter making it impossible for AI/MCP
  to discover planning_fields (reason_for_change, change_impact, rollout_plan,
  backout_plan) — these are now explicit parameters
- planning fields passed as top-level fields were sent raw to API and rejected
  (they must be wrapped in planning_fields.{field}.description structure)
- close_change relied on Dict mutation via .pop() — now calls update_change
  with explicit keyword arguments
- create_change and update_change were missing category, sub_category,
  item_category fields
- Neither create_change nor update_change supported assets association
- Docstrings now document all enum values for priority, impact, status, risk,
  change_type
Root cause: VS Code Copilot has a hard limit of 128 tools across all MCP
servers. With 115 tools, the Freshservice MCP was triggering VS Code's
'Virtual Tools' mechanism, which groups excess tools into activate_*
categories and disables individual tools until activated — breaking the
AI agent workflow.

Architecture changes:
- config.py: centralized enums, constants, AVAILABLE_SCOPES
- http_client.py: shared HTTP utilities (api_get/post/put/delete)
- discovery.py: dynamic form-field discovery with 2-level TTL cache
  (in-memory + on-disk JSON in ~/.cache/freshservice_mcp/)
- tools/tickets.py: 11 tools → 3 (manage_ticket, manage_ticket_conversation,
  manage_service_catalog)
- tools/changes.py: 33 tools → 5 (manage_change, manage_change_note,
  manage_change_task, manage_change_time_entry, manage_change_approval)
- tools/assets.py: 22 tools → 3 (manage_asset, manage_asset_details,
  manage_asset_relationship)
- tools/agents.py: 10 tools → 2 (manage_agent, manage_agent_group)
- tools/requesters.py: 12 tools → 2 (manage_requester, manage_requester_group)
- tools/solutions.py: 13 tools → 1 (manage_solution)
- tools/products.py: 4 tools → 1 (manage_product)
- tools/misc.py: 6 tools → 2 (manage_canned_response, manage_workspace)
- discovery tools: 2 (discover_form_fields, clear_field_cache)

New features:
- --scope CLI flag / FRESHSERVICE_SCOPES env-var to load only specific
  tool modules (e.g. --scope tickets changes)
- Dynamic field discovery replaces hard-coded org-specific parameters
- Consistent error handling across all tools
- Planning fields properly structured in changes

Old server.py preserved as server_legacy.py for reference.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant