Idea is to replace the explicit protocols implemented e.g. by QDeclarativeObserverService, QDeclarativeEngineDebugServer by a JavaScript API that can be explored by sending over JavaScript snippets from the debugging client to the server, and send the results back. Similar to the Python GDB interface.
Description of current protocols
JSDebugger
| Sender | Receiver | Message | Data | Reply | 
| Client | Service | EXEC | execId QByteArray name QString agentId uint | RESULT | 
| Client | Service | INTERRUPT | 
| Client | Service | CONTINUE | 
| Client | Service | STEPINTO | 
| Client | Service | STEPOUT | 
| Client | Service | STEPOVER | 
| Client | Service | ACTIVATE_FRAME | 
| Client | Service | EXPAND | 
| Client | Service | BREAKPOINTS | breakList QSet<QPair< QString, quint32> > | - | 
| Client | Service | SET_PROPERTY | 
| Client | Service | WATCH_EXPRESSIONS | 
| Client | Service | PING | int | 
| Service | Client | RESULT | execId QByteArray result JSAgentWatchData | 
| Service | Client | STOPPED | backtrace QList<QPair<QString, QPair<QString, qint32> > > watches QList<Internal::WatchData> locals QList<Internal::WatchData> becauseOfExpection bool exception QString | - | 
| Service | Client | RESULT | id, data | 
| Service | Client | EXPANDED | id, result | 
| Service | Client | LOCALS | frameId, locals | 
| Service | Client | PONG | ping | 
 
QmlDebug
| Sender | Receiver | Message | Data | Reply | 
| Client | Service | RESET_BINDING | int objectId, QString property | 
| Client | Service | WATCH_PROPERTY | 
| Client | Service | WATCH_EXPR_OBJECT | 
| Client | Service | WATCH_OBJECT | 
| Client | Service | NO_WATCH | 
| Client | Service | LIST_ENGINES | 
| Client | Service | LIST_OBJECTS | 
| Client | Service | FETCH_OBJECT | 
| Client | Service | EVAL_EXPRESSION | 
| Client | Service | SET_BINDING | 
| Client | Service | SET_METHOD_BODY | 
 
| Service | Client | LIST_ENGINES_R | 
| Service | Client | LIST_OBJECTS_R | 
| Service | Client | FETCH_OBJECT_R | 
| Service | Client | EVAL_EXPRESSION_R | 
| Service | Client | WATCH_PROPERTY_R | 
| Service | Client | WATCH_OBJECT_R | 
| Service | Client | WATCH_EXPR_OBJECT_R | 
| Service | Client | UPDATE_WATCH | 
| Service | Client | LIST_ENGINES_R | 
| Service | Client | OBJECT_CREATED | 
 
QmlJSObserver
| Sender | Receiver | Message | Data | Reply | 
| Client | Service | SET_CURRENT_OBJECTS | 
| Client | Service | OBJECT_ID_LIST | 
| Client | Service | SET_CONTEXT_PATH_IDX | 
| Client | Service | CLEAR_COMPONENT_CACHE | 
| Client | Service | RELOAD | 
| Client | Service | SET_DESIGN_MODE | 
| Client | Service | SET_ANIMATION_SPEED | 
| Client | Service | CHANGE_TOOL | [COLOR_PICKER|SELECT|SELECT_MARQUEE|ZOOM] | 
| Client | Service | CREATE_OBJECT | qmlSnippet, parentDebugId, imports, filename (with prefix _editorRevision:lineNumber) | 
| Client | Service | DESTROY_OBJECT | 
| Client | Service | MOVE_OBJECT | 
 
| Service | Client | CURRENT_OBJECTS_CHANGED | 
| Service | Client | TOOL_CHANGED | 
| Service | Client | ANIMATION_SPEED_CHANGED | 
| Service | Client | SET_DESIGN_MODE | 
| Service | Client | RELOADED | 
| Service | Client | COLOR_CHANGED | 
| Service | Client | CONTEXT_PATH_UPDATED | 
 
Other things
Use QByteArray instead of QString (makes debugger log more readable)