Expand description
§Run your AI agent fleet on your own infrastructure, with your own choice of inference.
systemprompt-core is the Rust library that compiles into a single ~50 MB binary. Install it, point Claude for Work, Claude Code, any Anthropic-SDK client, or any MCP host at it, and every request lands on a host you operate — on your network, in your air-gap, under your audit table. Pick the upstream per model pattern: Anthropic, OpenAI, Gemini, Moonshot (Kimi), Qwen, MiniMax, or a custom provider you register yourself via the inventory crate. One YAML block swaps it.
Every tool call authenticated, scoped, secret-scanned, rate-limited, and audited. Compile-time plugin model, compile-time verified SQL, zero-raw-String IDs. BSL-1.1 source-available; Apache 2.0 after four years.
Website · Documentation · Guides · Live Demo · Template · Discord
Building with this? ⭐ Star the repo — helps other Rust developers find it.
- Embed it —
systemprompt = { version = "0.9.0", features = ["full"] }inCargo.toml, then jump to Extensions (technical) for the compile-time plugin model. - Evaluate it running — clone
systemprompt-templatefor a turnkey demo.just build && just setup-local <key> && just startruns 40+ scripted demos against the live binary.
What's new
- 0.5.0 —
AppPathssingleton removed (now threaded viaAppContext); shared/models stripped of all I/O (bootstrap and profile-catalog loading moved tosystemprompt-config); typedOauthError,FilesError,McpDomainError,AgentErrorenums at every domain boundary. SeeCHANGELOG.md. - 0.4.x — independent ed25519 manifest signing key, RFC 8785 (JCS) canonical JSON for signatures, distinct
JwtAudience::Bridge, tenant-scoped plugin file route, structuredSyncSummary/ValidationReportreturns. - 0.3.x — typed error enums via
thiserroracross the workspace,tracingin library code. - 0.2.x — workspace published to crates.io as 30
systemprompt-*crates.
The bin/bridge binary tracks an independent semver — see bin/bridge/README.md and bin/bridge/CHANGELOG.md.
§Capabilities
Every tool call governed. Synchronous evaluation before execution, not after. Four layers of enforcement in the request path: scope check → secret detection → blocklist → rate limit. Deny reasons are structured and auditable. Single-digit milliseconds overhead. No sidecar. No proxy. Compliance that survives an audit: SOC 2 Type II, ISO 27001, HIPAA, OWASP Top 10 for Agentic Applications.
Secrets never touch inference — the agent calls the tool, the MCP service injects the credential server-side, the LLM never sees it. Secrets-at-rest are protected via the customer’s envelope-encryption infrastructure (KMS / Vault / sops) — the binary sees plaintext only after the customer’s tooling opens the envelope, so the master key never enters the binary. Every tool call produces a five-point audit trace: Identity → Agent Context → Permissions → Tool Execution → Result. Everything linked by trace_id. Structured JSON events for Splunk, ELK, Datadog, Sumo Logic. Cost tracking in microdollars by model, agent, and department.
Where in the code
| Concern | File |
|---|---|
| Scope / RBAC middleware | crates/domain/mcp/src/middleware/rbac.rs |
| Secret detection / scanner | crates/infra/security/src/services/scanner.rs |
| Blocklist rules | crates/infra/security/src/services/ |
Rate limit middleware (tower_governor) | crates/infra/security/src/ |
| Audit queries | crates/infra/logging/src/trace/audit_queries.rs |
| Event broadcasters | crates/infra/events/src/services/broadcaster.rs |
| Secrets bootstrap (customer envelope encryption: KMS / Vault / sops) | crates/shared/models/src/secrets_bootstrap.rs |
Typed IDs (TraceId, ContextId, TaskId …) | crates/shared/identifiers/src/lib.rs |
MCP (crates/domain/mcp) is implemented natively — not proxied. Per-server OAuth2, scoped tool exposure, central registry with health monitoring, end-to-end access logs. Works with Claude Code, Claude Desktop, ChatGPT, Cursor, and any other MCP-compatible client.
| Concern | File |
|---|---|
| Orchestrator | crates/domain/mcp/src/services/orchestrator/mod.rs |
| Network / port management / proxy | crates/domain/mcp/src/services/network/mod.rs |
| RBAC middleware | crates/domain/mcp/src/middleware/rbac.rs |
{
"mcpServers": {
"my-server": {
"url": "https://my-tenant.systemprompt.io/api/v1/mcp/my-server/mcp",
"transport": "streamable-http"
}
}
}Agent-to-Agent (crates/domain/agent) ships a standalone A2A server with streaming, a JSON-RPC protocol model, and .well-known discovery endpoints.
| Concern | File |
|---|---|
| Standalone A2A server | crates/domain/agent/src/services/a2a_server/mod.rs |
| Streaming | crates/domain/agent/src/services/a2a_server/streaming/mod.rs |
Protocol models (Message, Task, TaskState) | crates/domain/agent/src/models/a2a/protocol/mod.rs |
Discovery API
| Endpoint | Description |
|---|---|
/.well-known/agent-card.json | Default agent card |
/.well-known/agent-cards | List all available agents |
/.well-known/agent-cards/{name} | Specific agent card |
/api/v1/agents/registry | Full agent registry with status |
/api/v1/mcp/registry | All MCP servers with endpoints |
- Governance Pipeline
- Secrets Management
- MCP Governance
- Analytics & Observability
- Closed-Loop Agents
- Compliance
§Quick Start
Evaluation path — you get 40+ runnable demos:
gh repo create my-eval --template systempromptio/systemprompt-template --clone
cd my-eval
just build
just setup-local <anthropic-or-openai-or-gemini-key>
just startOpen http://localhost:8080, point Claude Code / Claude Desktop at it, and walk through demo/. Prerequisites: Rust 1.75+, just, Docker, jq, yq, ports 8080 and 5432 free.
Library path — add the facade to your own Rust workspace:
[dependencies]
systemprompt = { version = "0.9.0", features = ["full"] }See Extensions (technical) for the compile-time plugin model.
Infrastructure
One binary. One database. Deploys anywhere. The same surface local and remote. Config-as-code: agents, MCP servers, skills, AI providers, content, scheduler jobs, and web theme all live as YAML or Markdown under services/. Built on open standards: MCP (Model Context Protocol), A2A (Agent-to-Agent), OAuth2/OIDC with PKCE, WebAuthn.
Where in the code
| Concern | File |
|---|---|
| Bootstrap sequence | ProfileBootstrap → SecretsBootstrap → CredentialsBootstrap → Config → AppContext |
| AppContext wiring | crates/app/runtime/src/context.rs · builder.rs |
Provider traits (LlmProvider, ToolProvider, …) | crates/shared/provider-contracts/src/lib.rs |
| CLI entry point (8 domains) | crates/entry/cli/src/commands/ |
One binary, eight domains. Every command is discoverable — systemprompt <domain> --help works everywhere.
| Domain | Source | Purpose |
|---|---|---|
core | crates/entry/cli/src/commands/core/ | Skills, content, files, contexts, plugins, hooks, artifacts |
infra | crates/entry/cli/src/commands/infrastructure/ | Services, database, jobs, logs |
admin | crates/entry/cli/src/commands/admin/ | Users, agents, config, setup, session, rate limits |
cloud | crates/entry/cli/src/commands/cloud/ | Auth, deploy, sync, secrets, tenant, domain |
analytics | crates/entry/cli/src/commands/analytics/ | Overview, conversations, agents, tools, requests, sessions, content, traffic, costs |
web | crates/entry/cli/src/commands/web/ | Content types, templates, assets, sitemap, validate |
plugins | crates/entry/cli/src/commands/plugins/ | Extensions, MCP servers, capabilities |
build | crates/entry/cli/src/commands/build/ | Build core workspace and MCP extensions |
Integrations
Provider-agnostic. Protocol-native. Fully extensible. Provider-agnostic by trait, not by adapter — swap Anthropic / OpenAI / Gemini at the profile level.
Architecture
A 30-crate Rust workspace that compiles into a single ~50 MB binary. Dependencies flow downward only — no circular references.
┌─────────────────────────────────────────────────────────────────────┐
│ ENTRY api · cli │
├─────────────────────────────────────────────────────────────────────┤
│ APP runtime · scheduler · generator · sync │
├─────────────────────────────────────────────────────────────────────┤
│ DOMAIN agent · ai · analytics · content · files · mcp · │
│ oauth · templates · users │
├─────────────────────────────────────────────────────────────────────┤
│ INFRA cloud · config · database · events · loader · │
│ logging · security │
├─────────────────────────────────────────────────────────────────────┤
│ SHARED identifiers · provider-contracts · traits · │
│ extension · models · client · template-provider │
└─────────────────────────────────────────────────────────────────────┘All 30 crates publish on crates.io at matching workspace versions. Domain crates communicate via traits and the event bus, not direct dependencies. Database-touching crates ship a per-crate .sqlx/ query cache (committed) so downstream consumers compile offline.
Extensions (technical)
Extensions are discovered at compile time via the inventory crate — no runtime plugin loading, no dlopen. Your code compiles straight into your binary. Typed traits cover the full surface:
| Trait | File | Purpose |
|---|---|---|
Extension | crates/shared/extension/src/traits.rs | Identity, version, dependency metadata |
SchemaExtensionTyped | crates/shared/extension/src/typed/schema.rs | DDL + migrations via include_str!() |
ApiExtensionTyped · ApiExtensionTypedDyn | crates/shared/extension/src/typed/api.rs | Axum route handlers |
JobExtensionTyped | crates/shared/extension/src/typed/job.rs | Scheduled and background jobs |
ProviderExtensionTyped | crates/shared/extension/src/typed/provider.rs | Custom LLM / tool / data providers |
ConfigExtensionTyped | crates/shared/extension/src/typed/config.rs | Startup config validation |
Registration is a single macro — register_extension! lives in crates/shared/extension/src/traits.rs and wraps inventory::submit!. Discovery goes through ExtensionBuilder<R> and TypedExtensionRegistry.
[dependencies]
systemprompt = { version = "0.9.0", features = ["full"] }use systemprompt::extension::prelude::*;
struct MyExtension;
impl Extension for MyExtension {
fn metadata(&self) -> ExtensionMetadata {
ExtensionMetadata::new("my-extension", env!("CARGO_PKG_VERSION"))
}
fn schemas(&self) -> Vec<SchemaDefinition> {
vec![SchemaDefinition::new(
"my_extension",
include_str!("../schema/001_init.sql"),
)]
}
fn router(&self) -> Option<ExtensionRouter> { None }
}
register_extension!(MyExtension);Typed identifiers
Zero raw-String IDs. Every identifier that crosses a boundary is a newtype in crates/shared/identifiers — the compiler prevents passing a UserId where an AgentId is expected.
UserId · SessionId · TraceId · ContextId · TaskId · AgentId · TenantId · McpServerId · McpExecutionId · AiRequestId · PluginId · SkillId · ArtifactId · FileId · ContentId · MessageId · TokenId · ClientId · RoleId · ProfileName · Email · ValidatedUrl · ValidatedFilePath · PolicyVersion
Database & repositories
Services call repositories, repositories issue SQL. All queries go through compile-time verified macros — sqlx::query!(), sqlx::query_as!(), sqlx::query_scalar!(). No unverified sqlx::query().
DDL lives in {crate}/schema/*.sql and is embedded with include_str!() from extension.rs. The generic entity/repository traits live in crates/infra/database/src/repository/entity.rs (Entity, GenericRepository<E>).
use systemprompt_database::DbPool;
use systemprompt_identifiers::UserId;
pub struct UserRepository { pool: DbPool }
impl UserRepository {
pub async fn find_by_id(&self, id: &UserId) -> Result<Option<User>> {
sqlx::query_as!(User, "SELECT * FROM users WHERE id = $1", id.as_str())
.fetch_optional(self.pool.as_ref())
.await
.map_err(Into::into)
}
}Facade crate & feature flags
Pull in only what you need through the systemprompt facade.
| Feature | Includes |
|---|---|
core (default) | traits · models · identifiers · extension · template-provider |
database | SQLx-backed DbPool |
api | HTTP server, runtime, Axum (requires core + database) |
cli | CLI entry point |
runtime | Extension runtime builder (requires cli) |
mcp | rmcp macros |
sync | Cloud synchronization |
cloud | Cloud API client, credentials, OAuth |
test-utils | Credential fixtures (requires cloud) |
full | Everything: API + MCP + sync + cloud + CLI + all domain crates |
# Embedded library usage
systemprompt = { version = "0.9.0", features = ["core", "database"] }
# Building a product binary
systemprompt = { version = "0.9.0", features = ["full"] }use systemprompt::prelude::*;
use systemprompt::database::DbPool;Performance
Sub-5 ms governance overhead, benchmarked. Each request performs JWT validation, scope resolution, three rule evaluations, and an async database write.
- p50 < 5 ms
- p99 < 12 ms
- 200 concurrent governance requests
- Zero GC pauses — hundreds of concurrent developers on a single instance
Numbers measured on the author’s laptop. Reproduce with ./demo/performance/02-benchmark.sh in the template. Full results and a live load test: systemprompt.io/features/demo.
§License
BSL-1.1 (Business Source License). Source-available for evaluation, testing, and non-production use. Production use requires a commercial license. Each version converts to Apache 2.0 four years after publication.
See LICENSE for the full terms. Licensing enquiries: ed@systemprompt.io.
§Security
Vulnerability disclosure, triage SLAs, and supply-chain integrity are documented in SECURITY.md. Report vulnerabilities to ed@systemprompt.io — not via public issues.
Release binaries are built in GitHub-hosted CI and signed with Sigstore cosign keyless. A CycloneDX SBOM is attached to every release.
§Enterprise Documentation
The documentation/ directory is the public evaluation pack for prospective customers, security reviewers, and RFI / procurement teams.
- Compliance Control Matrix — HIPAA, SOC 2, ISO 27001 mappings
- Threat Model — STRIDE analysis with code paths
- Deployment Reference Architecture — HA, backup, DR, key rotation, monitoring, air-gap
- Stability Contract — what is stable vs. what tracks upstream
- Compatibility Matrix — providers, protocols, runtime versions
RFI and licensing contact: ed@systemprompt.io.
systemprompt.io · Documentation · Guides · Live Demo · Template · crates.io · docs.rs · Discord
Own how your organization uses AI. Every interaction governed and provable.
| Feature | Pulls in | Use case |
|---|---|---|
core (default) | traits, models, identifiers, extension, template-provider | Author extensions, share types, no I/O. |
database | systemprompt-database, sqlx | SQLx-backed DbPool and repository helpers. |
config | systemprompt-config | Profile, secrets, and credential bootstrap loaders. |
mcp | rmcp | Implement Model Context Protocol servers. |
api | systemprompt-api, systemprompt-runtime, axum (implies core + database) | HTTP server, AppContext, Axum router. |
sync | systemprompt-sync | Cloud synchronisation primitives. |
cloud | systemprompt-cloud | Cloud API client, credentials bootstrap, OAuth. |
logging | systemprompt-logging | Tracing setup with the workspace’s layer stack. |
loader | systemprompt-loader | Filesystem and module discovery. |
events | systemprompt-events | In-process event bus and SSE plumbing. |
client | systemprompt-client | HTTP API client used by the CLI. |
security | systemprompt-security | JWT, scope/RBAC, secret scanning, rate limit. |
cli | systemprompt-cli | The systemprompt CLI as a library entry point. |
runtime | cli + extension injection | RuntimeBuilder for embedding with custom extensions. |
test-utils | cloud plus credential fixtures | Test scaffolding; not for production. |
full | All of the above plus all domain crates (agent, ai, mcp, oauth, users, content, analytics, scheduler, generator, files) | Building a product binary. |
systemprompt = { version = "0.5", features = ["full"] }Re-exports§
pub use runtime::RuntimeBuilder;runtimepub use runtime::RuntimeError;runtimepub use crate::prelude::*;
Modules§
- agent
full - Agent-to-Agent (A2A) protocol surface from
systemprompt-agent— message types, task lifecycle, streaming server, agent registry. - ai
full - LLM integration surface from
systemprompt-ai— provider selection, request/response types, cost accounting. - analytics
full - Analytics domain from
systemprompt-analytics— request, conversation, agent, tool, cost metrics. - api
api - HTTP server entry: Axum router, middleware stack, listener bootstrap.
- cli
cli - CLI entry surface:
run,CliConfig,OutputFormat,ColorMode,VerbosityLevel. - client
client - HTTP API client used by the CLI and external tooling to drive a running instance.
- cloud
cloud - Cloud API client from
systemprompt-cloud— credentials bootstrap, tenant management, deployment. - config
config - Profile / secrets / credentials configuration loaders. Drives the
ProfileBootstrap → SecretsBootstrap → CredentialsBootstrap → Configsequence. - content
full - Content management domain from
systemprompt-content— pages, articles, markdown ingestion. - credentials
cloud - Cloud credentials bootstrap from
systemprompt-cloud— loads OAuth client credentials and tenant identity at startup. - database
database - SQLx-backed database abstraction:
DbPool,DatabaseProvider, repositories, introspection. - events
events - In-process event bus and SSE broadcasting from
systemprompt-events. - extension
core - Compile-time extension framework: the
Extensiontrait, typed variants,register_extension!macro, and registry. - files
full - File-storage domain from
systemprompt-files. - generator
full - Static-site generator from
systemprompt-generator— Tera-based renderer driving thewebCLI domain. - identifiers
core - Typed identifiers from
systemprompt-identifiers(UserId,AgentId,TaskId,TraceId, …). - loader
loader - Filesystem and module discovery for services, plugins, and config files.
- logging
logging - Tracing/logging setup helpers (startup-mode gating, layered subscribers).
- marketplace
full - Marketplace filtering domain from
systemprompt-marketplace— theMarketplaceFiltertrait that gates per-user visibility of plugins, skills, agents, and managed MCP servers in the bridge manifest. - mcp
full - Model Context Protocol implementation from
systemprompt-mcp— server orchestrator, network/proxy layer, RBAC middleware. - models
core - I/O-free data models from
systemprompt-models— config structs, profile types, domain DTOs. - oauth
full - OAuth2 / OIDC / WebAuthn flows from
systemprompt-oauth. - prelude
- Curated re-exports for ergonomic
use systemprompt::prelude::*. Seepreludefor the full list. Curated re-exports foruse systemprompt::prelude::*. - profile
core - Profile types — the on-disk profile schema (
Profile,CloudConfig,ProfileStyle,CloudValidationMode) plus theProfileBootstraploader when theconfigfeature is enabled. - runtime
runtime RuntimeBuilderfor embedding the platform with compile-time injected extensions and a custom web-asset strategy. Embedding helper for thesystempromptCLI.- scheduler
full - Background-job scheduler from
systemprompt-scheduler. - security
security - Security primitives: JWT verification, scope/RBAC, secret scanning, rate-limit middleware.
- sync
sync - Cloud synchronisation primitives from
systemprompt-sync. - system
api - Application runtime /
AppContextwiring. Construct viaAppContextBuilderfrom the prelude. - template_
provider core - Template provider trait surface for custom rendering backends (Tera, Handlebars, MJML, …).
- traits
core - Core trait surface from
systemprompt-traits. - users
full - User management domain from
systemprompt-users— accounts, roles, scopes.
Structs§
- Credentials
Bootstrap cloud - Top-level re-exports of
CredentialsBootstrapand its error.
Enums§
- Credentials
Bootstrap Error cloud - Top-level re-exports of
CredentialsBootstrapand its error. - WebAssets
runtime WebAssetsstrategy re-export — controls how the runtime serves the static web bundle (in-binary, on-disk, or disabled). Web-asset serving strategy re-exported fromsystemprompt-extension.