Skip to content

Agent workflows

These are the tool sequences that cover most agent work. You can hand them to your agent as instructions, but most agents follow them on their own once connected: the server sends a short version of this guidance when the agent connects.

Tool arguments are shown as JSON. Every tool is documented in the tool reference.

  1. browse_facets returns the packs (with their ids), categories, tags and types, with counts. Use it to turn “the Medieval Village pack” into a pack_ids value and to check which types and categories exist.

    { "query": "barrel" }
  2. Describe what you need in plain language and narrow with filters.

    {
    "query": "rusty metal barrel",
    "types": ["mesh"],
    "tri_max": 5000,
    "limit": 10
    }

    Rows include triangle count, bounds, pack, review state and whether a thumbnail exists, which is often enough to choose. For more, get_prop returns the full record and find_similar_props finds look-alikes of a good hit.

  3. get_prop_thumbnail returns the thumbnail as an image the agent can see. It only works for props with has_thumbnail: true.

  4. get_prop_graph with direction: "dependencies" lists everything the prop needs (materials, textures) with sizes.

  5. get_download_url returns a URL for the current version.

    { "entry_id": 1234 }

    If expires_at is set, fetch the URL with no Authorization header before that time. If expires_at is null, the URL is a path on https://api.prophouse.dev and needs your usual Authorization: Bearer header. Save it under suggested_filename.

If the goal is to get props into an open Unreal project, skip the download and use import_to_unreal instead. It brings dependencies along and places the files correctly.

This loop gives an agent the same safety as a person using the desktop app or Unreal plugin: nobody’s work is overwritten.

  1. checkout_prop locks the prop for you and returns the version to start from.

    { "entry_id": 1234, "note": "Reducing tri count for mobile" }

    The lock records the version you checked out as lock.base_object_id (the same as checkout.object_id). If the call fails with LOCKED, a teammate is editing it: details.holder says who. Do not try to work around the lock. Tell the user, or pick another prop.

  2. The result includes a download URL (same rules as get_download_url). Edit the file with your own tools.

  3. Compute the SHA-256 of the edited file (64 lowercase hex characters) and its exact size in bytes.

  4. Call checkin_prop with the hash and the size:

    {
    "entry_id": 1234,
    "content_hash": "<64-hex-sha256>",
    "blob_size": 482113,
    "release_lock": true
    }

    The check-in fails with STALE_FACE if the prop’s current version is no longer the one you checked out. You can pass expected_face_object_id to name the expected version yourself, but you don’t need to while you hold the checkout.

    For files under about 500 KB you can include the bytes as file_base64 and the check-in completes in one call.

  5. For larger files the first call returns status: "upload_required" with an upload object:

    • mode: "direct": PUT the raw bytes to upload.url with exactly the headers in upload.headers and no Authorization header. A 412 response means the bytes are already stored; treat it as success.
    • mode: "server": PUT the raw bytes to upload.url (a path on https://api.prophouse.dev) with your usual Authorization: Bearer header.

    Then call checkin_prop again with the same arguments. The result is checked_in.

Other outcomes:

  • no_change: the file is byte-identical to a version that already exists. Nothing was published.
  • decision_required: the file looks like a new version of an existing prop that lost its link to it. Call again with attach_to_lineage set to the returned candidate_lineage_id, or force_new_lineage: true to keep it separate. Ask the user if you are unsure.
  • STALE_FACE error: someone published or restored a different version after you checked out. Do not retry. Call release_checkout, then checkout_prop again to start from the current version, reapply your change and check in again. Calling checkout_prop again without releasing only refreshes the lock and keeps your original baseline; its result then carries a warning that the prop has moved.

To abandon an edit, call release_checkout with the entry_id. To register a brand-new prop instead of versioning one, pass new_entry ({"name": "SM_Crate_Small", "entry_type": "mesh"}) instead of entry_id, optionally with pack_name.

  1. list_reviews with view: "waiting_on_me" lists the rounds waiting for your response. get_review gives the details of one.

  2. Inspect the prop with get_prop, get_prop_thumbnail and list_comments.

  3. Respond with respond_to_review:

    {
    "request_id": 42,
    "response": "changes_requested",
    "note": "Pivot is off-center; please fix before approval.",
    "assign_to_name": "sam"
    }
  4. Discuss with add_comment. Mention people as @name to notify them, and pin a comment to a specific version with object_id.

To start a round, call request_review with the prop and one or more reviewers. get_notifications is the agent’s inbox, and mark_notifications_read clears handled items. More about the review process itself is in Reviews.

An agent can dress a level from your library: find props, import them into the Unreal project you have open, then place them with an editor-side tool. This needs one-time setup in the editor, described in Import props into Unreal.

  1. Find the props with search_props (and get_prop_thumbnail to check them). Collect their entry_id values.

  2. If you do not know the project name, or more than one project is open, call list_unreal_editors. Its ready_projects lists the projects you can import into.

  3. Call import_to_unreal:

    {
    "entry_ids": [1234, 1240, 1311],
    "project": "ColdStorage",
    "target_root": "/Game/Props"
    }

    The call waits up to 25 seconds for the editor to finish. If the result says done: false, call get_unreal_import with the job_id and wait_seconds until done is true.

  4. Each entry in requested has an object_path such as /Game/Props/Meshes/SM_Crate.SM_Crate. Spawn those in the level with a tool that controls the editor, such as an Unreal MCP server or the editor’s Python API:

    import unreal
    actors = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
    asset = unreal.load_asset("/Game/Props/Meshes/SM_Crate.SM_Crate")
    actors.spawn_actor_from_object(asset, unreal.Vector(0, 0, 0))

Prophouse’s tools get the files into the project. Placing, moving and arranging actors is up to the editor-side tool.