Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions gitbooks/developing/mcp-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,34 @@ session:
| --- | --- |
| `openhuman.tool_registry_list` | List MCP stdio tools and controller-backed tools with stable `tool_id`, route, version, input/output schemas, allowed agents, tags, enabled state, and health. |
| `openhuman.tool_registry_get` | Return one registry entry by `tool_id`, for example `memory.search` or `tools.web_search`. |
| `openhuman.tool_registry_diagnostics` | Return redacted inventory counts, write-surface candidates, policy surfaces, and external capability-provider diagnostics. |

The registry is discovery-only. It does not change tool dispatch or permission
checks; MCP calls still go through `tools/call`, and controller-backed tools
still route through their existing JSON-RPC methods.

### External Capability Providers

OpenHuman can record trusted external capability providers in `config.toml`.
This is governance metadata only: it does not install packages, execute remote
code, or bypass the existing MCP/controller dispatch paths.

```toml
[[capability_providers]]
id = "Acme Tools"
display_name = "Acme Tools"
source_uri = "https://example.com/openhuman/acme-tools"
source_digest = "sha256:abc123"
trust_state = "trusted"
enabled = true
```

Provider ids are normalized before policy checks. For example, `Acme Tools`
becomes `acme-tools`; duplicates after normalization are rejected. A provider is
eligible for future admission checks only when it is both `enabled = true` and
`trust_state = "trusted"`. Missing provider config preserves the previous
behavior: the provider registry is empty and no existing tools are hidden.

## Smoke Test

```bash
Expand Down
17 changes: 17 additions & 0 deletions gitbooks/developing/mcp-server.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,26 @@ HTTP JSON-RPC 服务器还暴露一个只读的全局工具注册表,供需要
| --- | --- |
| `openhuman.tool_registry_list` | 列出 MCP stdio 工具和控制器支持的工具,包含稳定的 `tool_id`、路由、版本、输入/输出 schema、允许的智能体、标签、启用状态和健康状况。 |
| `openhuman.tool_registry_get` | 通过 `tool_id` 返回一个注册表条目,例如 `memory.search` 或 `tools.web_search`。 |
| `openhuman.tool_registry_diagnostics` | 返回脱敏的清单统计、疑似写入面、策略面以及外部能力提供方诊断信息。 |

注册表仅用于发现。它不改变工具分派或权限检查;MCP 调用仍通过 `tools/call`,控制器支持的工具仍通过其现有的 JSON-RPC 方法路由。

### 外部能力提供方

OpenHuman 可以在 `config.toml` 中记录可信外部能力提供方。这只是治理元数据:不会安装包、执行远程代码,也不会绕过现有 MCP/控制器分派路径。

```toml
[[capability_providers]]
id = "Acme Tools"
display_name = "Acme Tools"
source_uri = "https://example.com/openhuman/acme-tools"
source_digest = "sha256:abc123"
trust_state = "trusted"
enabled = true
```

Provider id 会在策略检查前规范化。例如 `Acme Tools` 会变成 `acme-tools`;规范化后重复的 id 会被拒绝。只有同时满足 `enabled = true` 和 `trust_state = "trusted"` 的提供方,才会被后续准入检查视为可用。没有 provider 配置时保持旧行为:provider 注册表为空,现有工具不会被隐藏。

## 冒烟测试

```bash
Expand Down
4 changes: 2 additions & 2 deletions src/openhuman/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Authoritative TOML-backed configuration layer. Owns the `Config` schema (every d
## Public surface

- `pub struct Config` — `schema/types.rs` (re-exported `mod.rs:28`) — top-level user settings.
- Per-domain config structs (re-exported `mod.rs:28-39`): `AgentConfig`, `AuditConfig`, `AutocompleteConfig`, `AutonomyConfig`, `BrowserComputerUseConfig`, `BrowserConfig`, `ChannelsConfig`, `ComposioConfig`, `ContextConfig`, `CostConfig`, `CronConfig`, `CurlConfig`, `DelegateAgentConfig`, `DictationConfig`, `DiscordConfig`, `DockerRuntimeConfig`, `EmbeddingRouteConfig`, `GitbooksConfig`, `HeartbeatConfig`, `HttpRequestConfig`, `IMessageConfig`, `IntegrationsConfig`, `LarkConfig`, `LearningConfig`, `LocalAiConfig`, `MatrixConfig`, `MemoryConfig`, `ModelRouteConfig`, `MultimodalConfig`, `ObservabilityConfig`, `ProxyConfig`, `ReliabilityConfig`, `ResourceLimitsConfig`, `RuntimeConfig`, `SandboxConfig`, `SchedulerConfig`, `ScreenIntelligenceConfig`, `SecretsConfig`, `SecurityConfig`, `SlackConfig`, `StorageConfig`, `TelegramConfig`, `UpdateConfig`, `VoiceServerConfig`, `WebSearchConfig`, `WebhookConfig`.
- Enums: `DictationActivationMode`, `IntegrationToggle`, `ProxyScope`, `ReflectionSource`, `SandboxBackend`, `StorageProviderConfig`, `StorageProviderSection`, `StreamMode`, `VoiceActivationMode`.
- Per-domain config structs (re-exported `mod.rs:28-39`): `AgentConfig`, `AuditConfig`, `AutocompleteConfig`, `AutonomyConfig`, `BrowserComputerUseConfig`, `BrowserConfig`, `CapabilityProviderConfig`, `ChannelsConfig`, `ComposioConfig`, `ContextConfig`, `CostConfig`, `CronConfig`, `CurlConfig`, `DelegateAgentConfig`, `DictationConfig`, `DiscordConfig`, `DockerRuntimeConfig`, `EmbeddingRouteConfig`, `GitbooksConfig`, `HeartbeatConfig`, `HttpRequestConfig`, `IMessageConfig`, `IntegrationsConfig`, `LarkConfig`, `LearningConfig`, `LocalAiConfig`, `MatrixConfig`, `MemoryConfig`, `ModelRouteConfig`, `MultimodalConfig`, `ObservabilityConfig`, `ProxyConfig`, `ReliabilityConfig`, `ResourceLimitsConfig`, `RuntimeConfig`, `SandboxConfig`, `SchedulerConfig`, `ScreenIntelligenceConfig`, `SecretsConfig`, `SecurityConfig`, `SlackConfig`, `StorageConfig`, `TelegramConfig`, `UpdateConfig`, `VoiceServerConfig`, `WebSearchConfig`, `WebhookConfig`.
- Enums: `CapabilityProviderTrustState`, `DictationActivationMode`, `IntegrationToggle`, `ProxyScope`, `ReflectionSource`, `SandboxBackend`, `StorageProviderConfig`, `StorageProviderSection`, `StreamMode`, `VoiceActivationMode`.
- Model constants: `DEFAULT_MODEL`, `MODEL_AGENTIC_V1`, `MODEL_CODING_V1`, `MODEL_REASONING_V1`.
- `pub struct DaemonConfig` — `daemon.rs` — sidecar lifecycle / port descriptor.
- `pub fn apply_runtime_proxy_to_builder` / `pub fn build_runtime_proxy_client` / `pub fn build_runtime_proxy_client_with_timeouts` / `pub fn runtime_proxy_config` / `pub fn set_runtime_proxy_config` — `schema/proxy.rs`.
Expand Down
3 changes: 2 additions & 1 deletion src/openhuman/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ pub use schema::{
apply_runtime_proxy_to_builder, build_runtime_proxy_client,
build_runtime_proxy_client_with_timeouts, output_language_directive, runtime_proxy_config,
set_runtime_proxy_config, AgentConfig, AuditConfig, AutocompleteConfig, AutonomyConfig,
BrowserComputerUseConfig, BrowserConfig, ChannelsConfig, ComposioConfig, Config, ContextConfig,
BrowserComputerUseConfig, BrowserConfig, CapabilityProviderConfig,
CapabilityProviderTrustState, ChannelsConfig, ComposioConfig, Config, ContextConfig,
CostConfig, CronConfig, CurlConfig, DelegateAgentConfig, DictationActivationMode,
DictationConfig, DiscordConfig, DockerRuntimeConfig, EmbeddingRouteConfig, GitbooksConfig,
HeartbeatConfig, HttpRequestConfig, IMessageConfig, IntegrationToggle, IntegrationsConfig,
Expand Down
53 changes: 53 additions & 0 deletions src/openhuman/config/schema/capability_providers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//! External capability-provider trust metadata.

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// Configured external capability provider metadata.
///
/// The registry layer normalizes and validates `id` before policy code uses it.
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
#[serde(default)]
pub struct CapabilityProviderConfig {
/// Human-configured provider id. Registry normalization makes this stable.
pub id: String,
/// Display name for diagnostics and future UI surfaces.
pub display_name: String,
/// Optional source URI for provenance, such as a GitHub repo or MCP catalog URL.
pub source_uri: Option<String>,
/// Optional source digest, for example `sha256:<hex>`.
pub source_digest: Option<String>,
/// Explicit trust state. Defaults to `untrusted` for fail-closed behavior.
pub trust_state: CapabilityProviderTrustState,
/// Whether this provider is enabled for discovery/admission.
pub enabled: bool,
}

impl Default for CapabilityProviderConfig {
fn default() -> Self {
Self {
id: String::new(),
display_name: String::new(),
source_uri: None,
source_digest: None,
trust_state: CapabilityProviderTrustState::Untrusted,
enabled: false,
}
}
}

/// Trust state for an external capability provider.
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum CapabilityProviderTrustState {
/// Provider metadata is accepted, but capabilities from it are not trusted.
Untrusted,
/// Provider is explicitly trusted by local config.
Trusted,
}

impl Default for CapabilityProviderTrustState {
fn default() -> Self {
Self::Untrusted
}
}
2 changes: 2 additions & 0 deletions src/openhuman/config/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod accessibility;
mod agent;
mod autocomplete;
mod autonomy;
mod capability_providers;
mod channels;
mod context;
mod defaults;
Expand Down Expand Up @@ -43,6 +44,7 @@ pub use agent::{
};
pub use autocomplete::AutocompleteConfig;
pub use autonomy::AutonomyConfig;
pub use capability_providers::{CapabilityProviderConfig, CapabilityProviderTrustState};
pub use channels::{
AuditConfig, ChannelsConfig, DingTalkConfig, DiscordConfig, IMessageConfig, IrcConfig,
LarkConfig, LarkReceiveMode, MatrixConfig, MattermostConfig, QQConfig, ResourceLimitsConfig,
Expand Down
30 changes: 30 additions & 0 deletions src/openhuman/config/schema/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ pub struct Config {
#[serde(default)]
pub mcp_client: McpClientConfig,

/// Trust metadata for external capability providers. Empty by default so
/// existing installations keep the same tool-discovery behavior.
#[serde(default)]
pub capability_providers: Vec<CapabilityProviderConfig>,

#[serde(default)]
pub multimodal: MultimodalConfig,

Expand Down Expand Up @@ -617,6 +622,7 @@ impl Default for Config {
curl: CurlConfig::default(),
gitbooks: GitbooksConfig::default(),
mcp_client: McpClientConfig::default(),
capability_providers: Vec::new(),
multimodal: MultimodalConfig::default(),
seltz: SeltzConfig::default(),
searxng: SearxngConfig::default(),
Expand Down Expand Up @@ -724,6 +730,30 @@ mod model_pin_tests {
);
}

#[test]
fn config_parses_capability_provider_entries() {
let config: Config = toml::from_str(
r#"
[[capability_providers]]
id = "Acme Tools"
display_name = "Acme Tools"
source_uri = "https://example.com/openhuman/acme-tools"
source_digest = "sha256:abc123"
trust_state = "trusted"
enabled = true
"#,
)
.expect("config should parse capability providers");

assert_eq!(config.capability_providers.len(), 1);
assert_eq!(config.capability_providers[0].id, "Acme Tools");
assert_eq!(
config.capability_providers[0].trust_state,
CapabilityProviderTrustState::Trusted
);
assert!(config.capability_providers[0].enabled);
}

#[test]
fn empty_model_pin_values_fall_back_to_auto_routing() {
let mut config = Config::default();
Expand Down
11 changes: 9 additions & 2 deletions src/openhuman/tool_registry/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
//! Unified read-only tool registry for discovery across OpenHuman tool surfaces.

pub mod ops;
mod providers;
mod schemas;
mod types;

pub use ops::{get_tool, list_tools, registry_entries};
pub use providers::{
capability_provider_by_id, capability_provider_diagnostics, capability_provider_registry,
is_capability_provider_trusted_enabled, list_capability_providers,
normalize_capability_provider_id, CapabilityProviderMetadata, CapabilityProviderRegistry,
CapabilityProviderRegistryError,
};
pub use schemas::{
all_controller_schemas as all_tool_registry_controller_schemas,
all_registered_controllers as all_tool_registry_registered_controllers,
};
pub use types::{
ToolPolicyDiagnostics, ToolRegistryEntry, ToolRegistryHealth, ToolRegistryList,
ToolRegistryTransport,
CapabilityProviderDiagnostics, ToolPolicyDiagnostics, ToolRegistryEntry, ToolRegistryHealth,
ToolRegistryList, ToolRegistryTransport,
};
Loading
Loading