// protocol.proto — gRPC service contract between the Hermes Agent Runtime // (client, runs on the host machine) and the Android Runtime (server, runs // on the device or emulator). // // Generated stubs are NOT checked in; they are produced at build time by the // protoc-gen-grpc-java / grpc-kotlin plug-ins when the project adds gRPC // support to its Gradle configuration. syntax = "proto3"; package ai.lemon.phoneuse.mcpserver.protocol; option java_package = "ai.lemon.phoneuse.mcpserver.protocol"; option java_outer_classname = "ProtocolProto"; option java_multiple_files = true; import "google/protobuf/any.proto"; // --------------------------------------------------------------------------- // AndroidRuntime service // --------------------------------------------------------------------------- // AndroidRuntime is the primary entry-point exposed by the Agent Phone Runtime // running on the Android device. The Hermes Agent Runtime acts as the gRPC // client and issues calls over an authenticated, optionally-TLS-wrapped // channel. service AndroidRuntime { // Execute an action on the device (e.g. send a message, create a calendar // event). The call is synchronous from the caller's perspective; the // server blocks until the action completes or the supplied timeout_ms // elapses. rpc Execute(ActionRequest) returns (ActionResponse); // Query structured data from the device memory graph or a specific app // (e.g. contacts, recent messages, current app state). rpc Query(QueryRequest) returns (QueryResponse); // Subscribe to a stream of real-time events from the device. The server // pushes Event messages as they occur until the client cancels the stream // or the connection is closed. rpc Subscribe(SubscribeRequest) returns (stream Event); } // --------------------------------------------------------------------------- // Execute RPC — messages // --------------------------------------------------------------------------- // ActionRequest describes a single discrete action the Android Runtime should // perform on behalf of the Hermes Agent. message ActionRequest { // Identifies the action category. Must match a value in the ActionType // Kotlin enum (e.g. "SEND_MESSAGE", "CREATE_EVENT"). string action_type = 1; // Optional: the application that should handle this action (e.g. // "com.whatsapp", "com.android.calendar"). When absent the runtime // selects the default handler for the action type. optional string app_target = 2; // Arbitrary key/value parameters specific to the action_type. // See protocol_spec.md for the required and optional keys per action. map params = 3; // Caller-assigned correlation identifier. Echoed back in ActionResponse // so the client can match responses to outstanding requests. string request_id = 4; // Maximum time in milliseconds the runtime should wait before abandoning // the action and returning a TIMEOUT error. Must be > 0. int64 timeout_ms = 5; } // ActionResponse carries the outcome of a previously submitted ActionRequest. message ActionResponse { // Echoed from the corresponding ActionRequest.request_id. string request_id = 1; // true if the action completed successfully; false on any error. bool success = 2; // Action-specific result payload encoded as a JSON string. // Present when success == true; absent or empty on failure. // Using a plain string (rather than google.protobuf.Any) avoids requiring // the consumer to register type URLs and keeps the contract simple. string result_json = 3; // Human-readable error message. Present when success == false. string error = 4; // Wall-clock duration in milliseconds from action start to completion. int64 duration_ms = 5; } // --------------------------------------------------------------------------- // Query RPC — messages // --------------------------------------------------------------------------- // QueryType enumerates the first-class query targets supported by the runtime. enum QueryType { QUERY_TYPE_UNSPECIFIED = 0; MEMORY = 1; // Semantic memory graph APP_STATE = 2; // Live accessibility / foreground state of an app CONTACTS = 3; // Unified contacts from all integrated sources } // QueryRequest specifies what structured data the caller wants to retrieve. message QueryRequest { // Target data source to query. QueryType query_type = 1; // Optional key/value filter predicates applied by the runtime before // returning results. Filter semantics are query_type-specific; see // protocol_spec.md for supported keys per QueryType. map filters = 2; // Maximum number of results to return. Defaults to 20 when 0 is supplied. int32 limit = 3; } // QueryResponse returns a page of results for a QueryRequest. message QueryResponse { // Each element is a JSON-encoded object whose schema depends on // query_type (see protocol_spec.md). repeated string results_json = 1; // Total number of records that match the query (before limit is applied). int32 total_count = 2; // true if additional pages are available beyond the current limit. bool has_more = 3; } // --------------------------------------------------------------------------- // Subscribe RPC — messages // --------------------------------------------------------------------------- // SubscribeRequest tells the runtime which event categories the client wants // to receive. message SubscribeRequest { // List of event type strings to subscribe to (e.g. "APP_STATE_CHANGED", // "MESSAGE_RECEIVED"). An empty list is treated as "subscribe to all". repeated string event_types = 1; // Stable identifier for this subscriber (UUID or human-readable tag). // Used for deduplication and server-side fan-out logging. string subscriber_id = 2; } // Event is a single real-time notification pushed from the Android Runtime to // the Hermes Agent Runtime subscriber. message Event { // Discriminator string matching one of the known event types // (e.g. "APP_STATE_CHANGED", "MESSAGE_RECEIVED", "TASK_COMPLETED", // "ERROR"). Callers should handle unknown values gracefully. string event_type = 1; // JSON-encoded event-specific payload. Schema is event_type-dependent; // see protocol_spec.md for field definitions per event type. string payload_json = 2; // Unix epoch time in milliseconds when the event occurred on the device. int64 timestamp = 3; // Package name or system component that produced the event // (e.g. "com.whatsapp", "android.system"). string source = 4; }