BaseResource attributes

The full reference of class attributes and what they do.

Routing

AttributeTypeDefaultDescription
modelModelNoneThe 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_methodslist[str]['delete', 'get', 'patch', 'post']HTTP methods the resource accepts.
rate_limitslist[dict] | NoneNonePer-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.
routeslist[dict]NoneCustom routes. See Custom routes page.
authenticatedboolTrueRequire session/api-key when True.
summarystrNoneShort label for OpenAPI / MCP. Used as the noun in generated summaries (List <summary>, Get <summary>, โ€ฆ). Defaults to the class name.
descriptionstrNoneLong-form description for OpenAPI / MCP. Becomes the tag description in the generated spec.
mcp_exposeNone / bool / listNoneMCP 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_nullboolFalseWhen 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_nullboolFalseSame 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_fieldslistNoneOptional 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_expanddictNoneFK 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_fieldslistNoneFields 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

AttributeDefaultDescription
list_fieldsall 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_fieldsall model columnsColumns returned by GET /resource/{id}
edit_exclude_fields['_state']Subtract from edit_fields
create_fieldsNoneRequired for POST. Whitelist of writable fields.
update_fieldsNoneRequired for PATCH. Whitelist of writable fields.
filter_fieldsNoneWhitelist for ?...= and ?filter= JSON expressions.
search_fields[]Columns matched by ?search=
order_fields[]Columns allowed in ?order_by=

Pagination & ordering

AttributeDefaultDescription
limit25Page size
page1Default page number
order_by'id'Default ordering when client doesn't specify
search_operator'icontains'Operator used for ?search=

Response shape

AttributeDefaultDescription
normalize_listFalseWhen 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_objFalseWhen True, detail responses are wrapped as {"<id>": {...}} instead of the bare object. Useful when the client store indexes by id.
normalizedFalseInternal flag. When the handler returns already-normalized data, set this to skip the default wrapping.
count_resultsFalseInternal โ€” flipped by ?count=true to swap the response for {"count": N}.

Cache

AttributeDefaultDescription
cacheFalseEnable Redis cache for GET responses
cache_ttl120Seconds 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_namespaceNoneAuto-built (list:<model> / detail:<model>:<id>)
session_cacheFalseFold session id into the cache key (full per-session isolation)
cache_scope_fieldsNoneDimensions 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_cacheFalseWhether the matched custom route opted into caching (set from the route definition's cache flag)

Relations

AttributeDefaultDescription
list_related_fieldsNone{relation: [fields]} โ€” drives select_related on list and shapes nested objects
edit_related_fieldsNoneSame shape, applied to detail. M2M relations are detected and emitted as arrays
list_prefetch_relatedNone{relation: [fields]} โ€” prefetch_related for list, returns arrays of dicts
edit_prefetch_relatedNoneSame, applied to detail
related_modelsNoneMap of FK name โ†’ resource class. Used by the related-objects walker
many_to_many_modelsNoneMap of M2M name โ†’ through-model resource

Request state (read-only โ€” set during dispatch)

AttributeTypeDescription
requestHttpRequestThe current Django request (set in get_method)
methodstrLowercased HTTP method (HEAD โ†’ 'get')
idstr / intRow id parsed from the URL on detail/PATCH/DELETE
bodydictParsed JSON body, schema-validated when applicable
userdictAuthenticated user (session['user'])
accountdictCurrent tenant account
account_idintActive tenant id
tzZoneInfoTimezone resolved from user.timezone (default 'UTC')
identifierstrClient IP, honouring TRUSTED_PROXIES
objModel instanceThe row currently being processed (PATCH/DELETE)
obj_idintId of the most recently created/updated row
querysetQuerySetCurrent queryset (initialized to model.objects, mutated by hooks)
diffdict{field: {old, new}} โ€” populated during PATCH for audit logs
cache_keystrFinal 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.

AttributeDescription
fieldsNames of all non-relation fields on the model
all_fieldsEvery local field name + every m2m name (used for auto-fill checks)
m2m_fieldsMany-to-many field names

Multi-tenant

AttributeDefaultDescription
account_db'default'Active DB connection name (set by aset_tenant)

Schemas

AttributeDefaultDescription
create_schemaNonePydantic model used to validate POST body
update_schemaNonePydantic model used to validate PATCH body
list_schemaNonePydantic model used to shape GET responses

Ownership & filters

AttributeDefaultDescription
owner_fieldNoneColumn on model that holds the owning user id
queryset_filterNoneExtra filter applied to every query
filtersNonePre-built Q objects mixed in to filtered queries

0-mcp by Stamatios Stamou Jr โ€” github.com/ssjunior/0-mcp