Skip to main content
Every Codenull application exposes a remote MCP (Model Context Protocol) server at:
Through it, any MCP-compatible AI agent can explore your application (features, hooks, entities, menus, roles) and — depending on the permissions you grant — create and update configuration, running through the exact same resolvers, validations and audit trail as the visual builder.

1. Create an MCP API key

MCP access is authenticated with personal API keys (cnk_...), bound to your user and this application, with explicit scopes and an expiration date. Create one with a GraphQL mutation against https://MY_APPLICATION_DOMAIN/graphql (authenticated as your user):
The apiKey value is returned only once. Codenull stores a hash and cannot recover it. Anyone holding the key can act as your user within its scopes — treat it like a password.
List your keys with the mcpApiKeys query and revoke one at any time with revokeMcpApiKey(_id: "...").

Scopes

Creating keys requires the AI Designer agent permission on your role. Effective permissions are re-evaluated on every request as the intersection of the key’s scopes and your current role permissions — if your user is disabled or demoted, the key stops working within a minute. Admin-only scopes (hooks:write, roles:write, env:write, config:delete) additionally require that the key’s user still is an admin at request time: losing the admin role deactivates those scopes immediately, even on existing keys.

2. Connect your agent

The key travels in the Authorization header. No OAuth flow is required. Name the server per applicationcodenull-<app-name> — so connecting several Codenull applications at the same time doesn’t collide on the name (the keys panel generates the snippets with this convention already). The examples below use codenull-myapp.
The server is stateless: only POST /api/mcp is served. Tools your key’s scopes don’t allow are not even listed. Claude.ai custom connectors currently require OAuth and are not yet supported — use Claude Code, or Claude Desktop through the mcp-remote bridge (tab above).
No extra setup, rules files or skills are needed on the agent side: the server ships its own playbook via the MCP instructions field during the connection handshake, so any compatible client (Claude Code, Cursor, Codex) automatically teaches its model the Codenull working method — explore first, read the authoring guide and schema, validate, then create.

3. Available tools

Discovery (config:read)list_features, get_feature_details, list_hooks, get_hook_details, list_entities, get_entity_details, list_menus, list_roles, list_environment_variables, get_graphql_schema, get_feature_authoring_guide, validate_feature_code, validate_hook_code. Writingcreate_feature / update_feature / edit_feature_code (features:write), create_hook / update_hook / edit_hook_code (hooks:write), create_table / update_table / add_table_field (tables:write), upsert_menu (menus:write), grant_feature_access (roles:write), set_environment_variable (env:write), delete_feature / delete_hook (config:delete, require confirm: true).
See what the agent changed, line by line. When modifying existing code, agents are instructed to use edit_feature_code / edit_hook_code, which take old_str/new_str patches — so the tool call itself shows exactly what changes. The server applies the patches to the current code, validates the result, persists it, and returns a unified diff of what was actually written (also returned by update_feature/update_hook when replacing code in full). If a patch doesn’t match the current code, the edit is rejected instead of overwriting the file with a stale version.
A typical flow the agent follows to create a custom feature:
  1. get_feature_authoring_guide — learns the allowed modules (antd, Apollo hooks, dayjs…), the runtime rules, and your application’s configured theme (colors + shell CSS variables), used as the base palette when you don’t ask for specific colors — explicit color requests always take precedence.
  2. get_graphql_schema + get_entity_details — learns your data model.
  3. validate_feature_code — dry-run validation of the JSX (never executed server-side). Also returns informational warnings when the code uses fixed hex colors or Tailwind color classes (fine if you asked for them; otherwise the theme is the default).
  4. create_feature — persists through the same resolver the builder uses (id validation, default permissions, versioning).

4. Usage examples

Once connected, you talk to your agent in natural language — it discovers and calls the MCP tools on its own. These are real prompts you can paste into Claude Code or Cursor, with the tool sequence the agent typically runs.

Explore an application you don’t know

“Connect to my Codenull app and give me an overview: what entities, features and hooks does it have?”
The agent calls list_entities, list_features and list_hooks, then summarizes your data model, screens and server-side logic. Requires only config:read.

Create a table and a screen for it

“Create a Cliente table with fields Nombre (text, required), Correo (text, unique) and FechaRegistro (date). Then build a screen to list and create clients, and add it to the side menu.”
Typical sequence:
  1. get_entity_details on an existing table — to copy your field type conventions.
  2. create_table — creates Cliente with the fields (tables:write).
  3. get_feature_authoring_guide + get_graphql_schema — learns the runtime rules and the generated Cliente CRUD operations.
  4. validate_feature_code then create_feature — a custom feature with an antd table + creation form wired to useQuery/useMutation (features:write).
  5. upsert_menu — adds the /feature/clientes entry to the side menu (menus:write).

Add a validation hook

“Add a beforeSave validation on the Facturas table: reject any invoice whose Total is negative. Follow the same style as the existing hooks.”
Sequence: list_hooks + get_hook_details (to mimic your patterns) → validate_hook_code (syntax + rules dry-run) → create_hook with type: "beforeSave" and the table’s tableId. Requires hooks:write (admin-granted).

Modify an existing feature

“In the feature ventas_dashboard, add a date-range filter and a card with the month’s total.”
Sequence: get_feature_details (reads the current customCode) → validate_feature_codeupdate_feature. Updates run through the same versioning flow as the builder — pass status: "draft"/"published" if you use draft versions.

Grant access to a role

“Make the new Clientes screen visible to the Ventas role, plus Admin.”
Sequence: list_roles + list_features (to resolve ids) → grant_feature_access with the feature _id and the role ids (roles:write).

Calling the server without an agent (raw JSON-RPC)

The endpoint speaks standard MCP over Streamable HTTP, so you can also script it directly:
Destructive tools (delete_feature, delete_hook) refuse to run unless the agent passes confirm: true — agents are instructed to ask you before confirming. If a tool you expect is missing from tools/list, your key lacks that scope (or you lost the role permission backing it).

Security model

  • Keys: 256-bit entropy, SHA-256 hashed at rest, mandatory expiry (max 365 days), revocable, lastUsedAt tracking. The cnk_ prefix makes leaked keys easy to detect with secret scanners.
  • Tenant isolation: each deployment serves one application; keys are bound to it and rejected elsewhere.
  • Attribution: every mutation records your user as the author, same as in the builder.
  • Audit: every tool call is logged (mcp_audit_logs) with redacted arguments — env var values and API keys never reach the log; long code payloads are stored as a preview plus SHA-256 hash. Entries are retained for one year.
  • Rate limits: 60 requests/minute per key; failed authentication is limited per IP. Limits are tracked per server instance, so with N replicas the effective ceiling is N× the stated value.
  • Payload limits: 2 MB per request, 200 KB per hook, 1 MB per feature code.
  • Prompt-injection guard: read-tool responses are wrapped with a note marking application content as data, not instructions.
hooks:write deserves special care: hook content is JavaScript executed by your application’s backend. A leaked key with this scope means remote code execution. Only admins can grant it, and every hook write is audited with a hash of the exact code persisted. Application owners receive an email notification on every hook creation and modification, whichever entry point was used (visual builder or MCP).