357 lines
11 KiB
Markdown
357 lines
11 KiB
Markdown
# MCP Core Tools Contract
|
||
|
||
Date: 2026-07-09
|
||
|
||
## Route statement
|
||
|
||
项目核心不是继续做 UIA selector/report,而是通过 MCP 暴露 iSphere 的联系人、群组、消息、文件能力。
|
||
|
||
This contract defines the business-facing MCP tool surface. The existing `win_helper_*` tools remain low-level auxiliary tools for controlled read-only observation and fallback implementation work. They are not the product API.
|
||
|
||
## Implementation staging
|
||
|
||
- Build contact, group, message, and file read paths first because they unlock the digital employee workflow.
|
||
- Treat send message and send file as write-capable tools with preview, execution metadata, and audit fields.
|
||
- Use UIA selectors only where higher-priority sources cannot provide the required business capability.
|
||
|
||
|
||
## Common error codes
|
||
|
||
| Code | Meaning |
|
||
| --- | --- |
|
||
| `INVALID_ARGUMENT` | Required parameter missing or invalid. |
|
||
| `SOURCE_UNAVAILABLE` | Selected bridge/API/database/UIA source is unavailable. |
|
||
| `NOT_LOGGED_IN` | A required manually logged-in client session is not present. |
|
||
| `PERMISSION_DENIED` | Current operator/account is not authorized for the requested object. |
|
||
| `WRITE_NOT_READY` | The selected write connector is not ready for execution. |
|
||
| `PREVIEW_ONLY` | Tool returned a preview instead of executing the write. |
|
||
| `TARGET_NOT_FOUND` | Contact, group, conversation, message, or file was not found. |
|
||
| `AMBIGUOUS_TARGET` | Multiple possible targets match and the request must be narrowed. |
|
||
| `TIMEOUT` | The connector did not complete before timeout. |
|
||
| `CONNECTOR_FAILED` | Underlying source or helper returned a structured failure. |
|
||
| `INTERNAL_ERROR` | Unexpected implementation error. |
|
||
|
||
## Common audit fields
|
||
|
||
Every tool response should include an `audit` object:
|
||
|
||
```json
|
||
{
|
||
"tool": "isphere_search_contacts",
|
||
"request_id": "uuid",
|
||
"source": "bridge|local_readonly|uia|network|mock",
|
||
"operator_id": "optional operator identity",
|
||
"execution_mode": "read|preview|production",
|
||
"target_ref": "optional stable target reference",
|
||
"content_sha256": null,
|
||
"file_sha256": null,
|
||
"started_at": "ISO-8601",
|
||
"finished_at": "ISO-8601",
|
||
"result": "ok|error"
|
||
}
|
||
```
|
||
|
||
## Tool: `isphere_search_contacts`
|
||
|
||
| Field | Value |
|
||
| --- | --- |
|
||
| Business purpose | Search iSphere contacts so a digital employee can resolve a person before reading or drafting work. |
|
||
| Read-only | Yes. |
|
||
| Execution mode | Query preview or normal read. |
|
||
| Current priority | Stage C read-only loop, first priority. |
|
||
|
||
Input parameters:
|
||
|
||
```json
|
||
{
|
||
"query": "string, required",
|
||
"limit": "integer, optional, default 20, max 100",
|
||
"cursor": "string, optional",
|
||
"source_preference": "bridge|local_readonly|uia|network|auto, optional, default auto",
|
||
"include_inactive": "boolean, optional, default false"
|
||
}
|
||
```
|
||
|
||
Output JSON:
|
||
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"contacts": [
|
||
{
|
||
"contact_id": "string",
|
||
"display_name": "string",
|
||
"account": "string|null",
|
||
"department": "string|null",
|
||
"title": "string|null",
|
||
"source": "bridge|local_readonly|uia|network|mock",
|
||
"confidence": 0.98,
|
||
"raw_ref": "redacted source reference"
|
||
}
|
||
],
|
||
"next_cursor": null,
|
||
"audit": {}
|
||
}
|
||
```
|
||
|
||
Errors: `INVALID_ARGUMENT`, `SOURCE_UNAVAILABLE`, `NOT_LOGGED_IN`, `PERMISSION_DENIED`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`.
|
||
|
||
## Tool: `isphere_search_groups`
|
||
|
||
| Field | Value |
|
||
| --- | --- |
|
||
| Business purpose | Search iSphere groups so a digital employee can resolve a group conversation before reading or drafting work. |
|
||
| Read-only | Yes. |
|
||
| Execution mode | Query preview or normal read. |
|
||
| Current priority | Stage C read-only loop, first priority. |
|
||
|
||
Input parameters:
|
||
|
||
```json
|
||
{
|
||
"query": "string, required",
|
||
"limit": "integer, optional, default 20, max 100",
|
||
"cursor": "string, optional",
|
||
"source_preference": "bridge|local_readonly|uia|network|auto, optional, default auto",
|
||
"include_archived": "boolean, optional, default false"
|
||
}
|
||
```
|
||
|
||
Output JSON:
|
||
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"groups": [
|
||
{
|
||
"group_id": "string",
|
||
"display_name": "string",
|
||
"member_count": "integer|null",
|
||
"owner_ref": "string|null",
|
||
"source": "bridge|local_readonly|uia|network|mock",
|
||
"confidence": 0.96,
|
||
"raw_ref": "redacted source reference"
|
||
}
|
||
],
|
||
"next_cursor": null,
|
||
"audit": {}
|
||
}
|
||
```
|
||
|
||
Errors: `INVALID_ARGUMENT`, `SOURCE_UNAVAILABLE`, `NOT_LOGGED_IN`, `PERMISSION_DENIED`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`.
|
||
|
||
## Tool: `isphere_receive_messages`
|
||
|
||
| Field | Value |
|
||
| --- | --- |
|
||
| Business purpose | Read recent iSphere messages and normalize them for digital employee reasoning and drafting. |
|
||
| Read-only | Yes. |
|
||
| Execution mode | Source/query preview or normal read. |
|
||
| Current priority | Stage C read-only loop, first priority after contact/group source discovery. |
|
||
|
||
Input parameters:
|
||
|
||
```json
|
||
{
|
||
"conversation_id": "string, optional when query is supplied",
|
||
"conversation_type": "direct|group|system|unknown, optional",
|
||
"query": "string, optional target name or keyword",
|
||
"since": "ISO-8601 timestamp, optional",
|
||
"limit": "integer, optional, default 50, max 200",
|
||
"cursor": "string, optional",
|
||
"include_attachment_metadata": "boolean, optional, default true",
|
||
"source_preference": "bridge|local_readonly|uia|network|auto, optional, default auto",
|
||
"preview": "boolean, optional, default false"
|
||
}
|
||
```
|
||
|
||
Output JSON:
|
||
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"conversation": {
|
||
"conversation_id": "string",
|
||
"conversation_type": "direct|group|system",
|
||
"display_name": "string"
|
||
},
|
||
"messages": [
|
||
{
|
||
"message_id": "string",
|
||
"sender_id": "string|null",
|
||
"sender_name": "string|null",
|
||
"content_type": "text|image|file|rich|notify|unknown",
|
||
"content_text": "authorized text or redacted summary",
|
||
"attachments": [
|
||
{
|
||
"file_id": "string",
|
||
"file_name": "string",
|
||
"size_bytes": "integer|null",
|
||
"download_ref": "string|null"
|
||
}
|
||
],
|
||
"created_at": "ISO-8601|null",
|
||
"received_at": "ISO-8601|null",
|
||
"source": "bridge|local_readonly|uia|network|mock",
|
||
"raw_ref": "redacted source reference"
|
||
}
|
||
],
|
||
"next_cursor": null,
|
||
"audit": {}
|
||
}
|
||
```
|
||
|
||
Errors: `INVALID_ARGUMENT`, `SOURCE_UNAVAILABLE`, `NOT_LOGGED_IN`, `PERMISSION_DENIED`, `TARGET_NOT_FOUND`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`.
|
||
|
||
## Tool: `isphere_receive_files`
|
||
|
||
| Field | Value |
|
||
| --- | --- |
|
||
| Business purpose | List and receive/download files from messages while preserving the iSphere client state. |
|
||
| Read-only | Yes for source/client state. It writes downloaded files to a configured local output directory. |
|
||
| Execution mode | List/download preview or normal download. |
|
||
| Current priority | Stage C read-only loop after messages expose file metadata. |
|
||
|
||
Implementation note: if the implementation becomes clearer with two internal operations, split into `list_files` and `download_file` behind this business contract. Keep the roadmap focused on receive/download.
|
||
|
||
Input parameters:
|
||
|
||
```json
|
||
{
|
||
"conversation_id": "string, optional",
|
||
"message_id": "string, optional",
|
||
"file_id": "string, optional for download, omitted for list",
|
||
"mode": "list|download, optional, default list",
|
||
"output_dir": "string, optional, required for download",
|
||
"limit": "integer, optional, default 50, max 200",
|
||
"cursor": "string, optional",
|
||
"source_preference": "bridge|local_readonly|uia|network|auto, optional, default auto",
|
||
"preview": "boolean, optional, default true for download"
|
||
}
|
||
```
|
||
|
||
Output JSON:
|
||
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"mode": "list|download",
|
||
"files": [
|
||
{
|
||
"file_id": "string",
|
||
"message_id": "string|null",
|
||
"conversation_id": "string|null",
|
||
"file_name": "string",
|
||
"size_bytes": "integer|null",
|
||
"mime_type": "string|null",
|
||
"created_at": "ISO-8601|null",
|
||
"download_ref": "string|null",
|
||
"saved_path": "string|null",
|
||
"sha256": "string|null",
|
||
"source": "bridge|local_readonly|uia|network|mock"
|
||
}
|
||
],
|
||
"next_cursor": null,
|
||
"audit": {}
|
||
}
|
||
```
|
||
|
||
Errors: `INVALID_ARGUMENT`, `SOURCE_UNAVAILABLE`, `NOT_LOGGED_IN`, `PERMISSION_DENIED`, `TARGET_NOT_FOUND`, `PREVIEW_ONLY`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`.
|
||
|
||
## Tool: `isphere_send_message`
|
||
|
||
| Field | Value |
|
||
| --- | --- |
|
||
| Business purpose | Send a text message to a resolved contact or group. |
|
||
| Read-only | No. |
|
||
| Execution mode | Preview or production write. |
|
||
| Current priority | Stage D write capability. |
|
||
|
||
Input parameters:
|
||
|
||
```json
|
||
{
|
||
"target_type": "contact|group|conversation, required",
|
||
"target_id": "string, required",
|
||
"content_text": "string, required",
|
||
"execution_mode": "preview|production, optional, default preview",
|
||
"idempotency_key": "string, optional but recommended",
|
||
"source_preference": "bridge|uia|network|auto, optional, default auto"
|
||
}
|
||
```
|
||
|
||
Output JSON:
|
||
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"execution_mode": "preview",
|
||
"send_status": "planned|sent|rejected",
|
||
"target": {
|
||
"target_type": "contact|group|conversation",
|
||
"target_id": "string",
|
||
"display_name": "string|null"
|
||
},
|
||
"message_ref": null,
|
||
"content_sha256": "sha256 hex",
|
||
"audit": {}
|
||
}
|
||
```
|
||
|
||
Errors: `INVALID_ARGUMENT`, `WRITE_NOT_READY`, `PERMISSION_DENIED`, `NOT_LOGGED_IN`, `TARGET_NOT_FOUND`, `AMBIGUOUS_TARGET`, `PREVIEW_ONLY`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`.
|
||
|
||
## Tool: `isphere_send_file`
|
||
|
||
| Field | Value |
|
||
| --- | --- |
|
||
| Business purpose | Send a local file to a resolved contact or group. |
|
||
| Read-only | No. |
|
||
| Execution mode | Preview or production write. |
|
||
| Current priority | Stage D after `isphere_send_message`. |
|
||
|
||
Input parameters:
|
||
|
||
```json
|
||
{
|
||
"target_type": "contact|group|conversation, required",
|
||
"target_id": "string, required",
|
||
"file_path": "string, required; use configured outbound directory",
|
||
"caption": "string, optional",
|
||
"execution_mode": "preview|production, optional, default preview",
|
||
"idempotency_key": "string, optional but recommended",
|
||
"source_preference": "bridge|uia|network|auto, optional, default auto"
|
||
}
|
||
```
|
||
|
||
Output JSON:
|
||
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"execution_mode": "preview",
|
||
"send_status": "planned|sent|rejected",
|
||
"target": {
|
||
"target_type": "contact|group|conversation",
|
||
"target_id": "string",
|
||
"display_name": "string|null"
|
||
},
|
||
"file_ref": null,
|
||
"file_sha256": "sha256 hex",
|
||
"file_size_bytes": 12345,
|
||
"audit": {}
|
||
}
|
||
```
|
||
|
||
Errors: `INVALID_ARGUMENT`, `WRITE_NOT_READY`, `PERMISSION_DENIED`, `NOT_LOGGED_IN`, `TARGET_NOT_FOUND`, `AMBIGUOUS_TARGET`, `PREVIEW_ONLY`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`.
|
||
|
||
## Stage priority summary
|
||
|
||
| Priority | Tool | Stage |
|
||
| --- | --- | --- |
|
||
| 1 | `isphere_search_contacts` | C read-only loop |
|
||
| 2 | `isphere_search_groups` | C read-only loop |
|
||
| 3 | `isphere_receive_messages` | C read-only loop |
|
||
| 4 | `isphere_receive_files` | C read-only loop |
|
||
| 5 | `isphere_send_message` | D write capability |
|
||
| 6 | `isphere_send_file` | D write capability |
|