Skip to main content

Python client for the Context Surfaces API — manage context surfaces, Redis instances, and invoke MCP tools. Includes an optional CLI (ctxctl).

Project description

Context Surfaces Python Client

Python client for the Context Surfaces API with MCP (Model Context Protocol) support. Includes the ctxctl CLI for managing context surfaces, Redis instances, and MCP tools.

Contents

What is a context surface

A context surface is a configurable layer that connects your data (often in Redis) to MCP tools so applications and agents can query, filter, and retrieve information through a consistent API. You use context surfaces to define data models, generate tools, and securely operate those tools with agent keys.

When to use this package

Use context-surfaces when you need to:

  • Provision and manage context surfaces and admin/agent keys
  • Connect Redis instances that back context surfaces
  • Define data models that generate MCP tools
  • Invoke MCP tools from Python or the CLI

Key features

  • Complete API coverage for admin keys, context surfaces, agent keys, Redis instances, and MCP tools
  • Async-first client built on httpx with retries
  • Type-safe models via Pydantic v2
  • CLI (ctxctl) with secure credential storage and rich output formats
  • Unified client for API + MCP workflows

Installation

Requires Python 3.11+.

pip install context-surfaces

Optional with uv:

uv pip install context-surfaces

Common concepts

  • Provisioning auth: Use an admin API key to create and manage resources.
  • Agent auth: Agent keys are used to invoke MCP tools.

Python client

Quickstart

import asyncio
from context_surfaces import ContextSurfacesClient

async def main():
    async with ContextSurfacesClient() as client:
        health = await client.health()
        print(health.status)

asyncio.run(main())

Quickstart (Unified API + MCP)

import os

from context_surfaces import UnifiedClient

async with UnifiedClient() as client:
    admin_key = os.getenv("CTX_ADMIN_KEY")
    if not admin_key:
        raise RuntimeError("Set CTX_ADMIN_KEY before running this example.")
    surface = await client.create_context_surface(admin_key, "My Surface", data_model={...})
    agent_key = await client.create_agent_key(admin_key, surface.id, "Agent")
    result = await client.query_tool(agent_key.key, "search_customer_by_text", {"query": "john"})

Data model example (models.py)

Context surfaces can generate tools from a data model. A minimal models.py might look like:

from context_surfaces.context_model import ContextField, ContextModel


class Customer(ContextModel):
    __redis_key_template__ = "customer:{id}"

    id: int = ContextField(description="Customer ID", is_key_component=True)
    email: str = ContextField(description="Email address", index="text")
    city: str = ContextField(description="City", index="tag")

You can pass this file to the CLI with --models ./models.py, or use it in Python to generate a data_model for create_context_surface.

Import data with UnifiedClient (recommended)

Use UnifiedClient.import_data(...) to ingest validated ContextModel records through the API. This keeps key templates, schema validation, and indexes aligned with your context surface configuration. Avoid writing records directly to Redis unless you are intentionally managing the full storage/index contract yourself.

import asyncio
import os

from context_surfaces import UnifiedClient
from models import Customer


async def main() -> None:
    admin_key = os.getenv("CTX_ADMIN_KEY")
    surface_id = os.getenv("CTX_SURFACE_ID")
    if not admin_key or not surface_id:
        raise RuntimeError("Set CTX_ADMIN_KEY and CTX_SURFACE_ID before running this example.")

    records = [
        Customer(id=1, email="john@example.com", city="Berlin"),
        Customer(id=2, email="jane@example.com", city="Madrid"),
    ]

    async with UnifiedClient() as client:
        result = await client.import_data(
            admin_key=admin_key,
            context_surface_id=surface_id,
            records=records,
            on_conflict="overwrite",
            on_error="fail_fast",
        )
        print(f"Imported: {result.imported}, Failed: {result.failed}")


asyncio.run(main())

Connect Redis and create a context surface (Python)

import os

from context_surfaces import (
    ContextSurfacesClient,
    CreateContextSurfaceRequest,
    RedisConnectionConfig,
    RegisterRedisInstanceRequest,
)

async with ContextSurfacesClient() as client:
    admin_key = os.getenv("CTX_ADMIN_KEY")
    if not admin_key:
        raise RuntimeError("Set CTX_ADMIN_KEY before running this example.")

    redis_instance = await client.register_redis_instance(
        RegisterRedisInstanceRequest(
            name="Example Support Redis",
            connection_config=RedisConnectionConfig(
                addr="redis-12345.example.redis.cloud:6380",
                username="default",  # Optional: omit if your Redis uses default user
                password=os.getenv("REDIS_PASSWORD", ""),
                db=0,
                tls_enabled=True,
            ),
        ),
        admin_key=admin_key,
    )

    surface = await client.create_context_surface(
        CreateContextSurfaceRequest(
            name="Support",
            data_model={...},
            redis_instance_id=redis_instance.id,
        ),
        admin_key=admin_key,
    )

Authentication (Python clients)

For both ContextSurfacesClient and UnifiedClient, authentication is API-key based. The admin key is passed as an argument to each admin operation and is sent as the X-API-Key request header:

import os

from context_surfaces import ContextSurfacesClient, CreateContextSurfaceRequest

async with ContextSurfacesClient() as client:
    admin_key = os.getenv("CTX_ADMIN_KEY")
    if not admin_key:
        raise RuntimeError("Set CTX_ADMIN_KEY before running this example.")
    surface = await client.create_context_surface(
        CreateContextSurfaceRequest(name="Support", data_model={...}, redis_instance_id="ri-123"),
        admin_key=admin_key,
    )

Use an existing admin key created outside the Python client, for example via Redis Cloud console or ctxctl.

CLI

Quickstart

# Verify installation
ctxctl --help

# Authenticate with an admin key (stored in OS keyring)
ctxctl auth login --admin-key <key>

# Create a context surface
ctxctl surface create --name "Support" --models ./models.py --redis-instance-id ri-123

# Create an agent key for the surface (save the key from output!)
ctxctl agent create --name "Support Agent" --surface-id <surface-id>

# List MCP tools and call one
ctxctl tools list --agent-key <agent-key>
ctxctl tools call search_customer_by_text --query john --limit 10

# Filter query example (use exact parameter names from the tool schema)
ctxctl tools call filter_customer_by_city \
  --agent-key <key> \
  --value Berlin \
  --limit 5

When calling tools, use argument names exactly as defined by the tool input schema. If a schema field uses underscores, pass the same underscore form in CLI flags.

Connect Redis and create a context surface (CLI)

# Create Redis instance and capture the ID from command output
ctxctl redis create \
  --name "Example Support Redis" \
  --addr "redis-12345.example.redis.cloud:6380" \
  --username "default" \
  --password "$REDIS_PASSWORD" \
  --tls

# Create surface using that Redis instance ID
ctxctl surface create --name "Support" --models ./models.py --redis-instance-id <redis-instance-id>

# Create an agent key for the surface
ctxctl agent create \
  --name "Support Agent" \
  --surface-id <surface-id>

Important: Save the agent key output securely - it cannot be retrieved later!

You can also pass the admin key explicitly instead of using stored credentials:

ctxctl agent create \
  --name "Support Agent" \
  --surface-id <surface-id> \
  --admin-key <admin-key>

Optional parameters for agent keys:

# With description
ctxctl agent create \
  --name "Analytics Agent" \
  --surface-id <surface-id> \
  --description "Agent for analytics dashboard"

# With access tags for multi-tenant filtering
ctxctl agent create \
  --name "Tenant Agent" \
  --surface-id <surface-id> \
  --access-tags '{"tenant": ["acme"]}'

Authentication and configuration

  • Admin keys or Redis Cloud sessions (Service Manager credentials) are required for provisioning resources.
  • Agent keys are used for querying MCP tools.
  • CLI credentials are stored securely in the OS keyring and can be overridden via env vars.

Common configuration options:

# Config file location
export CTX_CONFIG_FILE=~/.config/ctxctl/config.yaml

# Auth override
export CTX_ADMIN_KEY=<key>

You can inspect and update config with ctxctl config show and ctxctl config set <key> <value>.

Redis Cloud session login (CLI)

If you have Redis Cloud credentials, you can create a session and use it for admin operations:

ctxctl auth login --username user@example.com
ctxctl admin create --name "My Admin Key"

Verify setup

After provisioning and import, validate the full path in a few quick checks:

  1. Confirm tools are available:
ctxctl tools list --agent-key <agent-key>
  1. Run one filter query:
ctxctl tools call filter_customer_by_city \
  --agent-key <agent-key> \
  --value Berlin \
  --limit 5
  1. Validate the response shape includes result metadata and records: count, results, and pagination fields such as has_more/total_count.

Common workflows

  1. Create an admin key via Redis Cloud console or ctxctl
  2. Create a context surface backed by a Redis instance
  3. Create an agent key for the surface
  4. Invoke MCP tools with the agent key

License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

context_surfaces-0.0.1.tar.gz (246.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

context_surfaces-0.0.1-py3-none-any.whl (65.0 kB view details)

Uploaded Python 3

File details

Details for the file context_surfaces-0.0.1.tar.gz.

File metadata

  • Download URL: context_surfaces-0.0.1.tar.gz
  • Upload date:
  • Size: 246.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for context_surfaces-0.0.1.tar.gz
Algorithm Hash digest
SHA256 f9ff032e401a3fb6c67d20898adf3ffe5170ada445b9adeae33dc0dcca4883fb
MD5 282624ae10b785fadc1caf56576c59a3
BLAKE2b-256 fcf632c9b5ee627cbf200d0a54d4744354e67a13100f30e1237701aa99f82720

See more details on using hashes here.

Provenance

The following attestation bundles were made for context_surfaces-0.0.1.tar.gz:

Publisher: python-publish.yml on redislabsdev/cloud-context-engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file context_surfaces-0.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for context_surfaces-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 24037fc184d3f8cccb203f1ca040b876d371523f4a325d2e9e599a474207e14c
MD5 9841db5d443753ed02e0bd443c4cf73a
BLAKE2b-256 830f32182988659782c59babdc132d73076d8027bad11feaf78dcaa63a7d1f15

See more details on using hashes here.

Provenance

The following attestation bundles were made for context_surfaces-0.0.1-py3-none-any.whl:

Publisher: python-publish.yml on redislabsdev/cloud-context-engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page