Class McpCallRecord

java.lang.Object
com.mcpdbwizard.pub.McpCallRecord

public final class McpCallRecord extends Object
One line per MCP tool call, for the operator: which tool ran, how it ended, and how long it took.

The generated server funnels every tool handler through a single call(...) helper, which writes one of these afterwards. Before this existed the funnel logged nothing at all — a failure went back to the caller as an error result and left no server-side trace, pool exhaustion included.

The format is a fixed prefix followed by a JSON object, so it can be grepped out of a mixed log and parsed without one:

MCP-CALL {"tool":"ob_gen_pkg_greet","outcome":"ok","ms":12,"args":["p_name"]}

Argument names, never argument values

Only the argument names are recorded. This is the one place where an MCP server differs sharply from an ordinary service: the values were chosen by a model rather than by a programmer, so they are the most interesting thing here and also the most dangerous — they can carry anything the caller put in front of the model, including personal data. Names give the shape of the call without that risk. Recording values should be a separate, explicit opt-in, and is deliberately not built.

This is not an audit trail. It is a diagnostic record written to a log that the process itself owns, so it has no durability, ordering or tamper-evidence guarantees. A real audit trail needs a sink that survives the container and cannot be rewritten by the thing being audited. Copyright 2003-2026 ATB Consultancy Services Ltd (formerly Orinda Software Ltd, Dublin, Ireland)

  • Field Details

    • PREFIX

      public static final String PREFIX
      Marks the line, so it can be found in a log carrying everything else too.
      See Also:
    • OUTCOME_OK

      public static final String OUTCOME_OK
      The tool ran and returned data.
      See Also:
    • OUTCOME_NOT_FOUND

      public static final String OUTCOME_NOT_FOUND
      The tool ran and found nothing — a normal answer, not a failure.
      See Also:
    • OUTCOME_DOCUMENT_CHANGED

      public static final String OUTCOME_DOCUMENT_CHANGED
      Optimistic-lock clash: the document changed since it was read.
      See Also:
    • OUTCOME_POOL_EXHAUSTED

      public static final String OUTCOME_POOL_EXHAUSTED
      Every pooled factory is checked out and the pool is at its ceiling. Load, not a fault.
      See Also:
    • OUTCOME_RATE_LIMITED

      public static final String OUTCOME_RATE_LIMITED
      Refused by the configured rate limit — load shed by policy, not by saturation.
      See Also:
    • OUTCOME_DATABASE_ERROR

      public static final String OUTCOME_DATABASE_ERROR
      The database refused the work.
      See Also:
    • OUTCOME_CONTEXT_REFUSED

      public static final String OUTCOME_CONTEXT_REFUSED
      Refused before reaching the database: a URL context parameter was missing, empty, undeclared or repeated. The caller's configuration is wrong, not the server or the data.
      See Also:
    • OUTCOME_ERROR

      public static final String OUTCOME_ERROR
      Anything else, including a bug in the generated code.
      See Also:
  • Method Details

    • line

      public static String line(String theToolName, Map<String,Object> theArguments, String theOutcome, long theMilliseconds)
      Build the record.
      Parameters:
      theToolName - the MCP tool that was invoked
      theArguments - the call's arguments; only the keys are used, and null is fine
      theOutcome - one of the OUTCOME_ constants
      theMilliseconds - wall-clock duration of the call
    • line

      public static String line(String theToolName, Map<String,Object> theArguments, String theOutcome, long theMilliseconds, Map<String,String> theContext)
      Build the record, with the URL context parameters the call ran under.

      Their VALUES are recorded, unlike the arguments': a model did not choose them, and "for which customer did this run" is the first thing an operator reading this line needs. They are identifiers, never secrets. Null or empty writes no context key at all, so a server without context parameters writes exactly the line it wrote before they existed.

      Parameters:
      theContext - name to value, or null