Skip to main content

Kurd MCP

PyPI Python License: MIT CI

Kurd is a high-performance Model Context Protocol (MCP) gateway for Python, powered by Rust.

The Rust data plane handles HTTP serving, JSON-RPC dispatch, tool routing, upstream aggregation, caching, retries, circuit breaking, backpressure, rate limiting, and Prometheus metrics. The Python layer provides the developer API — tool registration, runtime configuration, and an optional enterprise feature set.

Targets MCP protocol revision 2026-07-28. Fully typed (PEP 561).


Contents


Installation

pip install kurd

Requires Python 3.10+ and a 64-bit platform. Pre-built wheels are available for Windows, Linux (x86-64, aarch64), and macOS (x86-64, Apple Silicon).


Quick Start

from kurd import Router
from kurd._kurd import start_http_gateway

router = Router()

@router.tool()
async def add(a: int, b: int) -> int:
    """Add two integers."""
    return a + b

# Blocks until stop_http_gateway() is called or the process exits.
start_http_gateway("0.0.0.0:9200")

The gateway starts the following endpoints:

Path Method Purpose
/mcp POST JSON-RPC 2.0 MCP endpoint
/health GET Liveness probe — returns 200 OK
/status GET Runtime, cache, upstream, and circuit-breaker snapshot
/metrics GET Prometheus metrics
/admin/servers GET List registered upstream servers
/admin/servers POST Add or replace an upstream server
/admin/servers/{name} DELETE Remove an upstream server
/admin/tools GET List all tools (local + upstream) with source label
/admin/tools/reload POST Expire the tool-list cache immediately
/admin/tools/namespaces GET List upstream namespaces

Call the gateway:

curl -s http://localhost:9200/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"add","arguments":{"a":3,"b":4}}}'
{"jsonrpc":"2.0","id":1,"result":{"resultType":"complete","content":[{"type":"text","text":"7"}],"isError":false}}

CLI

Kurd ships a kurd command installed alongside the package.

Usage: kurd <COMMAND>

Commands:
  serve   Start the HTTP MCP gateway

Options:
  -h, --help  Show this message and exit

kurd serve

kurd serve [--host HOST] [--port PORT] [--token TOKEN]
Flag Default Description
--host 0.0.0.0 Bind address
--port 8000 Bind port
--token Bearer token for authentication (overrides KURD_AUTH_TOKEN)
# Start on port 8000 with no authentication
kurd serve

# Start on a specific address with a bearer token
kurd serve --host 127.0.0.1 --port 9200 --token my-secret

# Use an environment variable for the token
KURD_AUTH_TOKEN=my-secret kurd serve --port 9200

Registering Tools

Decorator API

from kurd import Router

router = Router()

@router.tool()
async def search(query: str, limit: int = 10) -> list[str]:
    """Search the knowledge base."""
    return [f"result {i}" for i in range(limit)]

Type annotations are converted to a JSON Schema inputSchema automatically:

Python type JSON Schema type
int integer
float number
bool boolean
str string
list[T] array with item schema
dict object
Optional[T] / T | None schema of T

Parameters with defaults become optional; parameters without defaults are added to required.

Hot-reloading

Replace a tool's implementation at runtime without restarting the gateway:

router.reload_tool("search", new_search_function)

Unregistering

router.unregister_tool("search")

Introspection

router.list_tools()      # -> ["add", "search", ...]
router.list_upstreams()  # -> [("github", "http://..."), ...]

Mounting Upstream Servers

Kurd aggregates remote MCP servers alongside local tools.

router.mount("github", "http://github-mcp.internal:9300")
router.mount("jira",   "http://jira-mcp.internal:9300")

Upstream tools are prefixed with the upstream name:

github.create_issue
jira.create_ticket

Clients discover all tools — local and upstream — through a single tools/list call. Kurd fetches remote tool lists concurrently, caches them with a configurable TTL, and follows pagination automatically.

Unmounting and cache invalidation

router.unmount("github")   # stop routing to this upstream
router.refresh_tools()     # expire the tool list cache immediately

Upstream behaviour

  • Connection pool: persistent HTTP/1.1 connections via Reqwest
  • Retry: up to 3 attempts with exponential backoff + jitter
  • Circuit breaker: opens after 5 consecutive failures; resets after 30 s
  • Timeout: configurable per RuntimeConfig.upstream_timeout_ms
  • Private-network policy: loopback/private URLs blocked by default unless set_allow_private_upstreams(True) is called

Tool Discovery Filtering

Clients can scope a tools/list call with an optional filter parameter — without any server-side configuration needed.

Namespace filter

Returns only tools belonging to a specific upstream:

{
  "jsonrpc": "2.0", "id": 1, "method": "tools/list",
  "params": { "filter": { "namespace": "github" } }
}

Search filter

Case-insensitive substring match across tool name and description:

{
  "jsonrpc": "2.0", "id": 1, "method": "tools/list",
  "params": { "filter": { "search": "file" } }
}

Discovery metadata

Every tools/list response includes a _kurd object:

{
  "result": {
    "tools": [...],
    "_kurd": { "available": 12, "returned": 3 }
  }
}

available is the count after tenant restrictions; returned is the count after the client filter. An LLM agent can use these counts to know whether to refine its query.

Security: client filters always run after per-tenant restrictions. A tenant cannot use search or namespace to enumerate tools outside their allowlist.


Admin API

The Admin API lets operators manage the gateway at runtime without a restart. All admin endpoints accept an optional Authorization: Bearer <token> header.

Set a dedicated admin token

router.set_admin_token("admin-secret")
# router.clear_admin_token()  # fall back to MCP bearer token / open

Or via the module-level API:

from kurd import set_admin_token, clear_admin_token
set_admin_token("admin-secret")

Manage upstream servers

# List
curl http://localhost:9200/admin/servers

# Add / replace
curl -X POST http://localhost:9200/admin/servers \
  -H 'Content-Type: application/json' \
  -d '{"name": "github", "url": "http://github-mcp.internal:9300/mcp"}'

# Remove
curl -X DELETE http://localhost:9200/admin/servers/github

Response codes: 201 Created (new), 200 OK (replaced), 404 Not Found (delete miss), 400 Bad Request (invalid URL or empty name).

Inspect tools

# All tools with source label
curl http://localhost:9200/admin/tools

# Reload (expire cache)
curl -X POST http://localhost:9200/admin/tools/reload

# List upstream namespaces
curl http://localhost:9200/admin/tools/namespaces

Runtime Configuration

All gateway tunables are collected in RuntimeConfig:

from kurd import Router, RuntimeConfig

router = Router()
router.configure_runtime(RuntimeConfig(
    # Concurrency
    global_concurrency   = 512,   # max simultaneous in-flight requests
    upstream_concurrency = 64,    # max simultaneous upstream calls
    python_concurrency   = 64,    # max simultaneous Python tool calls
    upstream_timeout_ms  = 30_000,

    # Logging
    request_logging      = False, # structured per-request log lines

    # Rate limiting
    rate_limiting_enabled   = True,
    rate_limit_per_ip_rps   = 1_000,
    rate_limit_global_rps   = 10_000,

    # IP allowlist (None = allow all)
    ip_allowlist         = ["192.168.1.0/24", "10.0.0.1"],

    # Tool cache
    tools_cache_ttl_ms   = 30_000,

    # Enterprise (all off by default)
    enable_dlq                  = False,
    enable_idempotency          = False,
    secrets_backend             = "env",
    enable_webhooks             = False,
    enable_distributed_state    = False,
    distributed_state_backend   = "memory",
    redis_url                   = "redis://localhost:6379/0",
    enable_distributed_tracing  = False,
))

configure_runtime also accepts keyword arguments directly for ergonomic one-liners:

router.configure_runtime(request_logging=True, rate_limiting_enabled=True)

Runtime status

status = router.runtime_status()
# {
#   "global_active": 3,
#   "global_limit": 512,
#   "python_active": 1,
#   "upstream_metrics": {...},
#   "cache": {"hits": 142, "misses": 3},
#   ...
# }

Security

Bearer token authentication

Set a bearer token before starting the gateway. Requests missing or carrying a wrong token receive 401 Unauthorized.

from kurd._kurd import set_http_bearer_token, clear_http_bearer_token

set_http_bearer_token("my-production-token")
# clear_http_bearer_token()  # disable authentication

Via environment variable (loaded automatically at gateway start):

KURD_AUTH_TOKEN=my-production-token kurd serve

Tokens are compared with a constant-time byte comparison to prevent timing attacks.

IP allowlist

from kurd import set_ip_allowlist, clear_ip_allowlist

set_ip_allowlist(["10.0.0.1", "10.0.0.2"])
clear_ip_allowlist()  # allow all IPs again

Or through RuntimeConfig.ip_allowlist. Blocked IPs receive 403 Forbidden.

Rate limiting

router.configure_runtime(
    rate_limiting_enabled=True,
    rate_limit_per_ip_rps=1_000,
    rate_limit_global_rps=10_000,
)

Rate-limited requests receive 429 Too Many Requests with a Retry-After: 1 header and a retryAfterMs field in the JSON-RPC error body.

Additional safeguards

Safeguard Details
Request size cap 1 MiB hard limit; 413 on excess
Content-type validation Must be application/json; -32600 otherwise
Upstream URL validation Rejects credentials, fragments, and unsupported schemes
Private-network policy Upstream calls to loopback/RFC1918 blocked by default
CORS OPTIONS /mcp returns correct preflight headers; POST responses include Access-Control-Allow-Origin: *
Overload rejection 503 when global concurrency limit is reached

For internet-facing deployments, terminate TLS at a reverse proxy (nginx, Caddy, AWS ALB) and apply network-level controls there.


Multi-tenancy & Policy Engine

Kurd ships a built-in TenantManager that wires directly into the Rust request hot path. One call to set_policy_engine() activates both tools/call gating and tools/list filtering simultaneously.

Basic setup

from kurd import Router, TenantManager

manager = TenantManager()

# Add tenants with explicit tool allowlists
manager.add_tenant("acme",   name="Acme Corp",  allowed_tools=["add", "search"], api_key="sk-acme")
manager.add_tenant("devops", name="DevOps Team", allowed_tools=["*"],            api_key="sk-ops")

router = Router()
router.set_policy_engine(manager)
# router.clear_policy_engine()  # disable, all requests allowed again

What it enforces

Behaviour Details
tools/call gating Unknown API key or tool outside allowlist → 403 Forbidden (JSON-RPC -32004)
tools/list filtering Response contains only the tools the caller may invoke
Wildcard support "*" in allowed_tools passes all tools through
Namespace wildcard "github.*" passes all tools prefixed github.
Unknown key Returns an empty tools list and 403 on any tools/call

Calling with a tenant key

curl http://localhost:9200/mcp \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer sk-acme' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# → returns only ["add", "search"]

Prometheus metric

kurd_policy_denied_total   # counter — requests blocked by the policy engine

Per-tenant quotas and billing

For rate-per-tenant quotas, request tracking, and billing see the Enterprise Features section.


Observability

Structured logging

Enable per-request log lines (goes to stdout in the format chosen by KURD_LOG):

router.configure_runtime(request_logging=True)

Control log verbosity via environment variable:

KURD_LOG=kurd=debug kurd serve   # debug, info, warn, error
RUST_LOG=info kurd serve         # fallback if KURD_LOG is unset

Log level can also be changed at runtime via the logging/setLevel MCP method.

Prometheus metrics

curl http://localhost:9200/metrics
Metric Type Description
kurd_requests_total{status} counter Total requests by status (total, completed, rejected)
kurd_policy_denied_total counter Requests blocked by the policy engine (-32004)
kurd_requests_active gauge In-flight requests right now
kurd_requests_peak_active gauge Highest concurrent request count since startup
kurd_request_latency_ms gauge Rolling average latency (ms)
kurd_request_latency_histogram_ms_bucket{le} histogram Latency distribution (1ms … 5000ms + Inf)
kurd_request_latency_histogram_ms_count counter Total completed requests counted in histogram
kurd_request_latency_histogram_ms_sum counter Total latency (ms) summed across all requests
kurd_python_active_calls gauge Active Python tool invocations
kurd_python_peak_active_calls gauge Peak simultaneous Python tool invocations
kurd_python_rejections_total counter Python tool calls dropped due to concurrency limit
kurd_upstream_requests_total{upstream} counter Requests forwarded per upstream
kurd_upstream_successes_total{upstream} counter Successful upstream calls
kurd_upstream_failures_total{upstream} counter Failed upstream calls
kurd_upstream_retries_total{upstream} counter Retry attempts per upstream
kurd_upstream_latency_ms{upstream} gauge Average upstream round-trip latency
kurd_upstream_circuit_breaker_state{upstream} gauge 0 = closed, 1 = open
kurd_upstream_active_calls{upstream} gauge Current in-flight calls per upstream
kurd_upstream_peak_active_calls{upstream} gauge Peak in-flight calls per upstream
kurd_upstream_rejections_total counter Upstream calls dropped due to concurrency limit
kurd_cache_hits_total counter Tool-list cache hits
kurd_cache_misses_total counter Tool-list cache misses
kurd_cache_invalidations_total counter Cache invalidations (manual or TTL expiry)
kurd_concurrency_limit{type} gauge Configured limits: global, upstream, python

Prometheus scrape config

# prometheus.yml
scrape_configs:
  - job_name: kurd
    static_configs:
      - targets: ["localhost:9200"]
    metrics_path: /metrics
    scrape_interval: 15s

Datadog

# datadog.yaml
instances:
  - openmetrics_endpoint: http://localhost:9200/metrics
    namespace: kurd
    metrics: ["kurd_.*"]

OpenTelemetry

Kurd exports real OTLP spans from the Rust core — no Python OpenTelemetry SDK required.

Quick setup

from kurd import Router
from kurd.telemetry import setup_otel

router = Router()

# Activates Rust-side OTLP export. setup_otel returns an OTELTracer for
# any additional Python-side instrumentation you want.
setup_otel(
    service_name = "my-gateway",
    endpoint     = "http://otel-collector:4318",  # OTLP HTTP receiver
)

Or directly via the Router:

router.configure_otel("http://otel-collector:4318", service_name="my-gateway")
# router.clear_otel()  # disable export

What gets traced

  • Every request that passes authentication, rate limiting, and concurrency checks produces one server-side span.
  • Spans are exported fire-and-forget (2-second timeout, errors silently dropped) so a slow or unavailable collector never adds latency.
  • The OTLP JSON payload is sent to {endpoint}/v1/traces.

W3C traceparent propagation

Every MCP response carries a traceparent header so downstream services and LLM agents can continue the trace:

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

If the incoming request already carries a traceparent, Kurd preserves the trace_id and issues a new span_id. Malformed headers start a fresh trace.

OTELConfig.service_version defaults to the installed kurd package version automatically.

Health checks

from kurd.health_checks import HealthCheckManager

hc = HealthCheckManager()

# Register a custom check
async def check_db():
    ...

hc.register_check("database", check_db, critical=True)

# Kubernetes probes
readiness = await hc.check_readiness()  # all critical checks pass
liveness  = await hc.check_liveness()   # process is running and active

MCP Protocol Compliance

Kurd implements the MCP 2026-07-28 protocol revision.

Supported methods

Method Behaviour
initialize Returns protocolVersion, capabilities, and serverInfo
ping Returns {}
server/discover Returns capabilities, supported versions, and server identity
tools/list Aggregates local + upstream tools; cursor-based pagination; params.filter.namespace / params.filter.search; _kurd metadata; per-tenant filtering when policy engine is active
tools/call Routes to local Python tool or upstream server; policy engine gate when active
resources/list Returns empty list with ttlMs and cacheScope
resources/read Returns {"contents": []}
prompts/list Returns empty list with ttlMs and cacheScope
prompts/get Returns -32602 (gateway holds no prompts)
completion/complete Returns {"values": [], "hasMore": false}
logging/setLevel Applies log level to the tracing filter at runtime
notifications/* Accepted silently — returns 202 Accepted with empty body

Modern HTTP headers

When a client sends Mcp-Protocol-Version: 2026-07-28, Kurd additionally validates:

  • Mcp-Method header matches the JSON-RPC method field
  • Mcp-Name header matches params.name for tools/call

Mismatched headers return -32020. Unsupported protocol versions return -32019.


Enterprise Features

Enable features through RuntimeConfig or by importing the relevant manager class directly.

Multi-tenancy

See Multi-tenancy & Policy Engine above for the full policy engine and tool-filtering setup.

from kurd import TenantManager

manager = TenantManager()
manager.add_tenant(
    tenant_id="acme",
    name="Acme Corp",
    quota_rps=100,
    allowed_tools=["add", "search"],
    api_key="sk-acme",
)

Each tenant receives a unique API key. Quotas and tool ACLs are enforced independently.

Billing

from kurd.billing import BillingManager

billing = BillingManager()
billing.set_pricing({"add": {"per_call": 0.001, "per_latency_ms": 0.0001}})
billing.track_call(tenant_id="acme", tool_name="add", latency_ms=12.5, success=True)

report = billing.get_usage_report("acme", period="2026-08")

Supported models: per-request, per-latency, tiered, hybrid.

Request idempotency

router.configure_runtime(enable_idempotency=True)
mgr = router.get_idempotency()

is_dup, cached = mgr.check_idempotent_key("req-abc-123", tenant_id="acme")
if is_dup:
    return cached

result = run_tool()
mgr.store_result("req-abc-123", "acme", result)

Backed by SQLite with a 24-hour TTL.

Dead-letter queue

router.configure_runtime(enable_dlq=True, dlq_storage_path="/data/kurd/dlq")
dlq = router.get_dlq()

dlq.add_message(request_id="req-123", tenant_id="acme",
                tool_name="add", arguments={"a":1,"b":2}, error="timeout")

dlq.register_replay_handler("add", handler)
success, error = dlq.replay_message("dlq_abc123")

stats = dlq.get_statistics(tenant_id="acme")
dlq.cleanup_archived(days=30)

Replay uses exponential backoff up to 1 hour.

Secrets management

from kurd.secrets_management import SecretsManager

# Kubernetes in-cluster | HashiCorp Vault | AWS Secrets Manager | env (default)
manager = SecretsManager(backend="vault",
                          vault_addr="https://vault.example.com",
                          vault_token="s.xxxxx")

secret = manager.get_secret("db_password")

Third-party dependencies (kubernetes, hvac, boto3) are imported lazily — only when the matching backend is activated.

Webhooks

router.configure_runtime(enable_webhooks=True)
hooks = router.get_webhooks()

hooks.register_webhook(
    url="https://example.com/hooks",
    events=["error", "rate_limit_exceeded"],
    tenant_id="acme",
)

Deliveries are HMAC-SHA256 signed and logged for audit via get_deliveries().

Distributed state

router.configure_runtime(
    enable_distributed_state=True,
    distributed_state_backend="redis",
    redis_url="redis://localhost:6379/0",
)
state = router.get_distributed_state()
state.set("gateway:version", 42)
state.increment("counters:acme:calls")

Use backend="memory" for single-instance deployments.

Distributed tracing

from kurd.distributed_tracing import extract_context

trace = extract_context(incoming_headers)
span  = trace.create_span("tool_execution", {"tool": "add"})
span.set_attribute("result", 42)
span.end()

Follows W3C Trace Context. Tracing state is available in router.runtime_status() when enabled.


Performance

Benchmarks from a Windows development machine (Python 3.12, release build):

Scenario Concurrency Throughput p50 p95 p99 Errors
Local Python tool 10 594.5 req/s 14.9 ms 23.9 ms 28.7 ms 0%
Local Python tool 50 587.9 req/s 33.3 ms 87.8 ms 119.1 ms 0%
Local Python tool 100 556.0 req/s 18.3 ms 29.5 ms 32.4 ms 0%
Upstream tool 10 412.2 req/s 21.8 ms 36.4 ms 42.7 ms 0%
Upstream tool 50 229.8 req/s 20.6 ms 534.6 ms 549.3 ms 0%
Sustained burst 100 573.3 req/s 73.5 ms 179.1 ms 218.5 ms 0%

Results depend on hardware, OS, Python version, and network conditions.

python -m pytest tests/test_load.py -q -s

Architecture

Python application
       │
       ▼
  kurd.Router                      ← Python API layer
       │
       ├── Policy engine (set_policy_engine)
       │   TenantManager callbacks wired into Rust hot path
       │
       ├── Enterprise modules (optional, lazy)
       │   multitenancy · billing · idempotency · DLQ
       │   secrets · webhooks · distributed state
       │
       ▼
   PyO3 boundary
       │
       ▼
  Rust MCP gateway (Axum + Tokio)
       │
       ├── HTTP handler  ─────────────────────────────────┐
       │   content-type · auth · IP allowlist              │
       │   rate limiting · concurrency backpressure        │
       │   CORS · request ID · W3C traceparent             │
       │   OTLP span export (fire-and-forget)              │
       │                                                   │
       ├── Admin API (/admin/*)                            │
       │   server CRUD · tool listing · cache reload       │
       │                                                   │
       ├── MCP dispatcher                                  │
       │   initialize · ping · server/discover             │
       │   tools/list (paginated, filtered, _kurd meta)    │
       │   tools/call (policy gate) · resources · prompts  │
       │   completion · logging · notifications (202)      │
       │                                                   │
       ├── Local Python tools ◄── PyO3 callback            │
       │   (Rayon-parallel batch parsing)                  │
       │                                                   │
       └── Upstream MCP servers                           │
           retry · circuit breaker · cache · metrics      ◄┘

The Rust layer holds all mutable gateway state in lock-free atomics and RwLock-guarded maps. Python code never touches the hot path after registration.


Development

Prerequisites

  • Rust stable toolchain (rustup update stable)
  • Python 3.10+
  • maturin and pytest
pip install maturin pytest

Build

# Development build (fast iteration)
maturin develop

# Optimised build (benchmarks, pre-release testing)
maturin develop --release

# Release wheel
maturin build --release

Test

python -m pytest -q

The test suite covers:

  • JSON-RPC parsing and fast batch parsing (Rayon)
  • Local sync and async tools
  • initialize handshake and lifecycle methods
  • tools/list pagination
  • completion/complete, notifications/202, CORS preflight
  • Upstream discovery, routing, and concurrency
  • Circuit breaker, retry, and timeout behaviour
  • Tool-list cache hits, misses, and invalidation
  • Bearer authentication (accepted and rejected)
  • IP allowlist enforcement
  • Rate-limit rejection and Retry-After header
  • Request-size and content-type guards
  • Prometheus metrics output
  • Load and burst behaviour
  • Policy engine: allow, deny, unknown key, clear (P0)
  • Admin API: server CRUD, tool listing, reload, auth token (P1)
  • Per-tenant tool filtering: wildcard, restricted, unknown key, clear (P2)
  • Client tool discovery: namespace filter, search, combined, _kurd metadata, bypass prevention (P3)
  • OpenTelemetry: traceparent presence/format, trace-id propagation, span-id rotation, malformed input, enable/disable (P4)

Linting

cargo check
cargo clippy -- -D warnings

Environment variables

Variable Purpose
KURD_AUTH_TOKEN Bearer token loaded automatically at gateway start
KURD_LOG Tracing filter (e.g. kurd=debug). Takes precedence over RUST_LOG
RUST_LOG Standard Rust log filter fallback

Project Structure

kurd-mcp/
├── kurd/
│   ├── __init__.py            # Public API + __version__
│   ├── py.typed               # PEP 561 marker
│   ├── cli.py                 # `kurd serve` entry point
│   ├── router.py              # Router class + RuntimeConfig
│   ├── telemetry.py           # OpenTelemetry integration
│   ├── health_checks.py       # Readiness and liveness probes
│   ├── authorization.py       # RBAC helpers
│   ├── multitenancy.py
│   ├── billing.py
│   ├── idempotency.py
│   ├── dead_letter_queue.py
│   ├── secrets_management.py
│   ├── webhooks.py
│   ├── distributed_state.py
│   ├── distributed_tracing.py
│   └── ...
├── src/
│   └── lib.rs                      # Rust data plane (~3500 lines)
├── tests/
│   ├── test_core.py
│   ├── test_http_gateway.py        # Integration tests (module-scoped gateway)
│   ├── test_admin_api.py           # P1 — Admin HTTP API
│   ├── test_tool_filtering.py      # P2 — Per-tenant tools/list filtering
│   ├── test_tool_discovery.py      # P3 — Client-requested filter + _kurd metadata
│   ├── test_otel.py                # P4 — traceparent / OTLP export
│   ├── test_upstream.py
│   ├── test_load.py
│   ├── test_prometheus_metrics.py
│   └── upstream_server.py          # In-process upstream fixture
├── Cargo.toml
├── pyproject.toml
├── LICENSE
└── README.md

Contributing

Issues and pull requests are welcome via the GitHub repository.

Before submitting:

cargo check
cargo clippy -- -D warnings
maturin develop --release
python -m pytest -q

Please open an issue before starting large changes.


License

MIT — Copyright © 2024 Semko Kermashani


The name Kurd honors Kurdish identity and heritage. Bezhi Kurd u Kurdistan.

Download files

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

Source Distribution

kurd-0.7.0.tar.gz (137.8 kB view details)

Uploaded Source

Built Distributions

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

kurd-0.7.0-cp313-cp313-win_amd64.whl (2.6 MB view details)

Uploaded CPython 3.13Windows x86-64

kurd-0.7.0-cp313-cp313-manylinux_2_28_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

kurd-0.7.0-cp313-cp313-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

kurd-0.7.0-cp312-cp312-win_amd64.whl (2.6 MB view details)

Uploaded CPython 3.12Windows x86-64

kurd-0.7.0-cp312-cp312-manylinux_2_28_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

kurd-0.7.0-cp312-cp312-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

kurd-0.7.0-cp311-cp311-win_amd64.whl (2.6 MB view details)

Uploaded CPython 3.11Windows x86-64

kurd-0.7.0-cp311-cp311-manylinux_2_28_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

kurd-0.7.0-cp311-cp311-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

kurd-0.7.0-cp310-cp310-win_amd64.whl (2.6 MB view details)

Uploaded CPython 3.10Windows x86-64

kurd-0.7.0-cp310-cp310-manylinux_2_28_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

kurd-0.7.0-cp310-cp310-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file kurd-0.7.0.tar.gz.

File metadata

  • Download URL: kurd-0.7.0.tar.gz
  • Upload date:
  • Size: 137.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for kurd-0.7.0.tar.gz
Algorithm Hash digest
SHA256 030983a47f1cf88d2636eaee9bbc3170dfb154c6e3152f851e3e7453bb337faf
MD5 50399a4342320f0c5b80a3adac1aaf21
BLAKE2b-256 8efca725f495902d68f57d9def602f3e5bfb9223b66cbca5b31d68e6f78a3d97

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0.tar.gz:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: kurd-0.7.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for kurd-0.7.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 e243e8d8fa33748f2abd73cd3135a211e2be3d7bbb33a7a6534f4b2d6e4fea93
MD5 7cbbe33a21b3ad21f138bd41711851b7
BLAKE2b-256 da630aea70623be9ef362ab34f4f0c31d83e4416ba00b258ba1ce09470a62564

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp313-cp313-win_amd64.whl:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for kurd-0.7.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 34a7c6fbbbd9f1456d2ec623aa2e19f416167cba211378a4b949a614c9d6a489
MD5 c1d4c89a8e4d7369a2d201da0648b1c7
BLAKE2b-256 2a4b9af1bf32d996788311ad6dd05a8b0145fdca63a2395ffc6d497d9c9d23e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp313-cp313-manylinux_2_28_x86_64.whl:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for kurd-0.7.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7fc1ddc5a1d66d183c8f4db0dea2a7b4ed8a6c59187137eb51ad9c0eb96394ae
MD5 a4157013e9a77252cb8b7da6ec042adf
BLAKE2b-256 8215ee564b386e1cbe2942344db8322b4d1940e7be15949fab22e75695094234

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: kurd-0.7.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for kurd-0.7.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 75c2d5f3dd488a6d1d3edacdb7ae3f071dc4f91d4df257ebf1c79f5b2280a5eb
MD5 5a59fd38dd28e7dbc77cdb9ecbbf4213
BLAKE2b-256 c9cefc4bf7b3f25e4b5f65e480fb9498015d20a040947e9b1df6da88dd0d70b9

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp312-cp312-win_amd64.whl:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for kurd-0.7.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0dcefb0aeef5be8e33375713e4e8aba6e2825d935902b263e02bbf810954a2f2
MD5 9e122f3cb6a878e73cca4e913c226f89
BLAKE2b-256 1cba3c81b36640f808329d6f645603b33d0b571c488244b8a6fd3a3a9348956f

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp312-cp312-manylinux_2_28_x86_64.whl:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for kurd-0.7.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9d7876c2c3c90e2c062561bc979c4ac1caef2940095848e6a44052da9ba39501
MD5 89a899b961593bf86a97ffd588a79f40
BLAKE2b-256 ca35695a478fee1e45cba49b1e186da7b7c0bc51120fb7081eb22653d618b962

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: kurd-0.7.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for kurd-0.7.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 50de8cf428944d3f3386738f429a4810e6e6f14fa8b0093d53e3ba17bd2af05f
MD5 fab2ed443ab43a5967444a68575fb050
BLAKE2b-256 917433eb2079872d0238f8b684d0d2b773051e2e74cfd15f955550c4b7d686c5

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp311-cp311-win_amd64.whl:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for kurd-0.7.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d46c977513f95dfb7afb77f20bf2a77711a13b54503df45fa86840d2b0ef4ba2
MD5 d0f76ad1eef5f9de409e491f72b8d131
BLAKE2b-256 0385b14ddaa1348109461a5a8914d0ed8bd93720a50ecbc6dd2522b7a49d2aa6

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp311-cp311-manylinux_2_28_x86_64.whl:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for kurd-0.7.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7b55efa804b1e3c3ace6044e9ae851f1c6b174424c3a5ea597c8fc389c833d33
MD5 e182e04b693378d74a8bf45b5280bc23
BLAKE2b-256 e23ccda2cd20fbcb72f6351be11854cdaf23b86145aa632b27f18427c9cf0e08

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: kurd-0.7.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for kurd-0.7.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 0c0052dcb44faf43dbb23fce1dba7b2e962ccf9263fc7241871d8467a69a7330
MD5 898be14038ffb538d64b0de25e6e5945
BLAKE2b-256 7a731fc794bf45cc2ced63a3b4a6f80f4e9a219f4b16125952296d19e2e26306

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp310-cp310-win_amd64.whl:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for kurd-0.7.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b4fd52b21c6eaf2a84184cc8c3c6f7ecff088415978655baa5f605183566ba4f
MD5 c0178fb5286bb3cde9463766fa9d0b02
BLAKE2b-256 746db2e0d43291b55a4c7d0bb933d62c326ba9569ccc540252095e2ca91713bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp310-cp310-manylinux_2_28_x86_64.whl:

Publisher: release.yml on sn391/kurd

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

File details

Details for the file kurd-0.7.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for kurd-0.7.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0032185ad410d2f0d5acff12199f431e21a7bb906f04d30c2036f2e9a14b91f7
MD5 26df9b0bf7ec582b19bf0da022b4865d
BLAKE2b-256 47f40184e6831ec77c6b005d97a518af4af1f86b00bdd1cb4eb6da2e015f9985

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurd-0.7.0-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: release.yml on sn391/kurd

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

Release history Release notifications | RSS feed

This release

0.7.0 This release

13 files

0.6.0

13 files

0.5.0

13 files

0.4.0

4 files

0.3.0

4 files

0.2.0

4 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page