feat: add dev config and graceful config handling
- Add deploy/dev/config.yaml for dev environment testing - Mount config from ./config.yaml instead of project root - Create template config if missing and exit gracefully - Update .gitignore to only ignore root config.yaml
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,7 +2,7 @@ __pycache__/
|
||||
*.py[cod]
|
||||
.venv/
|
||||
.env
|
||||
config.yaml
|
||||
/config.yaml
|
||||
*.egg-info/
|
||||
dist/
|
||||
.pytest_cache/
|
||||
|
||||
30
deploy/dev/config.yaml
Normal file
30
deploy/dev/config.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
# Development configuration for grist-mcp
|
||||
#
|
||||
# Token Generation:
|
||||
# python -c "import secrets; print(secrets.token_urlsafe(32))"
|
||||
# openssl rand -base64 32
|
||||
|
||||
# Document definitions
|
||||
documents:
|
||||
mcp-test-document:
|
||||
url: https://grist.bballou.com/
|
||||
doc_id: mVQvKTAyZC1FWZQgfuVeHC
|
||||
api_key: 83a03433a61ee9d2f2bf055d7f4518bedef0421a
|
||||
|
||||
# Agent tokens with access scopes
|
||||
tokens:
|
||||
- token: test-token-all-permissions
|
||||
name: dev-agent
|
||||
scope:
|
||||
- document: mcp-test-document
|
||||
permissions: [read, write, schema]
|
||||
- token: test-token-read-permissions
|
||||
name: dev-agent-read
|
||||
scope:
|
||||
- document: mcp-test-document
|
||||
permissions: [read]
|
||||
- token: test-token-no-schema-permissions
|
||||
name: dev-agent-no-schema
|
||||
scope:
|
||||
- document: mcp-test-document
|
||||
permissions: [read, write]
|
||||
@@ -8,7 +8,7 @@ services:
|
||||
- "${PORT:-3000}:3000"
|
||||
volumes:
|
||||
- ../../src:/app/src:ro
|
||||
- ../../config.yaml:/app/config.yaml:ro
|
||||
- ./config.yaml:/app/config.yaml:ro
|
||||
environment:
|
||||
- CONFIG_PATH=/app/config.yaml
|
||||
healthcheck:
|
||||
|
||||
@@ -41,13 +41,61 @@ async def send_error(send: Send, status: int, message: str) -> None:
|
||||
})
|
||||
|
||||
|
||||
CONFIG_TEMPLATE = """\
|
||||
# grist-mcp configuration
|
||||
#
|
||||
# Token Generation:
|
||||
# python -c "import secrets; print(secrets.token_urlsafe(32))"
|
||||
# openssl rand -base64 32
|
||||
|
||||
# Document definitions
|
||||
documents:
|
||||
my-document:
|
||||
url: https://docs.getgrist.com
|
||||
doc_id: YOUR_DOC_ID
|
||||
api_key: ${GRIST_API_KEY}
|
||||
|
||||
# Agent tokens with access scopes
|
||||
tokens:
|
||||
- token: REPLACE_WITH_GENERATED_TOKEN
|
||||
name: my-agent
|
||||
scope:
|
||||
- document: my-document
|
||||
permissions: [read, write]
|
||||
"""
|
||||
|
||||
|
||||
def _ensure_config(config_path: str) -> bool:
|
||||
"""Ensure config file exists. Creates template if missing.
|
||||
|
||||
Returns True if config is ready, False if template was created.
|
||||
"""
|
||||
path = os.path.abspath(config_path)
|
||||
|
||||
# Check if path is a directory (Docker creates this when mounting missing file)
|
||||
if os.path.isdir(path):
|
||||
os.rmdir(path)
|
||||
|
||||
if os.path.exists(path):
|
||||
return True
|
||||
|
||||
# Create template config
|
||||
with open(path, "w") as f:
|
||||
f.write(CONFIG_TEMPLATE)
|
||||
|
||||
print(f"Created template configuration at: {path}")
|
||||
print()
|
||||
print("Please edit this file to configure your Grist documents and agent tokens,")
|
||||
print("then restart the server.")
|
||||
return False
|
||||
|
||||
|
||||
def create_app():
|
||||
"""Create the ASGI application."""
|
||||
config_path = os.environ.get("CONFIG_PATH", "/app/config.yaml")
|
||||
|
||||
if not os.path.exists(config_path):
|
||||
print(f"Error: Config file not found at {config_path}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
if not _ensure_config(config_path):
|
||||
sys.exit(0)
|
||||
|
||||
config = load_config(config_path)
|
||||
auth = Authenticator(config)
|
||||
|
||||
Reference in New Issue
Block a user