create_endpoint — Create endpoint or directory
create_endpoint — Create endpoint or directory
Section titled “create_endpoint — Create endpoint or directory”Bind a draft path node to one target, or create an unbound directory.
Stable Viat 1.1.0. Start with MCP configuration and result handling. The examples below are synthetic, source-derived expected shapes, not executed responses. No service, provider or device was contacted to prepare this page.
Prerequisites and permissions
Section titled “Prerequisites and permissions”Editor-gated: project Owner, Admin or Developer; Viewer is refused. The PAT owner needs this project role and the PAT scope must permit the route.
Use an activated isolated instance, configured server/bearer, and an existing mcp-lab project except for list_projects. Examples using existing assets/IDs assume the fixtures in the overview; replace synthetic IDs with the IDs returned there. They are not self-provisioning.
Complete input fields
Section titled “Complete input fields”Required is the exported input contract’s structural requirement, not the full conditional API validation. For optional fields, explicit JSON null deserializes like omission, including unconstrained JSON fields. Empty strings/arrays/objects are actual values, not omission. Numeric formats describe serialization bounds; runtime clamps/defaults are separate. Schema default:null on args is not its effective runtime default {}.
| Field | Type | Required | Omission / explicit null | Constraints and meaning |
|---|---|---|---|---|
allowed_authorizers | array<string> / null | no (may be conditional) | inherit; null = omitted. | Authorizer names declared at this node; [] is explicit. |
authz_gates | array<JSON> / null | no (may be conditional) | inherit; null = omitted. | Array of {type,action} gate objects; [] differs from inherit. |
crud_config | JSON (any value) | no (may be conditional) | Not supplied to API; conditional rules below.; null = omitted. | CRUD object; required table/op plus options described below. |
crud_resource_name | string / null | no (may be conditional) | Not supplied to API; conditional rules below.; null = omitted. | Existing postgresql resource for table CRUD. |
method | string / null | no (may be conditional) | Not supplied to API; conditional rules below.; null = omitted. | HTTP method; accepted values and conditional requirement below. |
override_authorizers | boolean / null | no (may be conditional) | false; null = omitted. | Stored authorizer override flag; omitted updates preserve current value. |
overrides | JSON (any value) | no (may be conditional) | Not supplied to API; conditional rules below.; null = omitted. | Endpoint overrides object; replace, not recursive merge. |
parent_id | string / null | no (may be conditional) | tree root; null = omitted. | Parent endpoint UUID; omission/null has create/move semantics below. |
path_override | string / null | no (may be conditional) | Not supplied to API; conditional rules below.; null = omitted. | Leaf absolute path override; no null-clearing via MCP. |
project | string / null | no (may be conditional) | VIAT_PROJECT / current_project; else project_required; null = omitted. | Project slug; omission/null uses VIAT_PROJECT/current_project, otherwise project_required. |
proxy_resource_name | string / null | no (may be conditional) | Not supplied to API; conditional rules below.; null = omitted. | Existing http_api resource binding. |
proxy_strip_prefix | boolean / null | no (may be conditional) | true; null = omitted. | Strip mount prefix; create API default true. |
proxy_upstreams | map<string,string> / null | no (may be conditional) | Not supplied to API; conditional rules below.; null = omitted. | Path-parameter value → http_api resource name map. |
script_name | string / null | no (may be conditional) | Not supplied to API; conditional rules below.; null = omitted. | Script binding name, qualified by folder when needed. |
segment | string | yes | No default; missing/null is invalid. | One path segment, literal or :param. |
tree | string / null | no (may be conditional) | only tree, otherwise required; null = omitted. | Tree NAME, resolved to UUID; not an ID. |
workflow_name | string / null | no (may be conditional) | Not supplied to API; conditional rules below.; null = omitted. | Workflow binding name, qualified by folder when needed. |
ws_config | JSON (any value) | no (may be conditional) | Not supplied to API; conditional rules below.; null = omitted. | WebSocket config with routes; API validation applies. |
Behavior and validation
Section titled “Behavior and validation”Choose at most one binding: script_name, workflow_name, proxy_resource_name, crud_resource_name, ws_config. No binding and no method means directory. Script/workflow/CRUD leaves need a method; proxy mounts have no method; WebSocket uses GET. tree is a name and may be omitted only when exactly one tree exists. parent_id omitted/null creates a root node. segment is one literal or :param, not a multi-segment path. Proxy strip defaults true. Empty authorizer/gate arrays are explicit declarations, not omission; authorizers replace the inherited list while gates accumulate. Complex JSON fields are described below.
A segment must be 1..64 bytes, cannot be bare :, and cannot contain / or whitespace. A WebSocket node may omit method (the API supplies GET); if a method is supplied it must be GET. In ws_config.routes, script_id wins over script if both are present. Route names are [a-z0-9_]{1,64} or $connect, $disconnect, $default; at least one message route other than connect/disconnect is required. route_key must be nonblank and at most 64 bytes, and quota values must be positive.
JSON objects accepted by the API
Section titled “JSON objects accepted by the API”authz_gates: array of objects with required stringstype,action; the model must declare the type/action and the type must be usable as a subject-only gate. Omission inherits; an empty array declares no gates locally. Gates accumulate through ancestors until the stored override boundary. MCP does not expose changing that boundary.ws_config: requiredroutesmap; each route value identifies a script byscriptstring orscript_idUUID string. Optionalroute_keydefaults to"type"; optionalmessage_rate_limitis a quota;log_messagesisallor defaulterrors. Unknown top-level config keys are rejected. Routes resolve existing scripts at write time. This config does not enable WebSocket transport in MCP.crud_config: requiredtable:stringandop=list|get_by_pk|insert|update_by_pk|delete_by_pk.columns:string[]defaults [];filtersdefaults {} and maps query names to{column:string,op?:eq|neq|gt|gte|lt|lte|like|ilike}(op defaults eq);order_bydefaults [] of{column:string,dir:asc|desc}; optionallimithas integerdefault=50,max=200.writable:string[]defaults [];defaultsdefaults {} mapping columns to identity scope strings; optionalauthz_type:stringinherits the resource table binding when absent;allow_unscoped_writes:booleandefaults false. Unknown keys are rejected. Lists use filters/order/limits (other ops reject those options); limit.max must be positive and limit.default cannot exceed it. Empty columns selects all mapped columns; empty writable selects mapped non-primary-key columns. Primary-key operations derive the path key from the mapped table. Mutations need row scope (authz_type/resource binding) unless deliberately opting out; do not enable unscoped writes just to silence a publish refusal.overrides: object, replaced as a whole.path_params,query_params,body_fieldsdefault {} and map wire names to{type:int|float|bool|string|json,required?:boolean,nullable?:boolean,default?:JSON,as?:string}. required defaults false; absent nullable does not accept null; default/as are absent by default. Body nullable is separate from required.required_headers:string[]defaults [];response_headers:map<string,string>defaults {}; optionalresponse_transform:stringis RFC9535 JSONPath.strict,raw_body,run_asyncdefault false. Optionalaudit_reason:stringselects a validated reason source. Optionalrate_limithas nullable/optionalendpoint/subjectquotas andsubject_key= defaultidentityorip. A quota requires positive integerrequests,window_secs; optional positiveburstdefaults to requests. Optionalmultiparthasmax_file_bytesdefault 0 (deployment ceiling),max_filesdefault 0 (effective 1, max 32),fields:string[]default [] (all text fields). Optionalcacherequires positive integerttl_secswithin the deployment ceiling;scopedefaultscalleror may beshared;vary_headers:string[],ignore_params:string[]default []. Optionalproject_users_grantcontainsroles:string[]default []; optionalcurrent_user_grantcontainsread_social_identity:booleandefault false andprovision_meta_keys:string[]default []. These are privilege grants, not harmless annotations.
The API rejects incompatible options: multipart with raw_body/run_async; raw_body with body_fields; cache with raw_body/multipart/run_async. Cache serves GET only. Strict mode requires path declarations; duplicate argument bindings and malformed JSONPath/header names fail. path_override is leaf-only, absolute, at most 256 characters, cannot contain //, backslash or .., and cannot claim a reserved platform path. A string null is not a clearing command.
Output and pagination
Section titled “Output and pagination”Object {endpoint:Endpoint}. Endpoint object: string id, path, segment, tree_id, kind; optional strings method, parent_id, script_name, workflow_name, proxy_resource_name; optional ws_routes object (route → script string), authz_gates array of {type, action}. Optional fields are omitted, not null. This projection does not echo authorizer lists, overrides or full CRUD configuration; do not treat it as a complete backup.
No pagination or continuation cursor.
The value is JSON serialized inside one MCP content text block. Parse result.content[0].text as JSON. There is no promised structuredContent or outputSchema. Optional fields documented as omitted must not be assumed to exist with null.
Synthetic request and expected shape
Section titled “Synthetic request and expected shape”After MCP initialize/initialized, send this tools/call request as one JSON line over stdio (pretty-printed here for readability).
{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "create_endpoint", "arguments": { "project": "mcp-lab", "tree": "main", "segment": "mcp-demo", "method": "GET", "script_name": "mcp_demo" } }}Expected MCP envelope shape (IDs, timestamps, headers and computed values are illustrative, not deterministic assertions).
{ "jsonrpc": "2.0", "id": 3, "result": { "content": [ { "type": "text", "text": "{\"endpoint\":{\"id\":\"00000000-0000-4000-8000-000000000001\",\"method\":\"GET\",\"path\":\"/mcp-demo\",\"segment\":\"mcp-demo\",\"tree_id\":\"00000000-0000-4000-8000-000000000001\",\"script_name\":\"mcp_demo\",\"kind\":\"script\"}}" } ], "isError": false }}Decoded JSON value in the text block:
{ "endpoint": { "id": "00000000-0000-4000-8000-000000000001", "method": "GET", "path": "/mcp-demo", "segment": "mcp-demo", "tree_id": "00000000-0000-4000-8000-000000000001", "script_name": "mcp_demo", "kind": "script" }}Failures and recovery
Section titled “Failures and recovery”Mixed bindings, a method with no binding, orphan crud_config, or proxy fragments without a proxy resource → local bad_input. The API rejects invalid methods, missing targets, reserved paths, invalid schemas/gates and conflicting paths. A CRUD leaf needs both resource and config.
All upstream tools can fail with expired/revoked tokens, PAT confinement, project access denial, activation, network or timeout errors. Missing project/default gives project_required; control-plane non-2xx gives http_4xx/http_5xx. See the exact shared error envelope and retry rules. Input deserialization/unknown tool failures can be JSON-RPC protocol errors before the tool-layer envelope; do not assume every failure has isError. A retryable flag is not an idempotency guarantee.
Side effects, verification and cleanup
Section titled “Side effects, verification and cleanup”Creates a draft only; do not blindly publish the whole project for this one node. Inspect publish_plan. Cleanup a fresh fixture with delete_endpoint (after unpublishing it if published); deleting a directory removes its subtree.
Verification is observational: inspect the documented result fields and use the corresponding read tools before and after any authorized mutation. Do not verify by sending production traffic or deleting unrelated objects.
Maintenance evidence
Section titled “Maintenance evidence”Input inventory: contracts/1.1.0/mcp-tools.json, tool create_endpoint. Implementation/tests under the pinned product source: endpoints.rs; handlers/endpoints.rs; core/types/endpoint.rs; core/types/crud.rs; tests/it/tool_create_endpoint.rs. Tool module filenames refer to crates/viat-mcp/src/tools/; API handlers refer to crates/viat-api/src/handlers/. Shared transport/error evidence: crates/viat-mcp/src/tools/service.rs, http.rs, error.rs; tests were inspected, not run for this documentation change.