{
  "schemaVersion": "1.0",
  "title": "Run the Dify connector quickstart",
  "description": "In this tutorial, you will start the repository's deterministic Dify path and route two signed reads from aipctl, through product-neutral aipd, to the standalone aip-host-dify process.",
  "canonical": "https://getaip.org/docs/connectors/dify/getting-started/quickstart",
  "route": "/docs/connectors/dify/getting-started/quickstart",
  "source": "docs/connectors/dify/getting-started/quickstart.md",
  "protocol": "Agent Interoperability Protocol",
  "protocolVersion": "1.0",
  "section": "Connectors",
  "documentType": "Connector",
  "language": "en",
  "downloads": {
    "md": "/docs/download/connectors/dify/getting-started/quickstart.md",
    "txt": "/docs/download/connectors/dify/getting-started/quickstart.txt",
    "json": "/docs/download/connectors/dify/getting-started/quickstart.json",
    "pdf": "/docs/download/connectors/dify/getting-started/quickstart.pdf"
  },
  "content": {
    "format": "text/markdown",
    "markdown": "---\ntitle: Run the Dify connector quickstart\ndescription: >-\n  Route one application read and one Knowledge API read through the\n  deterministic standalone Dify topology\nkind: tutorial\naudience: application-developer\nappliesTo: \"1.x\"\nwritingStandard: \"aip-docs/1.0\"\nlastReviewedRevision: \"97be86e9efedf07ecf1783b03800f683f107fb04\"\nconnector: dify\ncapabilityIds:\n  - cap:dify:qualification-app:parameters.get\n  - cap:dify:knowledge:qualification-kb:dataset.list\n---\n\n# Run the Dify connector quickstart\n\nIn this tutorial, you will start the repository's deterministic Dify path and\nroute two signed reads from `aipctl`, through product-neutral `aipd`, to the\nstandalone `aip-host-dify` process.\n\nThe provider is a controlled local fixture. The procedure does not require or\ncontact an external Dify deployment. It is a learning exercise, not a\nproduction deployment or qualification run.\n\n## What you will verify\n\nBy the end, you will have observed:\n\n- source-derived local image and connector-release identities;\n- registry admission before the Dify host starts;\n- one `chat` app and one separately credentialed Knowledge boundary;\n- signed `parameters.get` and `dataset.list` Actions;\n- the completed app Action through the second gateway's durable status route;\n- cleanup limited to the named tutorial Compose project.\n\nYou will not test app invocation, mutation, approval, streaming, cancellation,\nprovider failure, restart, gateway failover, or a real Dify deployment.\n\n## Prerequisites\n\nYou need:\n\n- a clean `aip-core` checkout at the reviewed source revision;\n- Docker Engine, Docker Compose v2, and BuildKit;\n- enough CPU, memory, and disk for the source-owned fleet images;\n- TCP port `18443` free on loopback;\n- a POSIX-compatible shell, `lsof`, and `grep`;\n- authority to remove the named tutorial project after reviewing its state.\n\nRun every command from the `aip-core` repository root. The products profile\nbuilds all product hosts even though this tutorial starts only the Dify path.\n\nThe Compose project is `aip-connector-fleet-qualification`. Stop before startup\nif another investigation or retained run owns that project or its volumes.\n\n## 1. Verify source and port ownership\n\nSet and verify the reviewed revision:\n\n```sh\nexport AIP_SOURCE_REVISION=97be86e9efedf07ecf1783b03800f683f107fb04\n\ntest \"$(git rev-parse HEAD)\" = \"$AIP_SOURCE_REVISION\"\ntest -z \"$(git status --porcelain)\"\n```\n\nUse a separate clean checkout if either check fails. Do not hide or discard\nlocal changes to satisfy the tutorial.\n\nConfirm the required tools and the fixed edge port:\n\n```sh\ndocker info >/dev/null\ndocker compose version\n\ncommand -v lsof >/dev/null\nif lsof -nP -iTCP:18443 -sTCP:LISTEN | grep -q .; then\n  echo \"Port 18443 is already in use\" >&2\n  exit 1\nfi\n```\n\nExpected result: the port check prints nothing. Identify an existing listener\nbefore changing it; this tutorial does not authorize stopping another process.\n\n## 2. Prepare the controlled artifacts\n\nRun the source-owned preparation script:\n\n```sh\n./deploy/connector-fleet/prepare.sh\ntest -s deploy/connector-fleet/.env.qualification\n```\n\nExpected result: preparation ends with `connector fleet preparation: PASS`.\nThe owner-only environment file records the local source digest, image IDs,\nrelease ID, and release revision selected by Compose.\n\nDefine one helper that always selects the source-owned profile:\n\n```sh\ncompose() {\n  docker compose \\\n    --profile products \\\n    --env-file deploy/connector-fleet/.env.qualification \\\n    -f deploy/connector-fleet/compose.yml \\\n    \"$@\"\n}\n\ncompose ps --all\n```\n\nStop if the project contains state that must be retained. Do not remove it\nmerely because its name already exists.\n\n## 3. Start the Dify path\n\nStart the Dify host and its declared dependency graph:\n\n```sh\ncompose up --detach --wait --wait-timeout 300 dify-acme-a\ncompose ps --all\n```\n\nExpected result: `dify-acme-a`, both gateways, the control plane, edge,\nPostgreSQL, and the product fixture are healthy. Initialization, migration,\ngrant, and admission jobs may be exited with status `0`.\n\nDo not bypass a failed admission job or start the host under a different\nidentity. Preserve the failed job's bounded logs and correct its source-owned\ninput.\n\n## 4. Read application parameters\n\nRoute one signed read through the generated client identity:\n\n```sh\ncompose run --rm --no-deps \\\n  --entrypoint /usr/local/bin/aipctl \\\n  -e AIPCTL_NATIVE_PRINCIPAL_ID=service:aipctl:qualification-acme \\\n  -e AIPCTL_NATIVE_TRUST_DOMAIN=fleet.test \\\n  -e AIPCTL_NATIVE_SIGNING_SEED_FILE=/fleet-state/secrets/client-acme-signing-seed.hex \\\n  -e AIPCTL_NATIVE_PEER_DID_FILE=/fleet-state/public/gateway.did \\\n  -e AIPCTL_NATIVE_TLS_CA_FILE=/caddy-data/caddy/pki/authorities/local/root.crt \\\n  qualification action call \\\n  https://aipd.fleet.test:8443 \\\n  cap:dify:qualification-app:parameters.get \\\n  --action-id act_dify_quickstart_parameters_001 \\\n  --input '{}'\n```\n\nExpected result: the signed response names the Action and capability, reports a\ncompleted result, and contains the deterministic parameter payload.\n\nThis capability uses the application-specific fixture key. It does not expose\nthe key or let the caller choose a different app.\n\n## 5. Read the Knowledge catalogue\n\nUse a second Action for the separately credentialed Knowledge API:\n\n```sh\ncompose run --rm --no-deps \\\n  --entrypoint /usr/local/bin/aipctl \\\n  -e AIPCTL_NATIVE_PRINCIPAL_ID=service:aipctl:qualification-acme \\\n  -e AIPCTL_NATIVE_TRUST_DOMAIN=fleet.test \\\n  -e AIPCTL_NATIVE_SIGNING_SEED_FILE=/fleet-state/secrets/client-acme-signing-seed.hex \\\n  -e AIPCTL_NATIVE_PEER_DID_FILE=/fleet-state/public/gateway.did \\\n  -e AIPCTL_NATIVE_TLS_CA_FILE=/caddy-data/caddy/pki/authorities/local/root.crt \\\n  qualification action call \\\n  https://aipd.fleet.test:8443 \\\n  cap:dify:knowledge:qualification-kb:dataset.list \\\n  --action-id act_dify_quickstart_datasets_001 \\\n  --input '{\"query\":{\"limit\":1}}'\n```\n\nExpected result: the response reports a completed Action and contains the\nfixture dataset listing. The selected Knowledge credential is independent of\nthe application key used in the previous step.\n\n## 6. Verify durable Action state\n\nRead the first Action through the second gateway without repeating its provider\nrequest:\n\n```sh\ncompose run --rm --no-deps \\\n  --entrypoint /usr/local/bin/aipctl \\\n  -e AIPCTL_NATIVE_PRINCIPAL_ID=service:aipctl:qualification-acme \\\n  -e AIPCTL_NATIVE_TRUST_DOMAIN=fleet.test \\\n  -e AIPCTL_NATIVE_SIGNING_SEED_FILE=/fleet-state/secrets/client-acme-signing-seed.hex \\\n  -e AIPCTL_NATIVE_PEER_DID_FILE=/fleet-state/public/gateway.did \\\n  -e AIPCTL_NATIVE_TLS_CA_FILE=/caddy-data/caddy/pki/authorities/local/root.crt \\\n  -e AIPCTL_NATIVE_BEARER_TOKEN_FILE=/fleet-state/secrets/native-bearer-token \\\n  qualification action status \\\n  https://aipd-b.fleet.test:8443 \\\n  act_dify_quickstart_parameters_001 \\\n  --include-result\n```\n\nExpected result: the lifecycle view contains the same terminal Action and\nstored output. This demonstrates shared durable lookup, not gateway failover.\n\n## Diagnose before cleanup\n\nCapture bounded state before changing the project:\n\n```sh\ncompose ps --all\ncompose logs --no-color --tail 200 \\\n  aipd aipd-b control-plane dify-acme-a product-upstream\n```\n\n| Symptom | First check |\n|---|---|\n| Preparation cannot reach Docker | Repair the daemon, then repeat source and project checks |\n| Port `18443` is occupied | Identify the owner; do not terminate it without confirming scope |\n| Admission exits nonzero | Read that job's bounded log; do not bypass policy |\n| Dify host is unhealthy | Check descriptor files, key files, database, and fixture reachability |\n| App read is unauthorized | Verify the app-key file path without printing its value |\n| Knowledge read is unauthorized | Verify the separate Knowledge-key file path |\n| Second lookup fails | Preserve both gateway and PostgreSQL logs before changing shared state |\n\nThe tutorial does not authorize regenerating identities, weakening TLS,\nprinting credentials, deleting the database, or bypassing admission.\n\n## Stop and remove the tutorial project\n\nAfter confirming that the fixed project contains no state or evidence that must\nbe retained, remove its containers, network, and volumes:\n\n```sh\ncompose down --volumes --remove-orphans\n```\n\nReview `compose ps --all` before this command. Volume removal is intentionally\ndestructive and belongs only to the named disposable tutorial project.\n\n## Related documentation\n\n- [Dify connector overview](../README.md)\n- [AIP quickstart](../../../getting-started/quickstart.md)\n- [Deploy the connector fleet](../../../guides/deploy-connector-fleet.md)\n- [Errors and retry decisions](../../../reference/errors.md)\n- [Connector upstream baselines](../../upstream-baselines.md)\n",
    "text": "Run the Dify connector quickstart\n\nIn this tutorial, you will start the repository's deterministic Dify path and\nroute two signed reads from aipctl, through product-neutral aipd, to the\nstandalone aip-host-dify process.\n\nThe provider is a controlled local fixture. The procedure does not require or\ncontact an external Dify deployment. It is a learning exercise, not a\nproduction deployment or qualification run.\n\nWhat you will verify\n\nBy the end, you will have observed:\n• source-derived local image and connector-release identities;\n• registry admission before the Dify host starts;\n• one chat app and one separately credentialed Knowledge boundary;\n• signed parameters.get and dataset.list Actions;\n• the completed app Action through the second gateway's durable status route;\n• cleanup limited to the named tutorial Compose project.\n\nYou will not test app invocation, mutation, approval, streaming, cancellation,\nprovider failure, restart, gateway failover, or a real Dify deployment.\n\nPrerequisites\n\nYou need:\n• a clean aip-core checkout at the reviewed source revision;\n• Docker Engine, Docker Compose v2, and BuildKit;\n• enough CPU, memory, and disk for the source-owned fleet images;\n• TCP port 18443 free on loopback;\n• a POSIX-compatible shell, lsof, and grep;\n• authority to remove the named tutorial project after reviewing its state.\n\nRun every command from the aip-core repository root. The products profile\nbuilds all product hosts even though this tutorial starts only the Dify path.\n\nThe Compose project is aip-connector-fleet-qualification. Stop before startup\nif another investigation or retained run owns that project or its volumes.\n1. Verify source and port ownership\n\nSet and verify the reviewed revision:\n\nexport AIPSOURCEREVISION=97be86e9efedf07ecf1783b03800f683f107fb04\n\ntest \"$(git rev-parse HEAD)\" = \"$AIPSOURCEREVISION\"\ntest -z \"$(git status --porcelain)\"\n\nUse a separate clean checkout if either check fails. Do not hide or discard\nlocal changes to satisfy the tutorial.\n\nConfirm the required tools and the fixed edge port:\n\ndocker info >/dev/null\ndocker compose version\n\ncommand -v lsof >/dev/null\nif lsof -nP -iTCP:18443 -sTCP:LISTEN | grep -q .; then\n  echo \"Port 18443 is already in use\" >&2\n  exit 1\nfi\n\nExpected result: the port check prints nothing. Identify an existing listener\nbefore changing it; this tutorial does not authorize stopping another process.\n2. Prepare the controlled artifacts\n\nRun the source-owned preparation script:\n\n./deploy/connector-fleet/prepare.sh\ntest -s deploy/connector-fleet/.env.qualification\n\nExpected result: preparation ends with connector fleet preparation: PASS.\nThe owner-only environment file records the local source digest, image IDs,\nrelease ID, and release revision selected by Compose.\n\nDefine one helper that always selects the source-owned profile:\n\ncompose() {\n  docker compose \\\n    --profile products \\\n    --env-file deploy/connector-fleet/.env.qualification \\\n    -f deploy/connector-fleet/compose.yml \\\n    \"$@\"\n}\n\ncompose ps --all\n\nStop if the project contains state that must be retained. Do not remove it\nmerely because its name already exists.\n3. Start the Dify path\n\nStart the Dify host and its declared dependency graph:\n\ncompose up --detach --wait --wait-timeout 300 dify-acme-a\ncompose ps --all\n\nExpected result: dify-acme-a, both gateways, the control plane, edge,\nPostgreSQL, and the product fixture are healthy. Initialization, migration,\ngrant, and admission jobs may be exited with status 0.\n\nDo not bypass a failed admission job or start the host under a different\nidentity. Preserve the failed job's bounded logs and correct its source-owned\ninput.\n4. Read application parameters\n\nRoute one signed read through the generated client identity:\n\ncompose run --rm --no-deps \\\n  --entrypoint /usr/local/bin/aipctl \\\n  -e AIPCTLNATIVEPRINCIPALID=service:aipctl:qualification-acme \\\n  -e AIPCTLNATIVETRUSTDOMAIN=fleet.test \\\n  -e AIPCTLNATIVESIGNINGSEEDFILE=/fleet-state/secrets/client-acme-signing-seed.hex \\\n  -e AIPCTLNATIVEPEERDIDFILE=/fleet-state/public/gateway.did \\\n  -e AIPCTLNATIVETLSCAFILE=/caddy-data/caddy/pki/authorities/local/root.crt \\\n  qualification action call \\\n  https://aipd.fleet.test:8443 \\\n  cap:dify:qualification-app:parameters.get \\\n  --action-id actdifyquickstartparameters001 \\\n  --input '{}'\n\nExpected result: the signed response names the Action and capability, reports a\ncompleted result, and contains the deterministic parameter payload.\n\nThis capability uses the application-specific fixture key. It does not expose\nthe key or let the caller choose a different app.\n5. Read the Knowledge catalogue\n\nUse a second Action for the separately credentialed Knowledge API:\n\ncompose run --rm --no-deps \\\n  --entrypoint /usr/local/bin/aipctl \\\n  -e AIPCTLNATIVEPRINCIPALID=service:aipctl:qualification-acme \\\n  -e AIPCTLNATIVETRUSTDOMAIN=fleet.test \\\n  -e AIPCTLNATIVESIGNINGSEEDFILE=/fleet-state/secrets/client-acme-signing-seed.hex \\\n  -e AIPCTLNATIVEPEERDIDFILE=/fleet-state/public/gateway.did \\\n  -e AIPCTLNATIVETLSCAFILE=/caddy-data/caddy/pki/authorities/local/root.crt \\\n  qualification action call \\\n  https://aipd.fleet.test:8443 \\\n  cap:dify:knowledge:qualification-kb:dataset.list \\\n  --action-id actdifyquickstartdatasets001 \\\n  --input '{\"query\":{\"limit\":1}}'\n\nExpected result: the response reports a completed Action and contains the\nfixture dataset listing. The selected Knowledge credential is independent of\nthe application key used in the previous step.\n6. Verify durable Action state\n\nRead the first Action through the second gateway without repeating its provider\nrequest:\n\ncompose run --rm --no-deps \\\n  --entrypoint /usr/local/bin/aipctl \\\n  -e AIPCTLNATIVEPRINCIPALID=service:aipctl:qualification-acme \\\n  -e AIPCTLNATIVETRUSTDOMAIN=fleet.test \\\n  -e AIPCTLNATIVESIGNINGSEEDFILE=/fleet-state/secrets/client-acme-signing-seed.hex \\\n  -e AIPCTLNATIVEPEERDIDFILE=/fleet-state/public/gateway.did \\\n  -e AIPCTLNATIVETLSCAFILE=/caddy-data/caddy/pki/authorities/local/root.crt \\\n  -e AIPCTLNATIVEBEARERTOKENFILE=/fleet-state/secrets/native-bearer-token \\\n  qualification action status \\\n  https://aipd-b.fleet.test:8443 \\\n  actdifyquickstartparameters001 \\\n  --include-result\n\nExpected result: the lifecycle view contains the same terminal Action and\nstored output. This demonstrates shared durable lookup, not gateway failover.\n\nDiagnose before cleanup\n\nCapture bounded state before changing the project:\n\ncompose ps --all\ncompose logs --no-color --tail 200 \\\n  aipd aipd-b control-plane dify-acme-a product-upstream\n\n| Symptom | First check |\n\n| Preparation cannot reach Docker | Repair the daemon, then repeat source and project checks |\n| Port 18443 is occupied | Identify the owner; do not terminate it without confirming scope |\n| Admission exits nonzero | Read that job's bounded log; do not bypass policy |\n| Dify host is unhealthy | Check descriptor files, key files, database, and fixture reachability |\n| App read is unauthorized | Verify the app-key file path without printing its value |\n| Knowledge read is unauthorized | Verify the separate Knowledge-key file path |\n| Second lookup fails | Preserve both gateway and PostgreSQL logs before changing shared state |\n\nThe tutorial does not authorize regenerating identities, weakening TLS,\nprinting credentials, deleting the database, or bypassing admission.\n\nStop and remove the tutorial project\n\nAfter confirming that the fixed project contains no state or evidence that must\nbe retained, remove its containers, network, and volumes:\n\ncompose down --volumes --remove-orphans\n\nReview compose ps --all before this command. Volume removal is intentionally\ndestructive and belongs only to the named disposable tutorial project.\n\nRelated documentation\n• Dify connector overview (../README.md)\n• AIP quickstart (../../../getting-started/quickstart.md)\n• Deploy the connector fleet (../../../guides/deploy-connector-fleet.md)\n• Errors and retry decisions (../../../reference/errors.md)\n• Connector upstream baselines (../../upstream-baselines.md)\n"
  },
  "integrity": {
    "algorithm": "sha256",
    "sourceDigest": "f9191d7183fe674287a618fc8a93eb291dab06bee8852d7e219efac17c6fe52d"
  }
}
