diff --git a/src/grist_mcp/tools/__init__.py b/src/grist_mcp/tools/__init__.py new file mode 100644 index 0000000..ff98608 --- /dev/null +++ b/src/grist_mcp/tools/__init__.py @@ -0,0 +1 @@ +"""MCP tools for Grist operations.""" diff --git a/src/grist_mcp/tools/discovery.py b/src/grist_mcp/tools/discovery.py new file mode 100644 index 0000000..631ea81 --- /dev/null +++ b/src/grist_mcp/tools/discovery.py @@ -0,0 +1,12 @@ +"""Discovery tools - list accessible documents.""" + +from grist_mcp.auth import Agent + + +async def list_documents(agent: Agent) -> dict: + """List documents this agent can access with their permissions.""" + documents = [ + {"name": scope.document, "permissions": scope.permissions} + for scope in agent._token_obj.scope + ] + return {"documents": documents} diff --git a/tests/test_tools_discovery.py b/tests/test_tools_discovery.py new file mode 100644 index 0000000..166bf0a --- /dev/null +++ b/tests/test_tools_discovery.py @@ -0,0 +1,29 @@ +import pytest +from grist_mcp.tools.discovery import list_documents +from grist_mcp.auth import Agent +from grist_mcp.config import Token, TokenScope + + +@pytest.fixture +def agent(): + token_obj = Token( + token="test-token", + name="test-agent", + scope=[ + TokenScope(document="budget", permissions=["read", "write"]), + TokenScope(document="expenses", permissions=["read"]), + ], + ) + return Agent(token="test-token", name="test-agent", _token_obj=token_obj) + + +@pytest.mark.asyncio +async def test_list_documents_returns_accessible_docs(agent): + result = await list_documents(agent) + + assert result == { + "documents": [ + {"name": "budget", "permissions": ["read", "write"]}, + {"name": "expenses", "permissions": ["read"]}, + ] + }