
* Command-handlers are classes that implement the WingHandler
  interface. The command's json parameters automatically get
  injected into the handler's properties using reflection
  code.  Check out a few handlers to see how this works.
  
* Class WingFetcher can precisely and easily retrieve objects
  of all different kinds using a 'path'.  Study the API
  of this class, we use it everywhere.  It is the best tool
  when you need the caller to specify a blueprint, or a
  graph, or a pin - you name it.

* When you want to scan for a list of assets, MCPAssets
  is the best tool.  This wraps Unreal's asset database
  in a convenient interface.  Please study this API.

* The only valid way to get a name for an object is using
  WingUtils::FormatName(obj).  We don't allow the use of
  pin->GetName, or node->GetTitle, or any other name-fetching
  routine.  Using only WingUtils::FormatName guarantees
  consistency: that means, names output by one tool can
  be parsed by a different tool.

* To check whether a string matches an object's name,
  there's only one valid way to do that as well: using
  bool WingUtils::Identifies(Name, Obj).

* Concise output is better.  The output of these handlers
  will primarily be consumed by LLMs with finite context
  windows.  Avoid sending information the caller didn't ask
  for.  Don't echo the command parameters: the caller knows
  what parameters he sent.  Don't make things unnecessarily
  verbose: "type=int varname=x" can be shortened to "int x."
  Generate output in a form that *you* would want to
  consume.

* You can pass the output StringBuilder directly into
  WingFetcher and MCPAssets.  If you do, these will automatically
  generate good error messages.  If either of these classes
  returns 'false', you don't need to generate an error
  message: it's already been done.  Any other routine that
  accepts MCPErrorCallback can do the same.

* It's good for handlers to do operations in batches,
  where possible.  SpawnNodes is better than SpawnNode.
  When an LLM calls into an MCP, it often takes 15 to 30
  seconds.  It's *important* that ConnectPins can do batches,
  because building a graph can involve connecting dozens
  of pins.

* It is traditional to use UE_LOG in unreal code, but it
  really doesn't work for us: you see, the LLM invoking the
  MCP can't see the log messages, so what's the point?
  Better to report problems via the response.  Please remove
  UE_LOG calls in handlers.

* When you're going to edit something, it's important to
  mark things dirty.  There's a very powerful tool for that:
  WingUtils::PreEdit and WingUtils::PostEdit, which can also
  be accessed through WingFetcher::PreEdit and PostEdit.
  These routines are very careful about marking everything
  dirty, so you don't have to worry about it.
