mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-18 04:47:08 +00:00
Some checks are pending
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
TypeScript / Typecheck (push) Waiting to run
TypeScript / Test (push) Waiting to run
TypeScript / Build (push) Waiting to run
## What
Adds the **mcp-servers HTTP API**: `GET/POST /api/v1/mcp-servers` and
`GET/PUT/DELETE /api/v1/mcp-servers/{id}` on top of the merged
`fabro-mcp-store` foundation and OpenAPI spec.
This includes the AppState wiring needed for the catalog to work end to
end: `McpServerStore` construction from `{active-config-dir}/mcps/`, an
`AppState` accessor, the `fabro-server` dependency, and route
registration for list/create/get/replace/delete handlers.
The API mirrors the automations concurrency pattern with ETags on
read/write responses and required `If-Match` headers for replace/delete.
## Resolved before merge
- **Credential-omitting read model:** read responses now return
`McpServerView` / `McpTransportView`, so stored env/header values are
not exposed by GET/list/create/replace responses. Responses include only
`env_keys` / `header_keys`; persisted values remain available to runtime
execution.
- **Manifest catalog references:** run manifest validation, graph
rendering, preflight, and run creation now resolve server-managed MCP
catalog references such as `[run.agent.mcps.<name>] id = "..."`.
- **Schema strictness:** unknown MCP transport fields are rejected,
aligning the reused Rust domain type with the OpenAPI
`additionalProperties: false` contract.
- **Create response headers:** the `POST /mcp-servers` 201 response now
documents its `ETag` header in OpenAPI.
## Follow-up intentionally left out
Credential-literal validation remains structural only: create/replace
currently accept literal env/header values and persist them for runtime
use. The warn-vs-hard-reject UX is a separate follow-up for the settings
UI; it is not a response-omission issue.
## Testing
Current PR checks are green:
- Rust: format, clippy, generated docs, Linux tests
- TypeScript: build, test, typecheck
Local checks run during the simplify/CI-fix pass:
- `cargo +nightly-2026-04-14 fmt --check --all`
- `cargo +nightly-2026-04-14 clippy --locked --workspace --all-targets
-- -D warnings`
- `cargo nextest run -p fabro-config run_agent_mcps`
- `cargo nextest run -p fabro-mcp-store`
- `cargo nextest run -p fabro-api --test mcp_server_round_trip`
- `cargo build -p fabro-api`
- `cargo nextest run -p fabro-server --features test-support
system_sandbox_provider`
- `cargo nextest run -p fabro-server --features test-support --test it
mcp_servers`
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
77 lines
4.6 KiB
Rust
77 lines
4.6 KiB
Rust
#[allow(
|
|
clippy::absolute_paths,
|
|
clippy::all,
|
|
clippy::derivable_impls,
|
|
clippy::disallowed_methods,
|
|
clippy::disallowed_types,
|
|
clippy::needless_lifetimes,
|
|
clippy::unwrap_used,
|
|
unreachable_pub,
|
|
unused_imports,
|
|
reason = "Generated OpenAPI client code intentionally preserves codegen output."
|
|
)]
|
|
mod generated {
|
|
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
|
|
}
|
|
pub mod types {
|
|
pub use fabro_automation::{
|
|
Automation, AutomationDraft as CreateAutomationRequest,
|
|
AutomationReplace as ReplaceAutomationRequest, AutomationTarget, AutomationTrigger,
|
|
};
|
|
pub use fabro_environment::Environment;
|
|
pub use fabro_model::{
|
|
CostSource, Model, ModelCosts, ModelFeatures, ModelLimits, ModelRef as BillingModelRef,
|
|
ModelTestMode, Provider, ReasoningEffort, ReasoningEffortFeature, Speed as BillingSpeed,
|
|
};
|
|
pub use fabro_types::run_event::AgentSessionActivatedProps;
|
|
pub use fabro_types::settings::run::McpHttpProtocol;
|
|
pub use fabro_types::settings::server::{
|
|
GithubIntegrationSettings, GithubIntegrationStrategy, IntegrationWebhooksSettings,
|
|
LogDestination, ObjectStoreSettings, ServerApiSettings, ServerArtifactsSettings,
|
|
ServerAuthGithubSettings, ServerAuthMethod, ServerAuthSettings, ServerIntegrationsSettings,
|
|
ServerListenSettings, ServerLoggingSettings, ServerSandboxProviderSettings,
|
|
ServerSandboxProvidersSettings, ServerSandboxSettings, ServerSchedulerSettings,
|
|
ServerSlateDbSettings, ServerStorageSettings, ServerWebSettings, SlackIntegrationSettings,
|
|
WebhookStrategy,
|
|
};
|
|
pub use fabro_types::settings::{McpTransport, ServerNamespace};
|
|
pub use fabro_types::status::{
|
|
BlockedReason, FailureReason, PendingReason, RunControlAction, RunStatus, SuccessReason,
|
|
};
|
|
pub use fabro_types::{
|
|
ActivatedSkill, AgentMcpToolSummary, AgentSkillActivationSource, AgentSkillSummary,
|
|
AgentToolCategory, AgentToolSource, AgentToolSummary, AgentToolsAvailableProps, AskFabro,
|
|
AuthMethod, AutomationRef, BilledTokenCounts, CommandTermination, Conclusion, ContentPart,
|
|
CreateVariableRequest, DiffStats, DiffSummary, DirtyStatus, EventEnvelope, ExecOutputTail,
|
|
FailureCategory, FailureDetail, FailureSignature, GitContext, IdpIdentity,
|
|
IntegrationConnectionKind, IntegrationConnectionState, IntegrationConnectionStatus,
|
|
IntegrationProvider, IntegrationStatus, InterviewOption, InterviewQuestionRecord,
|
|
McpServerDraft as CreateMcpServerRequest, McpServerProjection,
|
|
McpServerReplace as ReplaceMcpServerRequest, McpServerStatus, McpServerView as McpServer,
|
|
McpTransportView, Message, PairId, PairMessageId, PairMessageRecord, PairMessageRequest,
|
|
PairRecord, PairStartRequest, PairStatus, PairTarget, PairTranscriptEntry,
|
|
PairTranscriptResponse, PendingInterviewRecord, PermissionLevel, PreRunPushOutcome,
|
|
Principal, PullRequest, PullRequestDetails, PullRequestDetailsStatus,
|
|
PullRequestDetailsUnavailableReason, PullRequestLink, PullRequestMeta, PullRequestResponse,
|
|
QuestionType, RepositoryRef, Role, Run, RunApproval, RunApprovalState, RunClientProvenance,
|
|
RunEvent, RunEventDetailContentKind, RunEventDetailResponse, RunFailure,
|
|
RunPairStatusResponse, RunProjection, RunProvenance, RunRunnableSource, RunSandbox,
|
|
RunSandboxFailure, RunSandboxInstance, RunSandboxKind, RunSandboxPlan, RunSandboxRuntime,
|
|
RunServerProvenance, RunSize, SandboxDetails, SandboxInfo, SandboxListMeta,
|
|
SandboxListResponse, SandboxNetwork, SandboxNetworkPolicy, SandboxNetworkPolicyMode,
|
|
SandboxProviderKind, SandboxProviderLookupError, SandboxResources, SandboxService,
|
|
SandboxServiceListResponse, SandboxState, SandboxTimestamps, SecretMetadata, SecretType,
|
|
ServerSettings, SessionDetail, SessionId, SessionMessage, SessionRecord, SessionStatus,
|
|
SessionSummary, SessionTurn, SkillsProjection, StageCompletion, StageContextWindow,
|
|
StageContextWindowBreakdownItem, StageContextWindowCategory, StageContextWindowCountMethod,
|
|
StageContextWindowProjection, StageContextWindowStaleness,
|
|
StageContextWindowUnavailableReason, StageContextWindowWarning, StageHandler,
|
|
StageModelUsage, StageOutcome, StageProjection, StageState, SubAgentProjection,
|
|
SubAgentStatus, SystemActorKind, SystemIntegrationStatus, SystemIntegrationsResponse,
|
|
TodoListProjection, TurnId, UpdateVariableRequest, UserPrincipal, Variable,
|
|
VariableListResponse, WorkflowSettings,
|
|
};
|
|
|
|
pub use crate::generated::types::*;
|
|
}
|
|
pub use generated::Client as ApiClient;
|