Skip to content

Commit 9ffdba1

Browse files
committed
Fix ctx parameter to be properly injected by FastMCP
The ctx parameter was exposed as a required/optional user parameter in the MCP tool schema, which is not standard MCP protocol behavior. Changes: - Add Context type annotation from fastmcp to all tool functions - FastMCP now automatically injects the context and excludes it from the MCP schema exposed to clients - Clients no longer need to pass ctx=null when calling tools This follows FastMCP's documented pattern for context injection: https://gofastmcp.com/servers/context
1 parent bace6c9 commit 9ffdba1

File tree

9 files changed

+104
-87
lines changed

9 files changed

+104
-87
lines changed

src/mcp_server_grist/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import httpx
1515
from dotenv import load_dotenv
16+
from fastmcp import Context
1617

1718
from .models import GristColumn, GristDocument, GristOrg, GristRecord, GristTable, GristWorkspace
1819
from .version import __version__
@@ -712,7 +713,7 @@ async def validate_formula_syntax(self, doc_id: str, table_id: str, formula: str
712713
return {"valid": False, "error": f"Could not validate formula: {str(e)}"}
713714

714715

715-
def get_client(ctx=None) -> GristClient:
716+
def get_client(ctx: Context = None) -> GristClient:
716717
"""
717718
Obtient un client Grist configuré.
718719

src/mcp_server_grist/tools/access.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import logging
99
from typing import Any, Dict, List, Optional, Union
1010

11+
from fastmcp import Context
12+
1113
from ..client import get_client
1214

1315
# Configurer le logger
@@ -37,8 +39,8 @@ def register_access_tools(mcp_server):
3739
# --- Organisation Access ---
3840

3941
async def list_organization_access(
40-
org_id: Union[int, str],
41-
ctx=None
42+
org_id: Union[int, str],
43+
ctx: Context = None
4244
) -> Dict[str, Any]:
4345
"""
4446
Liste les utilisateurs ayant accès à une organisation.
@@ -78,10 +80,10 @@ async def list_organization_access(
7880

7981

8082
async def modify_organization_access(
81-
org_id: Union[int, str],
83+
org_id: Union[int, str],
8284
user_email: str,
8385
access_level: str,
84-
ctx=None
86+
ctx: Context = None
8587
) -> Dict[str, Any]:
8688
"""
8789
Modifie l'accès d'un utilisateur à une organisation.
@@ -138,8 +140,8 @@ async def modify_organization_access(
138140
# --- Workspace Access ---
139141

140142
async def list_workspace_access(
141-
workspace_id: int,
142-
ctx=None
143+
workspace_id: int,
144+
ctx: Context = None
143145
) -> Dict[str, Any]:
144146
"""
145147
Liste les utilisateurs ayant accès à un espace de travail.
@@ -179,10 +181,10 @@ async def list_workspace_access(
179181

180182

181183
async def modify_workspace_access(
182-
workspace_id: int,
184+
workspace_id: int,
183185
user_email: str,
184186
access_level: str,
185-
ctx=None
187+
ctx: Context = None
186188
) -> Dict[str, Any]:
187189
"""
188190
Modifie l'accès d'un utilisateur à un espace de travail.
@@ -239,8 +241,8 @@ async def modify_workspace_access(
239241
# --- Document Access ---
240242

241243
async def list_document_access(
242-
doc_id: str,
243-
ctx=None
244+
doc_id: str,
245+
ctx: Context = None
244246
) -> Dict[str, Any]:
245247
"""
246248
Liste les utilisateurs ayant accès à un document.
@@ -280,10 +282,10 @@ async def list_document_access(
280282

281283

282284
async def modify_document_access(
283-
doc_id: str,
285+
doc_id: str,
284286
user_email: str,
285287
access_level: str,
286-
ctx=None
288+
ctx: Context = None
287289
) -> Dict[str, Any]:
288290
"""
289291
Modifie l'accès d'un utilisateur à un document.

src/mcp_server_grist/tools/administration.py

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import logging
99
from typing import Any, Dict, List, Optional, Union
1010

11+
from fastmcp import Context
12+
1113
from ..client import get_client
1214

1315
# Configurer le logger
@@ -51,9 +53,9 @@ def register_admin_tools(mcp_server):
5153
# --- Organisation Management ---
5254

5355
async def modify_organization(
54-
org_id: Union[int, str],
56+
org_id: Union[int, str],
5557
name: Optional[str] = None,
56-
ctx=None
58+
ctx: Context = None
5759
) -> Dict[str, Any]:
5860
"""
5961
Modifie les propriétés d'une organisation.
@@ -103,8 +105,8 @@ async def modify_organization(
103105

104106

105107
async def delete_organization(
106-
org_id: Union[int, str],
107-
ctx=None
108+
org_id: Union[int, str],
109+
ctx: Context = None
108110
) -> Dict[str, Any]:
109111
"""
110112
Supprime une organisation.
@@ -146,9 +148,9 @@ async def delete_organization(
146148
# --- Workspace Management ---
147149

148150
async def create_workspace(
149-
org_id: Union[int, str],
151+
org_id: Union[int, str],
150152
name: str,
151-
ctx=None
153+
ctx: Context = None
152154
) -> Dict[str, Any]:
153155
"""
154156
Crée un nouvel espace de travail dans une organisation.
@@ -195,9 +197,9 @@ async def create_workspace(
195197

196198

197199
async def modify_workspace(
198-
workspace_id: int,
200+
workspace_id: int,
199201
name: Optional[str] = None,
200-
ctx=None
202+
ctx: Context = None
201203
) -> Dict[str, Any]:
202204
"""
203205
Modifie les propriétés d'un espace de travail.
@@ -247,8 +249,8 @@ async def modify_workspace(
247249

248250

249251
async def delete_workspace(
250-
workspace_id: int,
251-
ctx=None
252+
workspace_id: int,
253+
ctx: Context = None
252254
) -> Dict[str, Any]:
253255
"""
254256
Supprime un espace de travail.
@@ -290,9 +292,9 @@ async def delete_workspace(
290292
# --- Document Management ---
291293

292294
async def create_document(
293-
workspace_id: int,
295+
workspace_id: int,
294296
name: str,
295-
ctx=None
297+
ctx: Context = None
296298
) -> Dict[str, Any]:
297299
"""
298300
Crée un nouveau document dans un espace de travail.
@@ -339,10 +341,10 @@ async def create_document(
339341

340342

341343
async def modify_document(
342-
doc_id: str,
344+
doc_id: str,
343345
name: Optional[str] = None,
344346
is_pinned: Optional[bool] = None,
345-
ctx=None
347+
ctx: Context = None
346348
) -> Dict[str, Any]:
347349
"""
348350
Modifie les propriétés d'un document.
@@ -395,8 +397,8 @@ async def modify_document(
395397

396398

397399
async def delete_document(
398-
doc_id: str,
399-
ctx=None
400+
doc_id: str,
401+
ctx: Context = None
400402
) -> Dict[str, Any]:
401403
"""
402404
Supprime un document.
@@ -436,9 +438,9 @@ async def delete_document(
436438

437439

438440
async def move_document(
439-
doc_id: str,
441+
doc_id: str,
440442
target_workspace_id: int,
441-
ctx=None
443+
ctx: Context = None
442444
) -> Dict[str, Any]:
443445
"""
444446
Déplace un document vers un autre espace de travail.
@@ -479,8 +481,8 @@ async def move_document(
479481

480482

481483
async def force_reload_document(
482-
doc_id: str,
483-
ctx=None
484+
doc_id: str,
485+
ctx: Context = None
484486
) -> Dict[str, Any]:
485487
"""
486488
Force le rechargement d'un document.
@@ -518,9 +520,9 @@ async def force_reload_document(
518520

519521

520522
async def delete_document_history(
521-
doc_id: str,
523+
doc_id: str,
522524
keep: int = 1000,
523-
ctx=None
525+
ctx: Context = None
524526
) -> Dict[str, Any]:
525527
"""
526528
Supprime l'historique d'un document, ne conservant que les dernières actions.
@@ -561,10 +563,10 @@ async def delete_document_history(
561563
# --- Table Management ---
562564

563565
async def create_table(
564-
doc_id: str,
566+
doc_id: str,
565567
table_id: str,
566568
columns: Optional[List[Dict[str, Any]]] = None,
567-
ctx=None
569+
ctx: Context = None
568570
) -> Dict[str, Any]:
569571
"""
570572
Crée une nouvelle table dans un document.
@@ -621,10 +623,10 @@ async def create_table(
621623

622624

623625
async def modify_table(
624-
doc_id: str,
626+
doc_id: str,
625627
table_id: str,
626628
new_table_id: Optional[str] = None,
627-
ctx=None
629+
ctx: Context = None
628630
) -> Dict[str, Any]:
629631
"""
630632
Modifie les propriétés d'une table.
@@ -682,14 +684,14 @@ async def modify_table(
682684
# --- Column Management ---
683685

684686
async def create_column(
685-
doc_id: str,
687+
doc_id: str,
686688
table_id: str,
687689
column_id: str,
688690
column_type: str = "Text",
689691
label: Optional[str] = None,
690692
formula: Optional[str] = None,
691693
widget_options: Optional[Dict[str, Any]] = None,
692-
ctx=None
694+
ctx: Context = None
693695
) -> Dict[str, Any]:
694696
"""
695697
Crée une nouvelle colonne dans une table.
@@ -760,15 +762,15 @@ async def create_column(
760762

761763

762764
async def modify_column(
763-
doc_id: str,
765+
doc_id: str,
764766
table_id: str,
765767
column_id: str,
766768
new_column_id: Optional[str] = None,
767769
column_type: Optional[str] = None,
768770
label: Optional[str] = None,
769771
formula: Optional[str] = None,
770772
widget_options: Optional[Dict[str, Any]] = None,
771-
ctx=None
773+
ctx: Context = None
772774
) -> Dict[str, Any]:
773775
"""
774776
Modifie les propriétés d'une colonne.
@@ -840,10 +842,10 @@ async def modify_column(
840842

841843

842844
async def delete_column(
843-
doc_id: str,
845+
doc_id: str,
844846
table_id: str,
845847
column_id: str,
846-
ctx=None
848+
ctx: Context = None
847849
) -> Dict[str, Any]:
848850
"""
849851
Supprime une colonne d'une table.

src/mcp_server_grist/tools/attachments.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import logging
99
from typing import Any, Dict, List, Optional, Union
1010

11+
from fastmcp import Context
12+
1113
from ..client import get_client
1214

1315
# Configurer le logger
@@ -31,7 +33,7 @@ async def list_attachments(
3133
doc_id: str,
3234
sort: Optional[str] = None,
3335
limit: Optional[int] = None,
34-
ctx=None
36+
ctx: Context = None
3537
) -> Dict[str, Any]:
3638
"""
3739
Liste les pièces jointes d'un document Grist.
@@ -77,7 +79,7 @@ async def list_attachments(
7779
async def get_attachment_info(
7880
doc_id: str,
7981
attachment_id: int,
80-
ctx=None
82+
ctx: Context = None
8183
) -> Dict[str, Any]:
8284
"""
8385
Obtient les métadonnées d'une pièce jointe.
@@ -120,7 +122,7 @@ async def get_attachment_info(
120122
async def download_attachment(
121123
doc_id: str,
122124
attachment_id: int,
123-
ctx=None
125+
ctx: Context = None
124126
) -> Dict[str, Any]:
125127
"""
126128
Télécharge le contenu d'une pièce jointe.
@@ -180,7 +182,7 @@ async def upload_attachment(
180182
filename: str,
181183
content_base64: str,
182184
content_type: str = "application/octet-stream",
183-
ctx=None
185+
ctx: Context = None
184186
) -> Dict[str, Any]:
185187
"""
186188
Téléverse une pièce jointe dans un document Grist.

src/mcp_server_grist/tools/export.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import logging
1010
from typing import Any, Dict, List, Optional, Union
1111

12+
from fastmcp import Context
13+
1214
from ..client import get_client
1315

1416
# Configurer le logger
@@ -31,7 +33,7 @@ async def download_document_sqlite(
3133
doc_id: str,
3234
nohistory: bool = False,
3335
template: bool = False,
34-
ctx=None
36+
ctx: Context = None
3537
) -> Dict[str, Any]:
3638
"""
3739
Télécharge un document Grist au format SQLite.
@@ -81,7 +83,7 @@ async def download_document_sqlite(
8183
async def download_document_excel(
8284
doc_id: str,
8385
header: str = "label",
84-
ctx=None
86+
ctx: Context = None
8587
) -> Dict[str, Any]:
8688
"""
8789
Télécharge un document Grist au format Excel.
@@ -137,7 +139,7 @@ async def download_table_csv(
137139
doc_id: str,
138140
table_id: str,
139141
header: str = "label",
140-
ctx=None
142+
ctx: Context = None
141143
) -> Dict[str, Any]:
142144
"""
143145
Télécharge une table Grist au format CSV.

0 commit comments

Comments
 (0)