Skip to main content
v2

Advanced Guide (v2.0.10)

This page documents the current 2.0.10 MCP runtime: scoped planner/tool selection, current rule phases, next-tool guardrails, direct-tool execution, and the guarded Semantic Query branch.

Read order

  1. MCP Basics
  2. Advanced Guide (this page)
  3. Semantic Query
  4. Semantic Query Deep Dive
  5. Knowledge (Semantic Query)
  6. HTTP Tool
  7. Example 1
  8. Example 2
  9. Example 3
  10. Example 4 - Zapper Disconnect

Phase names (current)

  • PRE_RESPONSE_RESOLUTION
  • POST_AGENT_INTENT
  • POST_AGENT_MCP
  • POST_TOOL_EXECUTION

Compatibility note: legacy values (PIPELINE_RULES, AGENT_POST_INTENT, AGENT_POST_MCP, TOOL_POST_EXECUTION) are normalized at runtime.

Current MCP branches

MCP execution branches

BranchEntry pointWhat it doesKey guardrails
Planner MCPMcpToolStepRuns planner loop (`CALL_TOOL` / `ANSWER`) and accumulates `context.mcp.observations`.Next-tool guardrail, scoped `ce_mcp_tool`, scoped `ce_mcp_planner`.
Direct toolToolOrchestrationStepExecutes exactly one `tool_request` and writes `context.mcp.toolExecution`.Scoped tool lookup, `POST_TOOL_EXECUTION` rules.
Semantic queryMcpToolStep planner branchRuns semantic interpret -> query -> SQL execution chain inside planner loop.`db.semantic.interpret` must resolve canonical intent before `db.semantic.query`; SQL remains read-only.

Exact planner MCP order (current)

  1. Intent and state resolve through the normal pipeline.
  2. McpToolStep enters the planner loop.
  3. McpPlanner returns CALL_TOOL or ANSWER.
  4. For CALL_TOOL, the selected tool runs and a new row is appended to context.mcp.observations.
  5. The planner loops again until it returns ANSWER.
  6. context.mcp.finalAnswer is written.
  7. POST_AGENT_MCP rules run.
  8. PRE_RESPONSE_RESOLUTION rules run.
  9. ResponseResolutionStep still decides the final transport payload.

For the Semantic Query branch, the same planner loop is used, but the tool order is stricter:

  1. db.semantic.interpret
  2. db.semantic.query
  3. postgres.query
  4. planner ANSWER

Tool execution paths

Planner MCP path (McpToolStep)

  1. Planner returns CALL_TOOL or ANSWER.
  2. Tool results are appended to context.mcp.observations.
  3. For ANSWER, final text is written to context.mcp.finalAnswer.
  4. Rules run in phase POST_AGENT_MCP.
  5. Response resolution runs after rule transitions.

Direct tool path (ToolOrchestrationStep)

  1. Request contains tool_request.
  2. Exactly one tool executes.
  3. Result stored in inputParams.tool_result and context.mcp.toolExecution.
  4. Rules run in phase POST_TOOL_EXECUTION.
  5. Response resolution runs with updated state/context.

Prompt-template interaction semantics

ce_prompt_template is now part of the runtime contract, not just prompt text storage.

  • interaction_mode: broad turn semantics such as COLLECT, CONFIRM, PROCESSING, FINAL
  • interaction_contract: JSON for capabilities and expectations

Recommended shape:

{"allows":["affirm","edit","retry","reset"],"expects":["structured_input"]}

Why it matters:

  • CorrectionStep uses this to decide confirm/edit/retry behavior
  • confirmation-first MCP flows should model turn behavior here, not by naming states CONFIRM

Guardrail blocked answer semantics

When MCP_STATUS=GUARDRAIL_BLOCKED_NEXT_TOOL:

  1. McpToolStep writes fallback text (McpConstants.FALLBACK_GUARDRAIL_BLOCKED) to context.mcp.finalAnswer.
  2. Rules in POST_AGENT_MCP still execute.
  3. ce_response remains the final response authority (commonly DERIVED using context.mcp.finalAnswer).

For the Semantic Query path, there is one additional hard stop:

  1. if the planner proposes db.semantic.query before a successful db.semantic.interpret
  2. McpToolStep blocks execution with semantic validation guardrail reason
  3. audit and response resolution still continue through the normal MCP lifecycle

Read-only DB behavior

All MCP DB execution is now enforced as read-only.

  • generic DB tools are guarded
  • Semantic Query query templates are guarded
  • statements such as INSERT, UPDATE, DELETE, DROP, TRUNCATE, ALTER, CREATE, MERGE, and CALL are blocked
  • SELECT INTO, FOR UPDATE, and multi-statement SQL are blocked
  • ce_mcp_sql_guardrail can extend function allow/block rules without making the runtime writable

For postgres.query, an interceptor SPI runs before guardrail + execution:

  • PostgresQueryInterceptor (consumer extension point, ordered chain)
  • DefaultPostgresQueryInterceptor (framework fallback, lowest precedence)
  • default behavior auto-corrects invalid epoch conversion on timestamp/date columns (for example to_timestamp(ts_col/1000.0) when ts_col is already timestamp/date)

MCP metadata model for rules

context.mcp.lifecycle:

  • phase, status, outcome, finished
  • blocked, error, errorMessage
  • lastAction, lastToolCode, lastToolGroup, lastToolArgs
  • toolExecuted
  • finalAnswerDetermined (true when MCP final answer is set)
  • toolExecutionAbrupted (true when loop stops due to max-loop guard without final answer)
  • toolExecutionAbruptionLimit (configured loop guard limit)

context.mcp.toolExecution:

  • phase, status, outcome, finished
  • error, scopeMismatch, toolExecuted
  • toolCode, toolGroup, meta, result, errorMessage

JSON_PATH patterns you can use in ce_rule.match_pattern

$[?(@.context.mcp.lifecycle.finished == true && @.context.mcp.lifecycle.outcome == 'BLOCKED')]
$[?(@.context.mcp.lifecycle.error == true)]
$[?(@.context.mcp.toolExecution.phase == 'POST_TOOL_EXECUTION' && @.context.mcp.toolExecution.status == 'SUCCESS')]
$[?(@.context.mcp.toolExecution.scopeMismatch == true)]

Direct tool example (POST_TOOL_EXECUTION)

User asks: Check order ORD-7017 status.

{
"tool_request": {
"tool_code": "mock.order.status",
"tool_group": "HTTP_API",
"args": { "orderId": "ORD-7017" }
}
}

Execution:

  • ToolOrchestrationStep executes one tool.
  • writes tool_result + tool_status=SUCCESS
  • writes context.mcp.toolExecution.*
  • executes POST_TOOL_EXECUTION rules
  • example: a rule sets state to ORDER_SUBMITTED_DIAGNOSIS when tool status is submitted

ce_mcp_tool and ce_mcp_planner scoping rules

intent_code and state_code are mandatory (no null/blank scope).

Allowed values:

  • intent_code: defined ce_intent.intent_code or ANY or UNKNOWN
  • state_code: values present in ce_rule.state_code or ANY or UNKNOWN

Invalid scope rows are blocked at startup by static scope validation.

Planner prompt source (ce_mcp_planner)

Planner prompt selection:

  1. exact intent_code + state_code
  2. exact intent_code + ANY
  3. global ANY + ANY
  4. legacy fallback (ce_config McpPlanner keys) if planner rows are unavailable

SQL snippets

INSERT INTO ce_mcp_planner (planner_id, intent_code, state_code, system_prompt, user_prompt, enabled)
VALUES
(1001, 'ANY', 'ANY', '...', '...', true),
(1002, 'LOAN_APPLICATION', 'ELIGIBILITY_GATE', '...', '...', true);
Recommended response pattern

For MCP chains, keep final user text in ce_response/ce_prompt_template and treat context.mcp.finalAnswer as a derived source, not the final transport payload.

Where the detailed examples live

Use Example 3 for the full confirmation-first flow and Example 4 - Zapper Disconnect for the guarded Semantic Query path.