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]
|
*.py[cod]
|
||||||
.venv/
|
.venv/
|
||||||
.env
|
.env
|
||||||
config.yaml
|
/config.yaml
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
dist/
|
dist/
|
||||||
.pytest_cache/
|
.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"
|
- "${PORT:-3000}:3000"
|
||||||
volumes:
|
volumes:
|
||||||
- ../../src:/app/src:ro
|
- ../../src:/app/src:ro
|
||||||
- ../../config.yaml:/app/config.yaml:ro
|
- ./config.yaml:/app/config.yaml:ro
|
||||||
environment:
|
environment:
|
||||||
- CONFIG_PATH=/app/config.yaml
|
- CONFIG_PATH=/app/config.yaml
|
||||||
healthcheck:
|
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():
|
def create_app():
|
||||||
"""Create the ASGI application."""
|
"""Create the ASGI application."""
|
||||||
config_path = os.environ.get("CONFIG_PATH", "/app/config.yaml")
|
config_path = os.environ.get("CONFIG_PATH", "/app/config.yaml")
|
||||||
|
|
||||||
if not os.path.exists(config_path):
|
if not _ensure_config(config_path):
|
||||||
print(f"Error: Config file not found at {config_path}", file=sys.stderr)
|
sys.exit(0)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
config = load_config(config_path)
|
config = load_config(config_path)
|
||||||
auth = Authenticator(config)
|
auth = Authenticator(config)
|
||||||
|
|||||||
Reference in New Issue
Block a user