Deployment
How to host a tool server so the Convilyn gateway can call into it. The same three targets work for any language's Author SDK runtime — AWS Lambda (Docker), AWS Fargate, and a plain VM / container behind an HTTPS frontend.
Prerequisites
- A working tool server (the
serve/Runruntime from your language's SDK). - An HTTPS-terminating endpoint reachable from the public internet.
- Ability to set environment variables on your runtime.
- A
cvl_developer token from your account settings.
HMAC contract (read first)
Every inbound request from Convilyn carries three headers:
| Header | Purpose |
|---|---|
X-Convilyn-Server-Id | Identifies which registered server is being called |
X-Convilyn-Timestamp | Unix-seconds at the gateway; rejected if more than 5 min stale |
X-Convilyn-Signature | HMAC-SHA256 over timestamp + "." + body_bytes |
The SDK runtime verifies all three automatically when CONVILYN_HMAC_SECRET is
set. In local dev mode the secret is optional — unsigned requests are accepted
with a warning so you can iterate without leaking a real secret. On any non-local
environment the secret is required; the runtime refuses to boot without it.
See Authentication for verifying the signature yourself if you run your own HTTP framework.
Environment variables
| Variable | Required? | Description |
|---|---|---|
CONVILYN_HMAC_SECRET | prod yes / dev no | Secret used to verify inbound HMAC signatures |
CONVILYN_HMAC_TOLERANCE_SECONDS | optional (default 300) | Max clock skew vs the gateway timestamp |
CONVILYN_HOST | optional (default 0.0.0.0) | Bind host |
CONVILYN_PORT | optional (default 8080) | Bind port |
CONVILYN_LOG_LEVEL | optional (default INFO) | Log level |
Target 1 — AWS Lambda (Docker image)
Best for low / bursty traffic: free idle, automatic scaling, and a public Function URL with HTTPS already terminated.
FROM public.ecr.aws/lambda/python:3.12
COPY pyproject.toml ./
RUN pip install --no-cache-dir convilyn-author
RUN pip install --no-cache-dir -e . # if you publish your tools as a package
COPY server.py ./
# The SDK ships an ASGI adapter that routes Lambda events to the runtime app.
CMD ["convilyn_author._internal.server_runtime.lambda_handler"]# Build + push to ECR, then create the function with a Function URL:
aws lambda create-function \
--function-name my-author-server \
--package-type Image --code ImageUri=<ECR-URL>:latest \
--role <EXECUTION-ROLE-ARN> \
--environment "Variables={CONVILYN_HMAC_SECRET=<SECRET>}"
aws lambda create-function-url-config --function-name my-author-server --auth-type NONETarget 2 — AWS Fargate
Best when you need warm instances (no cold start), jobs over 15 minutes, sidecars, or VPC-private inbound traffic.
{
"family": "my-author-server",
"containerDefinitions": [
{
"name": "server",
"image": "<ECR-URL>:latest",
"portMappings": [{ "containerPort": 8080, "protocol": "tcp" }],
"environment": [{ "name": "CONVILYN_PORT", "value": "8080" }],
"essential": true
}
],
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024"
}Put the HMAC secret in AWS Secrets Manager and reference its ARN via
valueFrom (never inline plaintext); the task execution role needs
secretsmanager:GetSecretValue. Fargate tasks aren't directly reachable —
terminate HTTPS on an Application Load Balancer (ACM cert) and target the service.
Target 3 — Plain VM / container
Quickest path for prototyping: any VM with a public IP and a proxy terminating HTTPS.
uv add --prerelease=allow convilyn-author # or: pip install --pre convilyn-author
export CONVILYN_HMAC_SECRET=<your-secret>
convilyn-author dev --host 0.0.0.0 --port 8080Caddy is the lowest-friction frontend (auto-issues Let's Encrypt):
my-author-server.example.com {
reverse_proxy localhost:8080
}Register the endpoint
Once your server is reachable and the HMAC secret matches what Convilyn issued you:
convilyn-author push \
--server-file server.py \
--endpoint-url https://<your-server>/Server submitted: srv_abc123 (pending_verification)
Use 'convilyn-author status' to check verification progress.The platform's verifier calls your endpoint with synthetic requests plus the
standard MCP tool-discovery probe. Pass that and your server flips to active,
ready for goal workflows — authored in the Convilyn chat Builder — to call.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
push → 402 | Developer account lacks Pro tier | Upgrade your plan |
| Inbound calls → 401 | HMAC signature mismatch | Re-issue the secret; confirm CONVILYN_HMAC_SECRET matches |
| Inbound calls → 408 | Timestamp older than tolerance | Clock skew — sync your server via NTP |
status shows verification_failed | Tool didn't pass the synthetic probe | Check logs; usually an unhandled exception → 500 |
Billing
Authoring a tool server is free. Workflows that use your server spend the
caller's quota — their consumer SDK sees PlanRequiredError /
QuotaExceededError when their plan can't afford the run. Publishing publicly
doesn't change who pays: Convilyn charges the caller; the author gets the exposure.