## 场景 03 · 接入外部数据源

为智能体挂载外部服务，扩展调用能力。

> **配置流程：** 创建服务 → （如需鉴权：查 Schema → 存凭证） → 启用服务 → 校验工具列表 → 对话中自动调用

## 路径 A：导入 MCP 服务

### Step 1: 导入 MCP 服务

POST /api/agent/finx/importMcpService — 支持标准 MCP JSON 格式

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| agentId | int64 | 智能体 ID（必填） |
| mcpServers | object | key=服务名, value=配置（仅 1 个条目） |
| autoGenerateDescription | bool | 自动生成描述 |

```bash
curl -X POST 'https://router.fis.aliyuncs.com/finx/api/agent/finx/importMcpService' \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'X-Principal-Id: <principalId>' \
  -H 'Content-Type: application/json' \
  -d '{
    "agentId": 1001,
    "autoGenerateDescription": true,
    "mcpServers": {
      "my-weather": {
        "type": "sse",
        "url": "https://example.com/mcp/sse"
      }
    }
  }'
```

## 路径 B：创建 HTTP 服务

### Step 1: 创建 HTTP 服务

POST /api/agent/finx/createHttpService

```bash
curl -X POST 'https://router.fis.aliyuncs.com/finx/api/agent/finx/createHttpService' \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'X-Principal-Id: <principalId>' \
  -H 'Content-Type: application/json' \
  -d '{"agentId":1001,"serviceName":"crm-api","httpConfig":{"baseUrl":"https://crm.example.com/api"}}'
```

### Step 2: 为服务添加工具

POST /api/agent/finx/createTool — 每个工具对应一个 HTTP 端点

| 字段 | 说明 |
| --- | --- |
| toolName | 工具名称（必填） |
| description | 工具描述（模型据此决定何时调用） |
| parameterSchema | 入参 JSON Schema |
| httpEndpoint | HTTP 端点配置（method、path） |

```bash
curl -X POST 'https://router.fis.aliyuncs.com/finx/api/agent/finx/createTool' \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'X-Principal-Id: <principalId>' \
  -H 'Content-Type: application/json' \
  -d '{"agentId":1001,"serviceId":5001,"toolName":"queryCustomer","description":"查询客户详情"}'
```

## 配置鉴权（按需）

### Step 1: 查询授权 Schema

POST /api/agent/finx/getAuthSchema — 获取需要填写的鉴权字段

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| agentId | int64 | 智能体 ID（必填） |
| serviceName | string | 服务名称（必填） |

```bash
curl -X POST 'https://router.fis.aliyuncs.com/finx/api/agent/finx/getAuthSchema' \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'X-Principal-Id: <principalId>' \
  -H 'Content-Type: application/json' \
  -d '{"agentId":1001,"serviceName":"my-weather"}'
```

### Step 2: 保存授权凭证

POST /api/agent/finx/saveAuthCredential — 提交凭证键值对

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| agentId | int64 | 智能体 ID（必填） |
| serviceName | string | 服务名称（必填） |
| credentials | object | 凭证键值对（必填），例如 `{"apiKey": "xxx"}` |

```bash
curl -X POST 'https://router.fis.aliyuncs.com/finx/api/agent/finx/saveAuthCredential' \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'X-Principal-Id: <principalId>' \
  -H 'Content-Type: application/json' \
  -d '{"agentId":1001,"serviceName":"my-weather","credentials":{"apiKey":"sk-xxxx"}}'
```

## 启用与校验

| 操作 | 方法 | 路径 |
| --- | --- | --- |
| 启用/禁用服务 | POST | /api/agent/finx/toggleServiceEnabled |
| 查询服务列表 | GET | /api/agent/finx/listServices |
| 查询工具列表 | GET | /api/agent/finx/listTools |
| 调试工具 | POST | /api/agent/finx/execute |

> **调试技巧**
> 
> 使用 POST /api/agent/finx/execute 直接调试工具，命令格式：`finx <服务名> <工具名> [--参数名 值]`

> 文件：`finx_tools.py`

```python
# 配置流程：创建服务 → 鉴权 → 启用 → 校验（MCP 推荐 / HTTP 可选）
# 两种接入方式：MCP（推荐）或 HTTP，均按 agentId 维度配置。
```

```python
# A. 导入 MCP 服务（最简，推荐）
def import_mcp_service(principal_id, agent_id, name, mcp_cfg):
    return unwrap(requests.post(
        f"{BASE_URL}/api/agent/finx/importMcpService",
        headers=auth_headers(principal_id),
        json={
            "agentId": agent_id,
            "autoGenerateDescription": True,
            "mcpServers": {name: mcp_cfg},
        },
    ))
```

```python
# B1. 创建 HTTP 服务 → serviceId
def create_http_service(principal_id, agent_id, name, http_cfg):
    return unwrap(requests.post(
        f"{BASE_URL}/api/agent/finx/createHttpService",
        headers=auth_headers(principal_id),
        json={
            "agentId": agent_id,
            "serviceName": name,
            "httpConfig": http_cfg,
        },
    ))
```

```python
# B2. 为 HTTP 服务添加工具 → toolId
def create_tool(
    principal_id, agent_id, sid, name, desc, schema, ep,
):
    return unwrap(requests.post(
        f"{BASE_URL}/api/agent/finx/createTool",
        headers=auth_headers(principal_id),
        json={
            "agentId": agent_id,
            "serviceId": sid,
            "toolName": name,
            "description": desc,
            "parameterSchema": schema,
            "httpEndpoint": ep,
        },
    ))
```

```python
# 鉴权 1：查询授权 Schema
def get_auth_schema(principal_id, agent_id, service_name):
    return unwrap(requests.post(
        f"{BASE_URL}/api/agent/finx/getAuthSchema",
        headers=auth_headers(principal_id),
        json={
            "agentId": agent_id,
            "serviceName": service_name,
        },
    ))
```

```python
# 鉴权 2：保存授权凭证
def save_auth_credential(
    principal_id, agent_id, service_name, creds,
):
    return unwrap(requests.post(
        f"{BASE_URL}/api/agent/finx/saveAuthCredential",
        headers=auth_headers(principal_id),
        json={
            "agentId": agent_id,
            "serviceName": service_name,
            "credentials": creds,
        },
    ))
```

```python
# 启用与校验
def toggle_service(principal_id, agent_id, name, enabled=True):
    return unwrap(requests.post(
        f"{BASE_URL}/api/agent/finx/toggleServiceEnabled",
        headers=auth_headers(principal_id),
        json={
            "agentId": agent_id,
            "serviceName": name,
            "enabled": enabled,
        },
    ))

def list_tools(principal_id, agent_id, name):
    return unwrap(requests.get(
        f"{BASE_URL}/api/agent/finx/listTools",
        headers=auth_headers(principal_id, json_body=False),
        params={"agentId": agent_id, "serviceName": name},
    ))

if __name__ == "__main__":
    pid = create_principal()
    aid = create_agent(pid)
    import_mcp_service(pid, aid, "my-weather", {
        "type": "sse",
        "url": "https://example.com/mcp/sse",
    })
    toggle_service(pid, aid, "my-weather", True)
    print("已加载工具:", list_tools(pid, aid, "my-weather"))
```
