BaseResource attributes
The full reference of class attributes and what they do.
Routing
| Attribute | Type | Default | Description |
|---|---|---|---|
model | Model | None | The Django model the resource maps to. Required for default CRUD handlers (get, post, patch, delete). Leave None for custom-route-only resources (webhooks, RPC, integrations). |
allowed_methods | list[str] | ['delete', 'get', 'patch', 'post'] | HTTP methods the resource accepts. |
rate_limits | list[dict] | None | None | Per-resource declarative rate-limit buckets, on top of the global api/login/abuse limits and the credential-path auto-defense. Each entry is {'key': callable | str, 'limit': int, 'window': int (seconds), 'name': str} โ runs after authentication so callable keys can read self.user. Keys returning None are skipped. Combine short + long windows for "rate limit + lockout" patterns. See Rate limiting. |
routes | list[dict] | None | Custom routes. See Custom routes page. |
authenticated | bool | True | Require session/api-key when True. |
summary | str | None | Short label for OpenAPI / MCP. Used as the noun in generated summaries (List <summary>, Get <summary>, โฆ). Defaults to the class name. |
description | str | None | Long-form description for OpenAPI / MCP. Becomes the tag description in the generated spec. |
mcp_expose | None / bool / list | None | MCP exposure. None (default) exposes every verb in allowed_methods. False hides the resource. List/tuple = explicit verbs (['list', 'get'] for read-only). |
mcp_list_omit_null | bool | False | When True, drops null/empty/zero-decimal fields from list responses on the MCP path โ REST is unaffected. Useful when listing many rows and you want token-efficient responses. The outputSchema still declares every field, so the agent knows what exists. Resolution order: framework default โ MCP['MCP_LIST_OMIT_NULL'] โ resource attribute. |
mcp_edit_omit_null | bool | False | Same as above, applied to get, create, update and custom routes (single-record paths). Resolution order: framework default โ MCP['MCP_EDIT_OMIT_NULL'] โ resource attribute. |
mcp_fields | list | None | Optional whitelist of field names exposed via MCP tools. When set, replaces list_fields / edit_fields for the MCP path only โ REST keeps using its own field lists. Useful for hiding columns from agents while keeping them in the REST UI. |
mcp_fk_expand | dict | None | FK expansion specific to MCP. Same shape as list_related_fields: {'currency': ['id', 'code'], ...}. Augments (not replaces) list_related_fields for MCP list/get calls โ REST is unaffected. Use it to resolve type_id โ type: {id, name} so the agent sees labels, not raw FK ids. |
sensitive_fields | list | None | Fields whose values must never leave the server โ the response masks them with '*********' instead of dropping the key, so callers (REST clients, agents over MCP) still know the field exists. Applies to both REST and MCP outputs symmetrically. The framework already masks password automatically; use this list for project-specific columns (api_key, internal tokens, audit fields, โฆ). For complete removal from the MCP surface (no schema, no value) use the legacy mcp_exclude_fields. |
Field whitelists
| Attribute | Default | Description |
|---|---|---|
list_fields | all concrete columns (FKs as <name>_id) | Columns returned by GET /resource. Default mirrors Model._meta.local_fields โ ForeignKey/OneToOne are emitted as their underlying <name>_id column (e.g. created_by_id, owner_id), so list responses round-trip the FK reference without an explicit override. |
list_exclude_fields | [] | Subtract from list_fields |
edit_fields | all model columns | Columns returned by GET /resource/{id} |
edit_exclude_fields | ['_state'] | Subtract from edit_fields |
create_fields | None | Required for POST. Whitelist of writable fields. |
update_fields | None | Required for PATCH. Whitelist of writable fields. |
filter_fields | None | Whitelist for ?...= and ?filter= JSON expressions. |
search_fields | [] | Columns matched by ?search= |
order_fields | [] | Columns allowed in ?order_by= |
Pagination & ordering
| Attribute | Default | Description |
|---|---|---|
limit | 25 | Page size |
page | 1 | Default page number |
order_by | 'id' | Default ordering when client doesn't specify |
search_operator | 'icontains' | Operator used for ?search= |
Response shape
| Attribute | Default | Description |
|---|---|---|
normalize_list | False | When True, list responses are returned as a dict keyed by id ({"42": {...}}) instead of an array. Also toggleable per request via ?normalize=true or ?normalize_list=true. |
normalize_obj | False | When True, detail responses are wrapped as {"<id>": {...}} instead of the bare object. Useful when the client store indexes by id. |
normalized | False | Internal flag. When the handler returns already-normalized data, set this to skip the default wrapping. |
count_results | False | Internal โ flipped by ?count=true to swap the response for {"count": N}. |
Cache
| Attribute | Default | Description |
|---|---|---|
cache | False | Enable Redis cache for GET responses |
cache_ttl | 120 | Seconds before a cached response expires. Project-level default can be set via settings.CACHE_TTL; an explicit cache_ttl = N on the resource always wins. |
cache_namespace | None | Auto-built (list:<model> / detail:<model>:<id>) |
session_cache | False | Fold session id into the cache key (full per-session isolation) |
cache_scope_fields | None | Dimensions to fold into the cache key from self.user / self.account โ e.g. ['space_id', ('account', 'plan_id')]. Strings are shorthand for ('user', field). Fail-safe: an authenticated request whose session payload is missing a configured field is logged at WARNING (logger zeromcp.base) and cache is disabled for that request (no read, no write). Anonymous requests skip the fold cleanly. See Cache. |
route_cache | False | Whether the matched custom route opted into caching (set from the route definition's cache flag) |
Relations
| Attribute | Default | Description |
|---|---|---|
list_related_fields | None | {relation: [fields]} โ drives select_related on list and shapes nested objects |
edit_related_fields | None | Same shape, applied to detail. M2M relations are detected and emitted as arrays |
list_prefetch_related | None | {relation: [fields]} โ prefetch_related for list, returns arrays of dicts |
edit_prefetch_related | None | Same, applied to detail |
related_models | None | Map of FK name โ resource class. Used by the related-objects walker |
many_to_many_models | None | Map of M2M name โ through-model resource |
Request state (read-only โ set during dispatch)
| Attribute | Type | Description |
|---|---|---|
request | HttpRequest | The current Django request (set in get_method) |
method | str | Lowercased HTTP method (HEAD โ 'get') |
id | str / int | Row id parsed from the URL on detail/PATCH/DELETE |
body | dict | Parsed JSON body, schema-validated when applicable |
user | dict | Authenticated user (session['user']) |
account | dict | Current tenant account |
account_id | int | Active tenant id |
tz | ZoneInfo | Timezone resolved from user.timezone (default 'UTC') |
identifier | str | Client IP, honouring TRUSTED_PROXIES |
obj | Model instance | The row currently being processed (PATCH/DELETE) |
obj_id | int | Id of the most recently created/updated row |
queryset | QuerySet | Current queryset (initialized to model.objects, mutated by hooks) |
diff | dict | {field: {old, new}} โ populated during PATCH for audit logs |
cache_key | str | Final cache key for this request (set when cache=True) |
Auto-populated from the model
These are filled in __init__ from model._meta. Read them in your code; do not assign.
| Attribute | Description |
|---|---|
fields | Names of all non-relation fields on the model |
all_fields | Every local field name + every m2m name (used for auto-fill checks) |
m2m_fields | Many-to-many field names |
Multi-tenant
| Attribute | Default | Description |
|---|---|---|
account_db | 'default' | Active DB connection name (set by aset_tenant) |
Schemas
| Attribute | Default | Description |
|---|---|---|
create_schema | None | Pydantic model used to validate POST body |
update_schema | None | Pydantic model used to validate PATCH body |
list_schema | None | Pydantic model used to shape GET responses |
Ownership & filters
| Attribute | Default | Description |
|---|---|---|
owner_field | None | Column on model that holds the owning user id |
queryset_filter | None | Extra filter applied to every query |
filters | None | Pre-built Q objects mixed in to filtered queries |
0-mcp by Stamatios Stamou Jr โ github.com/ssjunior/0-mcp