Own how your organization uses AI.
systemprompt-core is the Rust library behind systemprompt.io — the narrow waist between your AI and everything it touches.
Website · Documentation · Guides · Live Demo · Template · Discord
AI governance infrastructure for agentic systems. Every tool call authenticated, authorised, rate-limited, logged, and costed. Self-hosted. Air-gap capable. Provider-agnostic. One language. One database (PostgreSQL). One binary (~50 MB). No microservices. No Kubernetes. No Redis. No Kafka.
AI infrastructure built for AI agents. A production-ready Rust library with auth, MCP servers, A2A orchestration, and playbooks for deterministic execution. 30 crates published on crates.io under systemprompt-* and the systemprompt facade. Compile-time extensions via the inventory crate. Zero-raw-String-ID policy. Compile-time verified SQL via sqlx::query! macros. Typed identifiers across every boundary.
Evaluating? Clone
systemprompt-templateand runjust build && just setup-local <key> && just start. 40+ scripted demos exercise every claim below against your own machine in three commands.Building on it? Add
systemprompt = "0.2.1"to yourCargo.tomland jump to Extensions.
Table of Contents
- Infrastructure
- Capabilities
- Integrations
- Architecture
- Extensions (technical)
- Typed identifiers
- Database & repositories
- Facade crate & feature flags
- Performance
- Quick Start
- License
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 |
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. Per-user key hierarchy encrypted with ChaCha20-Poly1305. 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 |
| Secret storage (ChaCha20-Poly1305) | crates/infra/security/src/ |
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 |
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
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.
[]
= { = "0.2.1", = ["full"] }
use *;
;
register_extension!;
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
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 DbPool;
use UserId;
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
= { = "0.2.1", = ["core", "database"] }
# Building a product binary
= { = "0.2.1", = ["full"] }
use *;
use 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.
Quick Start
Evaluation path — you get 40+ runnable demos:
Open 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:
[]
= { = "0.2.1", = ["full"] }
See Extensions for the compile-time plugin model.
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.
systemprompt.io · Documentation · Guides · Live Demo · Template · crates.io · docs.rs · Discord
Own how your organization uses AI. Every interaction governed and provable.