cognee.serve()
Description
Connect the local Cognee Python SDK to Cognee Cloud or another remote Cognee API server. Afterserve() connects, high-level SDK operations route to the remote instance instead of local storage. You can call methods on the returned CloudClient, or continue using top-level operations such as cognee.remember(), cognee.recall(), cognee.improve(), and cognee.forget().
Use cognee.disconnect() to clear the active remote client and return the SDK to local mode.
serve() changes where SDK operations execute. It does not copy existing local datasets to the remote instance. Use push() to upload an already-built local graph, or call remember() after connecting to ingest directly into the remote instance.Connection resolution
serve() resolves the remote target in this order:
- Explicit
urlandapi_keyarguments COGNEE_SERVICE_URLandCOGNEE_API_KEYenvironment variables- The saved connection from a previous successful
serve()— reused only when it has both a URL and an API key
serve() raises a CogneeConfigurationError that lists the ways to connect. There is no interactive login.
A resolved url — from either of the first two steps — connects directly and, on success, is saved to ~/.cognee/cloud_credentials.json. Only a bare serve() reaches step 3. A connection made without an API key (a local server with access control off) is saved but not reused: pass its url again.
The saved file holds
service_url, api_key and tenant_id. Files written by older releases still load; their Auth0 tokens and other unknown keys are ignored, but a tenant_id saved by the old cloud login is kept and reused as is.Tenant lookup
After the credential probe accepts the connection,serve() calls GET /api/v1/users/me on the instance and records the tenant_id it reports for the API key’s user. On Cognee Cloud this is your cloud tenant; a self-hosted server reports its own local tenant. The id is saved with the connection and used only to tag telemetry events while the process is connected.
The lookup never fails serve() and delays it by at most 5 seconds: a timeout, a non-200 response or a value that is not a UUID leaves the tenant empty while the connection proceeds. A saved connection without a tenant_id (written by an older release, or saved after a failed lookup) gets the lookup on its next bare serve(), and the result is written back to the file; if that write fails, serve() still connects.
Credentials are verified at connect time
/health is unauthenticated, so it cannot tell a working API key from a rejected one. serve() therefore also probes an authenticated endpoint (GET /api/v1/datasets) before it reports a connection, so a bad key fails here instead of on your first real operation. When a url is resolved (the direct path):
The probe runs over the same HTTP session as every later remote call, and that session honours
HTTP_PROXY / HTTPS_PROXY / NO_PROXY. A key rejected through the proxy (for example, a credential proxy that did not substitute the real key) therefore fails at connect time; an instance the proxy cannot reach is treated like any unreachable instance — a warning, then errors on first use. See Proxy environment variables.
A saved connection goes through the same probe, with one difference: on that path both a rejected key and an unreachable instance raise (the third error below) rather than producing a connection that 401s on every call.
Errors
serve() raises CogneeConfigurationError (importable from cognee.exceptions) in these cases:
- The instance rejected the key —
name="ServeAuthenticationError", the 401/403 case above, on the direct path. Nothing is saved. - Nothing to connect with — a bare
serve()with no environment variables and no saved connection that has an API key.name="ServeConfigurationError"; the message lists the ways to connect. - The saved connection no longer works — a bare
serve()whose saved instance is unreachable or whose API key was rejected. Alsoname="ServeConfigurationError"; the message names the credentials file and the saved instance URL, and suggests deleting the file if the connection is stale.
Passing
url to a server that requires authentication without also passing api_key is a configuration error, not a silent downgrade: the probe returns 401 and serve() raises. A server with its default posture requires authentication — REQUIRE_AUTHENTICATION inherits from ENABLE_BACKEND_ACCESS_CONTROL, which is on by default, and setting it to false alone is ignored while access control is on — so serve(url="http://localhost:8000") needs an API key there. Only a server running with ENABLE_BACKEND_ACCESS_CONTROL=false, which also turns the auth requirement off, falls back to its default user and answers the probe without a key.Parameters
Optional[str]
default:"None"
Remote Cognee instance URL. When omitted, Cognee reads
COGNEE_SERVICE_URL, then the saved connection.Optional[str]
default:"None"
API key for the remote instance. When omitted, Cognee reads
COGNEE_API_KEY. The saved connection’s key is used only by a bare serve() (no url and no COGNEE_SERVICE_URL), which then ignores any api_key or COGNEE_API_KEY you set. A server running with ENABLE_BACKEND_ACCESS_CONTROL=false does not require it.Returns
ACloudClient configured for the connected instance.
The returned client exposes the main remote operations:
method
Ingest data and build memory on the remote instance.
method
Write a single session-memory entry on the remote instance.
method
Query memory from the remote instance.
method
Run enrichment or session-bridging on remote memory.
method
Delete remote data, datasets, or memory state.
method
Ingest data on the remote instance without building the graph.
method
Build the knowledge graph on the remote instance.
method
Query the remote knowledge graph.
method
Replace one document in place on the remote instance via
PATCH /api/v1/update.method
List the documents in a remote dataset via
GET /api/v1/datasets/{dataset_id}/data.Operations that route to the remote instance
While a connection is active, these top-level SDK calls are proxied to the remote instance instead of touching local storage — you do not have to call theCloudClient method yourself:
Routing happens before any local resolution, so these calls work against datasets that exist only on the remote instance, and they write nothing to the local store.
The remote routes accept a narrower parameter surface than their local counterparts.
update() proxies only data_id, data, dataset_id, node_set, and chunk_level_diff; anything else you pass is dropped and the server applies its own configuration. Most of the dropped parameters are named in a logged warning, but user, incremental_loading, and data_cache go silently. See update() for the full list. recall() likewise forwards only part of its parameters; see recall() for which ones.Examples
- Explicit credentials
- Environment variables
- Saved connection
- Local server
Disconnecting
disconnect() closes the active remote connection for the current SDK process. The saved connection is not deleted, so a later bare serve() can reconnect to it when it has an API key that still works. Use cognee-cli serve --logout (or cognee.disconnect(clear_saved=True)) to also delete it.