feat: add api_call pass-through tool and API reference resource
All checks were successful
Build and Push Monarch MCP Docker Image / build (push) Successful in 46s
All checks were successful
Build and Push Monarch MCP Docker Image / build (push) Successful in 46s
- Add single pass-through tool following blueprint 'escape hatch' pattern - Add monarch://api-reference resource with available methods documentation - Fix dependency: use monarchmoney>=0.1.15 instead of monarchmoneycommunity - Add JSON error handling for malformed params
This commit is contained in:
@@ -19,7 +19,7 @@ requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"mcp[cli]>=1.0.0",
|
||||
"fastmcp>=0.4.1",
|
||||
"monarchmoneycommunity>=0.1.0",
|
||||
"monarchmoney>=0.1.15",
|
||||
"gql>=4.0",
|
||||
"python-dotenv>=1.0.0",
|
||||
"pydantic>=2.0.0",
|
||||
|
||||
@@ -191,6 +191,85 @@ async def refresh_accounts(reason: Optional[str] = None) -> str:
|
||||
return serialize_json(result)
|
||||
|
||||
|
||||
# --- API Reference Resource ---
|
||||
|
||||
API_REFERENCE = """
|
||||
# Monarch Money API Reference
|
||||
Full method signatures: https://github.com/hammem/monarchmoney
|
||||
|
||||
## Transaction Operations
|
||||
- get_transactions(limit=100, offset=0, start_date=None, end_date=None, search='', category_ids=[], account_ids=[])
|
||||
- get_transaction_splits(transaction_id: str)
|
||||
- update_transaction_splits(transaction_id: str, split_data: List[Dict])
|
||||
- create_transaction(date, account_id, amount, merchant_name, category_id, notes='', update_balance=False)
|
||||
- update_transaction(transaction_id, category_id=None, merchant_name=None, amount=None, date=None, notes=None)
|
||||
- delete_transaction(transaction_id: str)
|
||||
- get_transaction_details(transaction_id: str)
|
||||
|
||||
## Categories & Tags
|
||||
- get_transaction_categories()
|
||||
- get_transaction_category_groups()
|
||||
- create_transaction_category(group_id, transaction_category_name, ...)
|
||||
- create_transaction_tag(name, color)
|
||||
- set_transaction_tags(transaction_id, tag_ids)
|
||||
- get_transaction_tags()
|
||||
|
||||
## Accounts
|
||||
- get_accounts()
|
||||
- get_account_holdings(account_id: int)
|
||||
- create_manual_account(account_type, account_sub_type, is_in_net_worth, account_name, account_balance=0)
|
||||
- update_account(account_id, account_name=None, account_balance=None, ...)
|
||||
|
||||
## Budget & Cashflow
|
||||
- get_budgets(start_date=None, end_date=None)
|
||||
- get_cashflow(limit=100, start_date=None, end_date=None)
|
||||
- get_recurring_transactions(start_date=None, end_date=None)
|
||||
|
||||
## Sync
|
||||
- request_accounts_refresh(account_ids: List[str])
|
||||
- is_accounts_refresh_complete(account_ids=None)
|
||||
"""
|
||||
|
||||
|
||||
@mcp.resource("monarch://api-reference")
|
||||
def get_api_docs() -> str:
|
||||
"""Returns the API documentation for using the 'api_call' tool."""
|
||||
return API_REFERENCE
|
||||
|
||||
|
||||
# --- Pass-through Tool ---
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
@retry_on_auth_error()
|
||||
async def api_call(method: str, params: str = "{}") -> str:
|
||||
"""
|
||||
Execute a raw method call to the Monarch Money API.
|
||||
|
||||
Args:
|
||||
method: The method name to call (e.g., 'get_transaction_splits', 'update_transaction_splits')
|
||||
params: JSON string of parameters to pass to the method
|
||||
|
||||
Returns:
|
||||
JSON result from the API call
|
||||
|
||||
Example:
|
||||
api_call(method="get_transaction_categories", params="{}")
|
||||
api_call(method="get_transaction_splits", params='{"transaction_id": "12345"}')
|
||||
api_call(method="update_transaction_splits", params='{"transaction_id": "12345", "split_data": [{"amount": -50.00, "categoryId": "100", "merchantName": "Groceries"}]}')
|
||||
"""
|
||||
client = await get_authenticated_client()
|
||||
method_func = getattr(client, method, None)
|
||||
if not method_func:
|
||||
return serialize_json({"error": f"Method '{method}' not found"})
|
||||
try:
|
||||
parsed_params = json.loads(params) if params else {}
|
||||
except json.JSONDecodeError as e:
|
||||
return serialize_json({"error": f"Invalid JSON in params: {e}"})
|
||||
result = await method_func(**parsed_params)
|
||||
return serialize_json(result)
|
||||
|
||||
|
||||
# --- Health Check Endpoint ---
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user