pub struct ServeArgs {
pub port: u16,
pub host: String,
pub cors: Option<String>,
pub token: Option<String>,
pub allow_admin: bool,
pub workdir_root: Option<PathBuf>,
pub tls_cert: Option<PathBuf>,
pub tls_key: Option<PathBuf>,
pub no_remote_yolo: bool,
}Expand description
Arguments for lev serve.
Fields§
§port: u16Port to listen on
host: StringHost to bind to
cors: Option<String>Allow browser requests from this origin (e.g. http://localhost:5173).
Defaults to none: the API is for programmatic clients, which are not
subject to CORS at all, so a browser-facing default of * gave nothing
to the normal case and widened the surface for the unusual one. A
dashboard served from another origin sets this explicitly.
* is still accepted and still means “any origin”. It is now a decision
someone typed rather than what you get by not thinking about it.
token: Option<String>API token clients must present (Authorization: Bearer <token>, or
?token= for WebSockets). Overrides the LEVIATH_API_TOKEN env var; the
server refuses to start if neither is set.
Prefer the environment variable: an argument is visible in ps to every
local user for the lifetime of the process.
allow_admin: boolEnable the MCP administration endpoints (POST/DELETE /api/mcp/servers).
Off by default, because they are remote code execution by
construction. Adding an MCP server writes a command and args into
~/.leviath/config.toml, and Leviath then spawns exactly that - so any
token holder could run an arbitrary process, persistently, for every
future run. The rest of the API can only run agents the user already
installed; this one adds new executables to the machine.
workdir_root: Option<PathBuf>Restrict agent working directories to this root.
Without it, POST /api/agents accepts any workdir - including / -
so a token holder can point a tool-executing agent at the whole
filesystem. Set this to the directory the API is meant to work in.
tls_cert: Option<PathBuf>PEM certificate chain to serve HTTPS with. Needs --tls-key too.
Bring your own; Leviath never generates one. Without HTTPS the browser
console cannot reach a lev serve that is not on loopback - the browser
blocks the request before sending it, so no server-side header and no
--cors value can help. A LAN address is blocked exactly like a public
one.
mkcert and tailscale cert both produce certificates that work here.
See the “reaching a Leviath on another machine” section of the docs.
tls_key: Option<PathBuf>PEM private key for --tls-cert. Needs --tls-cert too.
no_remote_yolo: boolRefuse "yolo": true and "allow": [...] on spawn requests, so an API
caller cannot waive approval prompts for an agent running on the host.
Both fields, because they are one lever: "allow": ["*"] reaches the
same wildcard override "yolo": true writes.
Trait Implementations§
Source§impl Args for ServeArgs
impl Args for ServeArgs
Source§fn augment_args<'b>(__clap_app: Command) -> Command
fn augment_args<'b>(__clap_app: Command) -> Command
Source§fn augment_args_for_update<'b>(__clap_app: Command) -> Command
fn augment_args_for_update<'b>(__clap_app: Command) -> Command
Command so it can instantiate self via
FromArgMatches::update_from_arg_matches_mut Read moreSource§impl FromArgMatches for ServeArgs
impl FromArgMatches for ServeArgs
Source§fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>
fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>
Source§fn from_arg_matches_mut(
__clap_arg_matches: &mut ArgMatches,
) -> Result<Self, Error>
fn from_arg_matches_mut( __clap_arg_matches: &mut ArgMatches, ) -> Result<Self, Error>
Source§fn update_from_arg_matches(
&mut self,
__clap_arg_matches: &ArgMatches,
) -> Result<(), Error>
fn update_from_arg_matches( &mut self, __clap_arg_matches: &ArgMatches, ) -> Result<(), Error>
ArgMatches to self.Source§fn update_from_arg_matches_mut(
&mut self,
__clap_arg_matches: &mut ArgMatches,
) -> Result<(), Error>
fn update_from_arg_matches_mut( &mut self, __clap_arg_matches: &mut ArgMatches, ) -> Result<(), Error>
ArgMatches to self.Auto Trait Implementations§
impl Freeze for ServeArgs
impl RefUnwindSafe for ServeArgs
impl Send for ServeArgs
impl Sync for ServeArgs
impl Unpin for ServeArgs
impl UnsafeUnpin for ServeArgs
impl UnwindSafe for ServeArgs
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> ConditionalSend for Twhere
T: Send,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more