Skip to main content

Hooks integration guide

This guide describes enterprise Hook configuration, HTTP invocation conventions, and event requests and responses for QwenWork.

This guide describes enterprise Hook configuration, HTTP invocation conventions, and event requests and responses for QwenWork. The desktop client invokes enterprise-provided HTTP services.

Currently supported Hooks events

The current QwenWork enterprise flagship edition (qwenwork_premium) supports these 12 events:
EventWhen triggeredTypical usesCan block the operation
SessionStartWhen a session starts, resumes, or restarts after clearing or compactionSession recording and injecting enterprise rulesBlocking is not recommended
UserPromptSubmitAfter the user submits content, before it reaches the AgentSensitive information and prompt compliance checksYes
PreToolUseBefore the Agent invokes a toolCommand and file-operation controls, permission approvalYes
PostToolUseAfter tool execution completesOperation auditing and result checksExecution has already occurred and cannot be undone
StopWhen the Agent is about to finish its current responseCompleteness checks and requiring further workCan prevent the Agent from stopping
NotificationWhen the Agent emits a notificationNotification forwarding and security auditingBlocking is not recommended
PreUserPromptSubmitBefore each user input is saved and sent to the Agent, including the first and subsequent turnsPrompt replacement and input compliance checksYes
PreCompactBefore manual or automatic context compactionPre-compaction checksCan prevent this compaction
PostCompactAfter successful context compactionRecording the compaction summaryCompaction has already occurred and cannot be undone
ConnectorAddedBefore adding, enabling, or updating a connector takes effectConnector configuration security approvalYes
ExpertSuiteAddedBefore a plugin installation takes effectSecurity approval of the plugin's complete filesYes
SkillAddedBefore a skill installation takes effectSecurity approval of the skill's complete filesYes

Hook configuration

Hook configuration format

In the enterprise console, go to Security → Hooks, select an event, and enter its JSON configuration array. Each array item is a Hook group: matcher determines when it matches, and hooks lists the services to invoke on a match. The following configuration invokes a check service before the Bash tool executes. Configure it for the PreToolUse event:
Replace the URL and credentials with actual values. Omit headers if authentication is unnecessary. An empty configuration array [] disables enterprise Hook calls for this event. All events use this Hook group array structure. Select the corresponding event in the console; do not wrap the array in an additional event-name or hooks object.

Fields

Hook group fields: matcher matches the tool name for PreToolUse and PostToolUse, source for SessionStart, notification_type for Notification, and trigger (manual or auto) for PreCompact and PostCompact. UserPromptSubmit and Stop do not require this field.
FieldTypeRequiredDescription
matcherstringNoCase-sensitive JavaScript regular expression; omitting it matches all
hooksarrayYesList of HTTP Hooks containing at least 1 item
Omit matcher for PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded. Omission, an empty string, or "*" matches all; other values are regular expressions matched against the event name, not the prompt, file name, or connector name. Filter content by examining the request body on your server. matcher matching rules
PatternMeaningExample
OmittedMatch allEvery tool triggers the Hook
Exact valueExact match"Bash" matches only the Bash tool
Separated by ``Match multiple values
Regular expressionRegex match"mcp__.*" matches all MCP tools
HTTP Hook fields:
FieldTypeRequiredDescription
typestringYesMust be http. The client rejects other types and does not execute them
urlstringYesFull HTTP or HTTPS URL that receives the event
timeoutnumberNoTimeout in seconds, greater than 0. Defaults to 10 seconds for PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded; 600 seconds for other events. Explicit configuration is recommended.
headersobject<string, string>NoCustom headers with string keys and values. An explicit headers.Accept overrides the default.
When multiple Hooks match an event, PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded execute them sequentially in configuration order. A valid block stops execution immediately; a later allow cannot override it. URLs are not deduplicated. Other events execute Hooks in parallel by default and deduplicate identical URLs; do not rely on array order.

HTTP invocation conventions

  • **Method:**POST, with the current event's JSON object as the body.
  • **Headers:**Content-Type: application/json and Accept: application/json by default, plus configured headers.
  • Timeout: The call ends after timeout; automatic retries are not currently performed.
Return HTTP 200 and a JSON object supported by the event. PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded use the allow / block format below; return {} for other events when no intervention is needed.
HTTP statusResponse bodyClient behavior
2xxEmptyLeaves the original flow unchanged
2xxValid JSON objectProcesses the response fields supported by the current event
2xxPlain textSessionStart and UserPromptSubmit use the text as context; PreToolUse interprets it as allow, which is not recommended
2xxInvalid JSON syntax or field validation failurePreToolUse rejects the tool call; other events log the error and continue
Non-2xxAnyLogs the invocation error and continues the original flow
Connection failure or timeout—Logs the invocation error and continues the original flow
Additional handling for PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded:
ResultHandling
HTTP 2xx + valid allowContinues to subsequent Hooks; proceeds with the original operation if none blocks it.
HTTP 2xx + valid blockStops the operation immediately and skips remaining Hooks. Skills, plugins, and connectors display reason as plain text without executing HTML.
Service unreachable, connection failure, timeout, or non-2xx HTTP (including 4xx and 5xx)Logs the error, skips this Hook, and continues subsequent Hooks; proceeds with the original operation unless a valid block is received.
Empty response, plain text, invalid JSON, unknown fields, or field validation failureLogs the error, skips this Hook, and continues the original flow. This is not a successful approval.
User cancellation, identity not ready or changed during the request, local URL safety validation failure, or file validation failureStops the operation. These are not service outages and do not permit proceeding on error.
These 4 events do not follow HTTP redirects. To block, return HTTP 2xx with a valid block response. HTTP 403, HTTP 500, or a block missing required fields is treated as an error and skipped, without blocking.

Hook input and output

Common request fields

The client fills request fields automatically; they are not customer configuration fields. SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Stop, Notification, PreCompact, and PostCompact include the following common information:
FieldTypeDescription
eventstringHTTP event name, identical to hook_event_name
hook_event_namestringCurrent event name, usable for server-side dispatch
session_idstringCurrent session ID
transcript_pathstringLocal path to the client's session transcript
cwdstringClient's current working directory
permission_modestring, may be omittedCurrent permission mode
agent_idstring, may be omittedAgent ID
agent_typestring, may be omittedAgent type
modelstring, may be omittedModel identifier, currently available in SessionStart
PreCompact and PostCompact include only the basic fields in the example above and their event-specific fields, excluding permission_mode, agent_id, agent_type, and model. PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded use these common fields:
Request fieldTypeDescription
hook_event_namestringCurrent event name, usable for server-side dispatch.
request_idstringStable identifier derived from user identity, the logical operation, and its content. Use it to correlate requests; it is neither a never-repeating global sequence number nor a promise of automatic client retries.
user_idstringID of the current logged-in user whose identity has been reconciled.
app_versionstringClient version.
These 4 events do not include engine fields such as event, cwd, or transcript_path. Only PreUserPromptSubmit additionally includes session_id and turn_id. User, request, session, and version values in the examples are illustrative.

Common response fields

  1. Plain text: Only for supplemental context in SessionStart and UserPromptSubmit.
  2. JSON object: Returns control fields such as decision, reason, and hookSpecificOutput.
The following response fields apply to SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Stop, and Notification. Not every event supports every field; use the combinations shown for each event and return {} to leave the flow unchanged.
FieldTypeDescription
continuebooleanfalse requests stopping the current execution; omission does not actively stop it
stopReasonstringReason for stopping, used with continue: false
decisionstringBusiness decision; block blocks, with event-specific meaning described below
reasonstringReason for the business decision
hookSpecificOutputobjectEvent-specific response fields
If hookSpecificOutput is present, it must contain hookEventName, set to the current event name. Top-level decision does not accept ask; use permissionDecision for tool confirmation. continue: false controls execution for UserPromptSubmit, PreToolUse, PostToolUse, and Stop. SessionStart supplements context; Notification does not control the flow through responses. Do not use async: true to express asynchronous enterprise HTTP callback processing. PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded accept only the strict JSON responses listed for each event, without the common response fields above. Unknown fields, incorrect types, invalid combinations, plain text, and {} are invalid responses. See the corresponding events for PreCompact and PostCompact responses.

Hook events

The request examples below show event names and event-specific fields. Actual requests also include the corresponding common information from “Common request fields”. Handle HTTP failures according to “HTTP invocation conventions”.

SessionStart

Triggered when a session starts or resumes, to provide context such as business background and project constraints. Request body:
FieldTypeDescription
sourcestringSession source: startup (new), resume (resumed), clear (started after clearing), compact (resumed after compaction), etc.
Response body:
Event-specific response fieldTypeDescription
additionalContextstringSession context added for the model
Plain text can also be returned as context. Return {} if there is no additional content. This event does not set operating-system environment variables.

PreUserPromptSubmit

Triggered for each user-submitted text input, before it is saved to the official chat transcript and reaches the Agent. It replaces or blocks the entire input for this turn. The existing UserPromptSubmit receives the processed text afterward and can only block or supplement context using its original protocol; it cannot replace the entire input. Request body:
Event fieldTypeDescription
session_idstringClient session identifier, which may be preallocated for the first turn.
turn_idstringClient identifier for this logical submission, distinct from the native engine's internal Turn ID.
isFirstTurnbooleanWhether the request is the actual first user input. Resubmitting a blocked first turn remains true; restarting or reopening the session does not reset it.
promptstringText to submit for this turn.
Response body: Allow and preserve the original text:
Allow and replace the entire text for this turn:
Block this submission:
Response fieldTypeConstraints
decisionstringRequired; only allow or block.
isFirstTurnbooleanRequired in both response types and returned by the server. Controls the first/subsequent-turn replacement marker and block notice. Normally echoes the request value; the client does not require equality.
updated_promptstringAllowed only with allow; must be a nonblank string. Omission preserves the current text.
reasonstringAllowed only with block; required and must be nonblank.
After replacement, the official chat transcript, displayed user message, subsequent session history, and model input use the replaced text with an enterprise-processing marker. Blocking does not add an official user message and leaves the input editable. This event handles text only; it does not review or replace attachments, system instructions, tool arguments, or tool results. Multiple Hooks process the same turn sequentially. One Hook's replacement becomes the next Hook's prompt; a later service error does not restore the original text. The last valid allow response's isFirstTurn determines the displayed turn marker.

UserPromptSubmit

Triggered after prompt submission but before model processing, to inspect input or supplement context. matcher does not filter prompt content. Request body:
FieldTypeDescription
promptstringUser prompt for this submission
To reject this input, return:
To supplement context, return:
Response fieldTypeDescription
decisionstringblock prevents this prompt from reaching the model; omit if there is no decision
reasonstringReason for rejection; the UI does not guarantee verbatim display
hookSpecificOutput.additionalContextstringContext added to this request
Return {} for no additional behavior. Plain-text context is also supported. Do not return prompt to replace user input.

PreToolUse

Triggered before actual tool execution to validate or change arguments, allow or deny the call, or request user confirmation. matcher matches tool_name (such as Bash, Write, Edit, Read, Glob, Grep, or MCP tool names such as mcp__server__tool). Request body:
FieldTypeDescription
tool_use_idstringID of this tool call
tool_namestringTool name
tool_inputobjectTool input arguments
mcp_contextobject, optionalMCP service information: server_name, tool_name, and optionally url, command, args, cwd, and tcp
original_request_namestring, optionalRequest name before tool-name resolution or alias conversion
Response example: adjust the command arguments for a read-only check and request user confirmation.
Event-specific response fieldTypeDescription
permissionDecisionstringallow: explicitly allow;deny: deny;ask: request confirmation;
permissionDecisionReasonstringReason for the permission decision
updatedInputobjectReplaces the entire tool argument object rather than merging selected fields; arguments are revalidated after replacement
additionalContextstringAdditional explanation for the model
Return {} when there is no permission decision; do not use allow to mean “no opinion”. Decisions from multiple Hooks are aggregated as deny > ask > allow; allowed calls are still subject to tool permission rules. deny rejects only this tool call. Use continue: false to stop the current execution.

PostToolUse

Triggered after successful tool execution to inspect results, supplement context, or replace output. matcher matches tool_name. Request body:
Tool fields are the same as for PreToolUse, plus:
FieldTypeDescription
tool_responseobjectTool execution result, whose structure varies by tool; the example is not a fixed response schema
Block the tool result:
Supplement or replace the tool result:
Response fieldTypeDescription
decisionstringdecision: "block" provides Hook error feedback to subsequent processing; it does not guarantee hiding the original result and does not undo operations already performed.
reasonstringReason for blocking the result
hookSpecificOutput.additionalContextstringAdditional explanation for the model
hookSpecificOutput.updatedToolOutputstringReplacement tool-output text
hookSpecificOutput.updatedMCPToolOutputstringMCP-only compatibility replacement field; prefer updatedToolOutput
Replacement fields should contain nonempty strings. If both are present, updatedToolOutput takes precedence. Multiple Hooks should not modify the same input or output simultaneously. The tool has already executed when this event occurs. Rejecting or replacing its result does not undo file changes, command execution, or external calls. Use PreToolUse to prevent the operation.

Stop

Triggered when the Agent is about to finish the current turn, to check delivery conditions. block means “do not finish yet; continue working”. Request body:
FieldTypeDescription
stop_hook_activebooleanWhether a Stop Hook has already required further work; true when the Agent is about to finish again
last_assistant_messagestring, optionalAccumulated Agent text output for this turn
To require additional work, return:
Response fieldTypeDescription
decisionstringblock prevents normal completion and requires the Agent to continue; {} allows completion
reasonstringSpecific remaining work the Agent must perform
continue: false stops execution; it does not request further work. Check stop_hook_active and define a termination condition on your server. For example, return {} after requiring further work once to avoid repeated triggering.

Notification

Triggered for notifications such as permission confirmation and MCP elicitation. matcher matches notification_type, not the tool name. Request body:
FieldTypeDescription
notification_typestringNotification type; see the values below
messagestringNotification body
detailsobjectNotification details; structure varies by type
notification_type values:
ValueMeaning
permission_promptPermission confirmation requested
elicitation_dialogMCP elicitation started
elicitation_responseMCP elicitation response received
elicitation_completeMCP elicitation completed
Return {} after receipt. This event's response does not approve, deny, or change the original operation. Some paths still wait for the HTTP response, so respond quickly. A particular client may not emit every notification type, and idle_prompt is not guaranteed for every completed task.

PreCompact

Triggered before actual manual or automatic context compaction, not on every conversation turn. matcher matches trigger. Request body:
FieldTypeDescription
triggerstringmanual: manual compaction; auto: automatic compaction.
custom_instructionsstringCustom instructions for this compaction, or an empty string if none.
Response body: Do not intervene in this compaction:
Prevent this compaction:
Response fieldTypeDescription
decisionstringdeny prevents this compaction; return {} for no intervention. This event does not use the allow / block approval format.
reasonstringReason for preventing compaction.
Preventing compaction does not terminate the session or guarantee that model requests can continue after the context limit is exceeded. Verify compaction control against the delivered version during integration testing.

PostCompact

Triggered after successful context compaction to receive its summary. Failed or prevented compaction does not trigger a success notification. matcher matches trigger. Request body:
FieldTypeDescription
triggerstringmanual: manual compaction; auto: automatic compaction.
compact_summarystringSummary of this compaction; may be empty.
Response body:
Return {} after receipt. This event cannot undo compaction. This guide does not define response fields for replacing the summary or injecting context. Verify actual triggering against the delivered version during integration testing.

ConnectorAdded

Reviews a connector's pending configuration, covering controlled creation, import, marketplace installation, enabling, and configuration updates. After a valid block, the client does not register, enable, or apply the update; previously effective configuration is not undone. Request body:
FieldTypeDescription
sourcestringSource: marketplace (marketplace installation), local_import (local import or installation after creation in a conversation), manual_config (manual configuration and similar entries), or console (delivered by the enterprise console). Filled by the client.
content_digeststringSHA-256 hexadecimal digest of the pending content, used to correlate the review snapshot; not a download URL.
connectorobjectPending connector configuration; see its fields below.
connector fieldTypeDescription
namestringConnector name.
kindstringmcp or builtin.
configobjectRedacted copy of the actual pending configuration. HTTP connectors include the address; local command connectors include actual configuration such as command and args. Structure varies by connector type.
redacted_fieldsstring[]Paths of sensitive fields that have been hidden; empty array if none.
The client processes explicit credential fields such as tokens, passwords, Cookie, and Authorization, as well as URL credentials, sensitive query parameters, and explicit command arguments. Redaction is not a general-purpose secret detector; do not hide credentials in unrecognizable custom fields, text, or command fragments. Response body: Allow:
Reject:
This event reviews configuration additions; it does not replace subsequent PreToolUse checks for tool calls.
Response fieldTypeDescription
decisionstringRequired; only allow or block. allow continues adding; block prevents this operation.
reasonstringAllowed only with block; required and nonblank. The client displays it as plain text.
content_digest is computed from the actual configuration before redaction and cannot be recomputed from the received redacted config. Triggered when adding, enabling, or changing connectors through controlled client entries; directly editing configuration files on disk is not guaranteed to trigger it.

ExpertSuiteAdded

Reviews the complete file snapshot before plugin installation, including the manifest, skills, scripts, and other resources. Reading the review content does not execute package scripts. Request body:
FieldTypeDescription
sourcestringSource: marketplace (marketplace installation), local_import (local import or installation after creation in a conversation), manual_config (manual configuration and similar entries), or console (delivered by the enterprise console). Filled by the client.
content_digeststringSHA-256 hexadecimal digest of the pending content, used to correlate the review snapshot; not a download URL.
expert_suiteobjectPlugin to install; see its fields below.
expert_suite fieldTypeDescription
namestringPlugin name.
versionstring, may be omittedOmitted if the package declares no version.
manifestobjectActual parsed package manifest.
filesarrayComplete pending file snapshot, each item containing path, encoding, and content. The example only illustrates the file structure.
File fieldTypeDescription
files[].pathstringRelative path within the package; not a local path or download URL the server can read directly.
files[].encodingstringMust be base64.
files[].contentstringBase64-encoded complete file content; decode it on the server for inspection.
Response body: Allow:
Reject:
If rejected, this plugin is not installed or activated. The client displays reason as plain text without adding an “Import plugin failed” prefix.
Response fieldTypeDescription
decisionstringRequired; only allow or block. allow continues adding; block prevents this operation.
reasonstringAllowed only with block; required and nonblank. The client displays it as plain text.
Triggered through controlled installation entries in the marketplace, local import, or conversation. The same complete file snapshot is installed after review. A snapshot is limited to 20 MiB of raw content and 5000 files. Symbolic links, special files, exceeded limits, or read failures are local validation failures and stop installation. Directly editing directories on disk is not guaranteed to trigger it.

SkillAdded

Reviews the complete file snapshot before skill installation, including SKILL.md, scripts, references, and other resources, not just the skill description. Request body:
FieldTypeDescription
sourcestringSource: marketplace (marketplace installation), local_import (local import or installation after creation in a conversation), manual_config (manual configuration and similar entries), or console (delivered by the enterprise console). Filled by the client.
content_digeststringSHA-256 hexadecimal digest of the pending content, used to correlate the review snapshot; not a download URL.
skillobjectSkill to install; see its fields below.
skill fieldTypeDescription
namestringSkill name.
versionstring, may be omittedOmitted if skill metadata declares no version.
filesarrayComplete pending file snapshot, each item containing path, encoding, and content.
File fieldTypeDescription
files[].pathstringRelative path within the package; not a local path or download URL the server can read directly.
files[].encodingstringMust be base64.
files[].contentstringBase64-encoded complete file content; decode it on the server for inspection.
Response body: Allow:
Reject:
If rejected, this skill is not installed into the active directory. As with connectors and plugins, the client displays reason directly rather than replacing it with a generic upload failure message.
Response fieldTypeDescription
decisionstringRequired; only allow or block. allow continues adding; block prevents this operation.
reasonstringAllowed only with block; required and nonblank. The client displays it as plain text.
Triggered through controlled installation entries in the marketplace, local import, or conversation. The same complete file snapshot is installed after review. A snapshot is limited to 20 MiB of raw content and 5000 files. Symbolic links, special files, exceeded limits, or read failures are local validation failures and stop installation. Directly editing directories on disk is not guaranteed to trigger it.