This global OpenClaw runtime skill helps agents safely interact with running Kanvas Ecosystem API instances through GraphQL.
It is not a repository-development skill. It is for runtime API calls only.
Installed location:
~/.openclaw/skills/sa-kanvas-graphql/
Files:
~/.openclaw/skills/sa-kanvas-graphql/SKILL.md
~/.openclaw/skills/sa-kanvas-graphql/README.md
Create the global skill directory and place SKILL.md and README.md inside it:
mkdir -p ~/.openclaw/skills/sa-kanvas-graphqlThis skill is self-contained and does not require GraphQL, HTTP, curl, API, or JSON helper skills.
Ask OpenClaw to use the skill before making Kanvas API calls:
Use the sa-kanvas-graphql skill to query my Kanvas staging API.
The agent must confirm runtime context before every GraphQL request. It must not run mutations without explicit confirmation.
Example local setup:
export KANVAS_ENVIRONMENT="local"
export KANVAS_GRAPHQL_ENDPOINT="http://localhost/graphql"
export KANVAS_ADMIN_KEY="replace-with-secret"
export KANVAS_COMPANY_BRANCH_ID="replace-with-company-branch-uuid"
export KANVAS_COMPANY_ID="replace-with-company-id"
export KANVAS_APP_ID="replace-with-app-id-or-app-key"
export KANVAS_USER_ID="replace-with-user-id-if-required"Example staging setup:
export KANVAS_ENVIRONMENT="staging"
export KANVAS_GRAPHQL_ENDPOINT="https://staging-api.example.com/graphql"
export KANVAS_ADMIN_KEY="replace-with-staging-secret"
export KANVAS_COMPANY_BRANCH_ID="replace-with-staging-branch-uuid"
export KANVAS_COMPANY_ID="replace-with-staging-company-id"
export KANVAS_APP_ID="replace-with-staging-app-id-or-key"
export KANVAS_USER_ID="replace-with-staging-user-id-if-required"Never paste full secrets into chat responses. The agent should display only masked credentials, for example:
KANVAS_ADMIN_KEY=****abcd
Before every request, the agent must state and confirm:
Active Kanvas GraphQL context to use:
- endpoint: http://localhost:8000/graphql
- environment: local
- company id: 123
- company branch id: branch-uuid
- app id: app-key-or-app-uuid
- user id: 456
- admin key: ****abcd
The agent must never assume or silently reuse company, branch, app, user, environment, or credential context.
Use __typename first:
curl -sS "$KANVAS_GRAPHQL_ENDPOINT" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-Kanvas-App: $KANVAS_APP_ID" \
-H "X-Kanvas-Key: $KANVAS_ADMIN_KEY" \
-H "X-Kanvas-Location: $KANVAS_COMPANY_BRANCH_ID" \
--data @- <<'JSON'
{
"query": "query HealthCheck { __typename }",
"variables": {}
}
JSONExpected response shape:
{
"data": {
"__typename": "Query"
}
}Example query with variables:
curl -sS "$KANVAS_GRAPHQL_ENDPOINT" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-Kanvas-App: $KANVAS_APP_ID" \
-H "X-Kanvas-Key: $KANVAS_ADMIN_KEY" \
-H "X-Kanvas-Location: $KANVAS_COMPANY_BRANCH_ID" \
--data @- <<'JSON'
{
"query": "query ListLeads($first: Int!, $page: Int) { leads(first: $first, page: $page) { data { id uuid title email phone } paginatorInfo { currentPage hasMorePages total } } }",
"variables": {
"first": 10,
"page": 1
}
}
JSONUse narrow field selections and avoid broad production data pulls unless explicitly confirmed.
Before any mutation, the agent must show:
- endpoint
- environment
- company id
- company branch id
- app id if used
- user id if used
- mutation name
- affected entity
- exact variables
Example confirmation:
Mutation confirmation required:
- endpoint: https://staging-api.example.com/graphql
- environment: staging
- company id: 123
- company branch id: branch-uuid
- mutation name: createTemplate
- affected entity: Template
- variables:
{
"input": {
"name": "sales_assist_followup",
"parent_template_id": 0,
"template": "Hi {{first_name}},\nThanks for your interest.",
"template_variables": [
{ "key": "first_name", "value": "Lead first name" }
],
"title": "Sales Assist Follow-up",
"subject": "Following up",
"is_system": false
}
}
After explicit confirmation:
curl -sS "$KANVAS_GRAPHQL_ENDPOINT" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-Kanvas-App: $KANVAS_APP_ID" \
-H "X-Kanvas-Key: $KANVAS_ADMIN_KEY" \
-H "X-Kanvas-Location: $KANVAS_COMPANY_BRANCH_ID" \
--data @- <<'JSON'
{
"query": "mutation CreateTemplate($input: TemplateInput!) { createTemplate(input: $input) { id name subject title } }",
"variables": {
"input": {
"name": "sales_assist_followup",
"parent_template_id": 0,
"template": "Hi {{first_name}},\nThanks for your interest.",
"template_variables": [
{ "key": "first_name", "value": "Lead first name" }
],
"title": "Sales Assist Follow-up",
"subject": "Following up",
"is_system": false
}
}
}
JSONDestructive or high-impact mutations require a second confirmation immediately before execution.
POST /graphql HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json
Authorization: Bearer <masked-token-if-used>
X-Kanvas-App: <app-id-or-key>
X-Kanvas-Key: <masked-admin-key-if-used>
X-Kanvas-Location: <company-branch-uuid>
{
"query": "query HealthCheck { __typename }",
"variables": {}
}- Set
KANVAS_ENVIRONMENT=localordevelopment. - Set
KANVAS_GRAPHQL_ENDPOINT, commonlyhttp://localhost:8000/graphql. - Confirm whether the request is from the host or from inside Docker.
- Set app, key, and branch context.
- Run
__typename. - Run narrow read queries.
- Confirm all mutation details before writes.
Docker notes:
- From the host, use published ports such as
localhost:8000. - From a container, use service DNS/container hostname.
localhostinside a container is not the host machine.
- Set
KANVAS_ENVIRONMENT=staging. - Confirm endpoint host.
- Confirm company and branch context.
- Run
__typename. - Verify target entities with read queries.
- Confirm mutations with exact variables.
For production writes:
- Confirm
KANVAS_ENVIRONMENT=production. - Confirm production endpoint host.
- Confirm company id and branch id.
- Run a read-only verification query first.
- Show exact mutation name, affected entity, and variables.
- Wait for explicit production confirmation.
- Ask for a second confirmation for destructive/high-impact operations.
Do not run production writes from remembered context.
Unauthenticated: missing/invalid bearer token, missingX-Kanvas-Key, expired app key, or guarded field.You are not authorized: user lacks admin role, ability, or correct scope.No Company Branched Specified: missing company branch context.No Company Branch configured with this key: invalidX-Kanvas-Location.No App configured with this key: invalidX-Kanvas-App.No App Key configured with this key: invalidX-Kanvas-Key.App Key has expired: use a valid key.Cannot query field: wrong schema, stale cache, wrong endpoint, or disabled module.Variable "$input" got invalid value: variable shape does not match input type.- HTTP
429: throttled. - HTTP
413: request body too large.
The agent should summarize useful data and show errors with path and message:
GraphQL request failed:
- HTTP status: 200
- path: createTemplate
- message: Validation failed for the field [createTemplate].
- likely cause: missing required input or invalid variable type
Do not dump sensitive raw responses unless explicitly requested.
This skill is designed to prevent:
- cross-company data leakage
- cross-branch mutations
- accidental production mutations
- invalid runtime context reuse
- authorization mistakes
- secret exposure
- malformed GraphQL requests
- broad production data dumps