Files
isphere-ai-bridge/docs/mcp-core-tools-contract.md

370 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
## Hard boundaries
- No automatic login.
- No permission bypass.
- No process injection, hook, target-process memory read, credential extraction, or endpoint-security bypass.
- Search contacts, search groups, receive messages, and receive files should be implemented read-only first.
- Real message sending and file sending require `approval_id`.
- Without `approval_id`, write-capable tools must stay in `dry_run=true` behavior and must not send.
- Every real write must produce an audit record with target, content/file hash, approver, timestamp, source connector, and result.
- UIA selectors are allowed only as fallback access mechanics after higher-priority sources are exhausted or unavailable.
## 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. |
| `APPROVAL_REQUIRED` | A real write was requested without valid approval. |
| `DRY_RUN_ONLY` | Tool is currently limited to dry-run behavior. |
| `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",
"approval_id": null,
"dry_run": false,
"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 authorized iSphere contacts so a digital employee can resolve a person before reading or drafting work. |
| Read-only | Yes. |
| Requires `approval_id` | No. |
| Supports `dry_run` | Not required; optional `dry_run` may return the planned query only. |
| 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 authorized iSphere groups so a digital employee can resolve a group conversation before reading or drafting work. |
| Read-only | Yes. |
| Requires `approval_id` | No. |
| Supports `dry_run` | Not required; optional `dry_run` may return the planned query only. |
| 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 authorized recent messages and normalize them for digital employee reasoning and drafting. |
| Read-only | Yes. |
| Requires `approval_id` | No. |
| Supports `dry_run` | Optional; if true, returns source/query plan without message bodies. |
| 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",
"dry_run": "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 authorized files from messages without mutating the iSphere client state. |
| Read-only | Yes for source/client state. It may write downloaded files only to an operator-approved local output directory. |
| Requires `approval_id` | No for read-only listing or authorized download. Approval can be added later for sensitive destinations. |
| Supports `dry_run` | Yes. `dry_run=true` lists planned files and destination paths without downloading. |
| 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. Do not expand the roadmap beyond 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",
"dry_run": "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`, `DRY_RUN_ONLY`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`.
## Tool: `isphere_send_message`
| Field | Value |
| --- | --- |
| Business purpose | Send an approved text message to a resolved contact or group. |
| Read-only | No. |
| Requires `approval_id` | Yes for any real send. |
| Supports `dry_run` | Yes, required. Default must be `true` until production approval flow is accepted. |
| Current priority | Stage D approval-after-read-only loop. |
Input parameters:
```json
{
"target_type": "contact|group|conversation, required",
"target_id": "string, required",
"content_text": "string, required",
"approval_id": "string, required when dry_run=false",
"dry_run": "boolean, optional, default true",
"idempotency_key": "string, optional but recommended",
"source_preference": "bridge|uia|network|auto, optional, default auto"
}
```
Output JSON:
```json
{
"ok": true,
"dry_run": true,
"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`, `APPROVAL_REQUIRED`, `PERMISSION_DENIED`, `NOT_LOGGED_IN`, `TARGET_NOT_FOUND`, `AMBIGUOUS_TARGET`, `DRY_RUN_ONLY`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`.
## Tool: `isphere_send_file`
| Field | Value |
| --- | --- |
| Business purpose | Send an approved local file to a resolved contact or group. |
| Read-only | No. |
| Requires `approval_id` | Yes for any real send. |
| Supports `dry_run` | Yes, required. Default must be `true` until production approval flow is accepted. |
| 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; must be under an approved outbound directory",
"caption": "string, optional",
"approval_id": "string, required when dry_run=false",
"dry_run": "boolean, optional, default true",
"idempotency_key": "string, optional but recommended",
"source_preference": "bridge|uia|network|auto, optional, default auto"
}
```
Output JSON:
```json
{
"ok": true,
"dry_run": true,
"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`, `APPROVAL_REQUIRED`, `PERMISSION_DENIED`, `NOT_LOGGED_IN`, `TARGET_NOT_FOUND`, `AMBIGUOUS_TARGET`, `DRY_RUN_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 approval-backed write |
| 6 | `isphere_send_file` | D approval-backed write |