npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dinglebear/soma

v0.10.0

Published

RMCP runtime for provider-backed agents with CLI, REST, HTTP MCP, plugins, and scaffold support.

Readme

Soma

RMCP runtime for provider-backed agents with CLI, REST, HTTP MCP, plugins, and scaffold support.

Docs API docs — rustdoc for every workspace crate plus the Redoc-rendered OpenAPI reference, deployed to GitHub Pages from main.

Soma is a batteries-included server runtime and shipping binary for bringing new agent capabilities online with as little custom Rust as possible. It locks in the production patterns that every server in the family keeps rediscovering: one compact MCP tool, stdio and Streamable HTTP transports, CLI parity, direct REST routes, auth/OAuth, observability, plugin packaging, web fallback, Docker/runtime samples, generated contracts, and release automation.

The repository can still scaffold a renamed project, but Soma is now a shipped runtime first. The default product path is to run soma in an explicit mode, drop provider files into providers/ (or point SOMA_PROVIDER_DIR elsewhere), and let the provider registry project those capabilities across MCP, CLI, REST, OpenAPI, Palette summaries, generated docs, and plugin metadata. Provider manifests also carry MCP-native prompt, resource, task, and elicitation metadata for the registry contract. Scaffolding is the path for creating a new distributable repo with the same locked-in runtime.

30-second path: install the soma binary -> soma status -> npx -y @dinglebear/soma mcp from an MCP client -> call the soma MCP tool through tools/call with {"action":"status"}.

Status: production RMCP runtime. Write-capable provider actions are allowed only when the provider declares them and destructive actions are gated.

Not for: an unauthenticated public gateway, a replacement for upstream service authorization, arbitrary untrusted code execution, or a multi-tenant security boundary by itself.

Contents

Naming

Soma is the runtime product first and the template/export source second. Generated projects replace these names during scaffold post-processing, but the shipped soma command is the source of truth for product behavior.

| Surface | Soma value | Generated-project pattern | |---|---|---| | Repository | dinglebear-ai/soma (formerly rmcp-template, then rtemplate-mcp — both still redirect) | dinglebear-ai/r<service>, or the bare product name; older servers still carry <service>-rmcp names behind redirects | | Rust crate/package | soma | service-specific crate names | | Canonical binary | soma | usually r<service> or the product name | | npm package | @dinglebear/soma | <service>-rmcp | | MCP tool | soma | usually <service> | | Env prefix | SOMA_* | generated service prefix |

Capabilities And Boundaries

| Path | Use when | You author | Runtime supplies | |---|---|---|---| | Drop-in provider | You can describe a capability as a manifest, script, WASM module, OpenAPI operation, or upstream MCP call. | Files under providers/ with tools, prompts, resources, env needs, capability grants, and surface overlays. | MCP tool dispatch, dynamic CLI commands, direct REST routes, schema validation, auth policy, refresh, OpenAPI/Palette summaries, generated docs, and plugin metadata. | | Static Rust provider | The capability needs native Rust, tight integration, or reusable crates. | A Rust provider/action registered with the provider registry. | The same MCP/CLI/REST/docs/plugin projection without per-surface rewrites. | | Scaffolded product | You need a renamed repository, package identity, ports, plugins, Docker labels, and release metadata. | A scaffold_intent payload or cargo xtask scaffold options. | A compiling product repo, scaffold report, cargo-generate post-processing, and scaffold/export verification checks. | | Custom profile | You need a narrower binary or deployment shape. | Cargo feature selection. | The same runtime crates behind local-adapter, server, and full profiles. |

Batteries Included

  • One compact MCP service tool (soma) with action dispatch, so agent tool lists stay small even as provider catalogs grow.
  • One canonical binary: soma with explicit serve, mcp, and CLI modes for REST API, Streamable HTTP MCP, stdio MCP, optional web UI, and local actions.
  • Dynamic provider loading from .json, .ts, .py, .wasm, and .md files, plus native Rust providers and upstream MCP/OpenAPI provider kinds. A structured providers/{tools,prompts,resources}/ layout is supported alongside root-level files, including path-derived MCP resources (static files and dynamic .ts readers) with a path-traversal trust boundary.
  • Provider manifest contracts for tools, prompts, resources, tasks, elicitation forms, env requirements, capability grants, and surface overlays.
  • Shared validation, destructive-action confirmation, auth/scope enforcement, response limits, redaction, logging, metrics, generated OpenAPI, generated provider surface docs, plugin manifests, setup, doctor, and release tooling.

Soma owns the runtime projection, validation, auth policy, packaging, generated metadata, and scaffold automation. Provider code owns service-specific behavior and credentials. Upstream services own their own authorization and data model. Soma deliberately refuses to make credentials part of tool-call input and does not turn provider manifests into an unrestricted remote execution boundary.

Install

Use the npm launcher when an MCP client expects an npx command. During postinstall, the package downloads the matching Linux/x64 or Windows/x64 release archive, verifies its SHA256SUMS entry and GitHub build attestation, and installs the native binary inside the package. GitHub CLI 2.68 or newer is required for provenance verification.

npx -y @dinglebear/soma mcp

Use Cargo while developing the repo:

cargo run --bin soma -- mcp
cargo run --bin soma -- serve

Release builds publish GitHub Release binaries, Docker/OCI metadata, the @dinglebear/soma npm launcher, MCP registry metadata, and plugin package files from the same release component.

Product Profiles

Choose the amount of surface area you want without changing the provider authoring model.

| Target | Best fit | Default profile | Includes | |---|---|---|---| | Local agent adapter | Thin wrapper over dropped providers or an upstream API | local-adapter | CLI + stdio MCP in one local binary. No REST/Web mirror by default. | | Shared API/MCP server | Service used by multiple clients or a gateway | server | CLI + REST API + Streamable HTTP MCP + stdio MCP + health/status routes + auth-capable runtime. | | Full application platform | App owns state, jobs, dashboards, workflows, or human UI | full | server plus embedded web UI, OAuth, observability, and plugin support. | | CLI-only or custom local tool | Scripts, operator utilities, one-machine tools | Custom feature set, usually starting from cli | CLI parser and shared service layer. The stock packaged local binary uses local-adapter, so CLI-only products may prune MCP or adjust binary feature gates. |

Lower-level Cargo features are available when you need a custom shape:

| Feature | Purpose | |---|---| | cli | CLI shim and command parsing. | | mcp | MCP tool, schema, resource, prompt, and scope layers. | | mcp-stdio | Local stdio MCP transport. | | api | REST handlers and OpenAPI-backed business routes. | | auth | Shared auth policy and bearer-token enforcement. | | oauth | Google, Authelia, and GitHub OAuth/OIDC plus JWT issuance on top of auth. | | mcp-http | Streamable HTTP MCP mounted in Axum. | | web | Embedded static web UI fallback. | | observability | Metrics/tracing hooks. | | plugin | Plugin setup/support helpers. | | local-adapter | Lean local binary: cli + mcp-stdio. | | server | Deployable HTTP runtime profile: cli + api + HTTP MCP + stdio MCP. | | full | Complete platform profile: local adapter, server, web, OAuth, observability, and plugin support. |

Quickstart

Run the product as-is:

git clone https://github.com/dinglebear-ai/soma
cd soma

# Full platform mode: REST API + HTTP MCP + web fallback on :40060
cargo run --bin soma -- serve

# Local binary: stdio MCP
cargo run --bin soma -- mcp

# Local binary: CLI
cargo run --bin soma -- greet --name Alice

Useful smoke checks:

curl http://localhost:40060/health
cargo run --bin soma -- status
cargo run --bin soma -- doctor

Call the MCP endpoint directly:

curl -s -X POST http://localhost:40060/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"soma","arguments":{"action":"greet","name":"Alice"}}}'

Drop In A Provider

The fastest path for a new server is provider-first. Add a provider manifest or module to providers/, then run the same binary. Use SOMA_PROVIDER_DIR when the provider catalog should live outside the working directory.

mkdir -p providers
cat > providers/hello-local.json <<'JSON'
{
  "schema_version": 1,
  "provider": {
    "name": "hello-local",
    "kind": "static-rust",
    "title": "Hello Local"
  },
  "tools": [
    {
      "name": "hello_local",
      "description": "Return a deterministic hello payload from a dropped provider.",
      "input_schema": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": { "type": "string" }
        }
      },
      "cli": {
        "enabled": true,
        "command": "hello-local"
      },
      "rest": {
        "enabled": true,
        "method": "POST",
        "path": "/v1/hello-local"
      },
      "meta": {
        "result": {
          "message": "hello from a dropped provider"
        }
      }
    }
  ]
}
JSON

Call it through the dynamic CLI surface:

cargo run --bin soma -- hello-local --name Alice

Run the server and call the same provider over REST and MCP:

cargo run --bin soma -- serve

curl -s -X POST http://localhost:40060/v1/hello-local \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice"}'

curl -s -X POST http://localhost:40060/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"soma","arguments":{"action":"hello_local","name":"Alice"}}}'

Plain Python functions can also be dropped directly into providers/:

PROVIDER = {"name": "math-tools", "kind": "python"}

def add(a: int, b: int) -> int:
    """Add two integers."""
    return a + b

When TOOLS is absent, public functions defined in the module become tools. Sync and async functions are supported, and common Python type annotations are converted into input schemas.

Python provider files are trusted code. Soma imports them during provider catalog refresh to discover tools, then executes tool calls in a sidecar with a cleared environment plus only declared provider/tool env values. Catalog import does not receive provider env; read secrets inside tool functions, not at module import time.

Provider manifests can declare:

  • tools/actions exposed through MCP by default and through CLI/REST when their overlays opt in
  • MCP-native prompt, resource, task, and elicitation metadata for the provider registry contract
  • required environment variables and redaction rules
  • filesystem, network, browser, terminal, GitHub, and env capability grants
  • limits, destructive-action metadata, examples, generated docs, plugin, and UI metadata

Supported provider kinds are static-rust, openapi, ai-sdk, wasm, mcp, python, langchain, and llamaindex. See docs/specs/dynamic-provider-runtime.md, docs/contracts/provider-manifest.schema.json, and docs/generated/provider-surfaces.md.

Scaffold A New Project

Use cargo xtask scaffold when the provider-first path needs to become a new repository with its own crate names, binary names, ports, plugin package, Docker metadata, release metadata, and docs. It can plan without touching files, generate with cargo-generate plus the Rust post-processor, write docs/scaffold-report.md, and verify the generated export shape.

Plan from a short service name:

cargo xtask scaffold --name myservice --category upstream-client --port auto --plan

Plan from MCP scaffold_intent JSON:

cargo xtask scaffold --intent scaffold-intent.json --plan

Generate into an output parent directory:

cargo xtask scaffold --intent scaffold-intent.json --apply ../generated

Verify an existing generated project:

cargo xtask scaffold --verify ../generated/myservice-mcp

Print a path-aware follow-up plan for adapting the generated stub:

cargo xtask scaffold --adapt-plan ../generated/myservice-mcp

Materialize starter artifacts from an action manifest:

cargo xtask scaffold \
  --write-action-starters ../generated/myservice-mcp \
  --actions actions.json

Add starter action snippets:

cargo xtask scaffold \
  --intent scaffold-intent.json \
  --actions actions.json \
  --plan

Example action manifest:

{
  "actions": [
    {
      "name": "list_things",
      "description": "List visible things.",
      "scope": "read",
      "params": [
        { "name": "kind", "type": "string", "required": false }
      ]
    }
  ]
}

Use:

  • --category upstream-client for a lean local adapter around an existing API.
  • --category application-platform for API + CLI + MCP + web defaults.
  • --no-cargo-check only when you need fast static verification while iterating.

See docs/SCAFFOLD.md, docs/CARGO_GENERATE.md, and docs/contracts/scaffold-intent.schema.json for the full scaffold contract.

Architecture

The runtime keeps product behavior behind the provider registry. Every external surface is a thin parser/formatter around the same provider snapshot and service runtime, so dropping a provider does not require hand-editing MCP, CLI, REST, OpenAPI, plugin, or docs code.

ProviderRegistry
  crates/soma/application/src/provider_registry.rs
  Validates provider manifests, computes snapshots/fingerprints, indexes tools,
  prompts, resources, CLI commands, REST routes, and MCP primitives.

Provider sources
  crates/soma/application/src/providers/
  Static Rust, file-backed JSON manifests, TypeScript AI SDK sidecars, Python
  LangChain/LlamaIndex sidecars, WASM, OpenAPI-backed providers, and upstream
  MCP providers.

SomaService
  crates/soma/application/src/service.rs
  Built-in product/service logic used by the static Rust provider.

Transport shims
  crates/soma/cli/src/lib.rs        CLI parser and output formatting.
  crates/soma/mcp/src/tools.rs      MCP JSON args to service calls.
  crates/soma/api/src/api.rs        REST extractors to service calls.
  apps/soma/src/http.rs             Axum router, auth, MCP, API, web fallback.

Built-in action metadata
  crates/soma/domain/src/actions.rs
  Native action metadata, validation, cached catalog/help, and native dispatch.

The thin-shim rule is strict:

  1. Parse input at the surface.
  2. Call the provider registry or service runtime.
  3. Return or print the result.

Do not put business rules in CLI, MCP, REST handlers, or the binary entrypoint (apps/soma/src/bin/soma.rs / apps/soma/src/bootstrap.rs).

Runtime Surfaces

The canonical binary can run the whole app from one executable:

soma serve       # HTTP server: REST API + Streamable HTTP MCP + web fallback
soma mcp         # stdio MCP transport
soma status      # CLI command through the same binary

Local adapter mode is optimized for plugin/local use:

soma mcp                # stdio MCP transport
soma greet --name Alice # CLI command
soma doctor             # operator pre-flight checks
soma watch              # poll /health and emit state changes
soma setup check        # plugin/appdata setup checks

Every explicit runtime mode loads the provider registry. File providers default to ./providers and can be moved with SOMA_PROVIDER_DIR. CLI startup, MCP dispatch, and dynamic REST routes refresh file providers before execution, then enforce the active provider snapshot's schema, surface, scope, capability, destructive-action, and response-limit rules.

HTTP routes in the server profile:

| Route | Purpose | |---|---| | /mcp | Streamable HTTP MCP transport. | | /health | Unauthenticated liveness. | | /readyz | Readiness check. | | /status | Public redacted runtime status. | | /openapi.json | Generated REST OpenAPI schema. | | /metrics | Prometheus metrics when built with observability. | | /v1/capabilities | REST route inventory. | | /v1/greet, /v1/echo, /v1/status, /v1/help | Direct REST business routes. | | /v1/tools/{action} | Generic REST execution route for dropped provider tools. | | /v1/{provider-route} | Optional provider-declared REST route when a tool supplies a custom REST overlay. | | /mcp/.well-known/* | OAuth metadata when OAuth is enabled. | | /* | Embedded web UI fallback when built with web. |

REST is direct-route-only: there is no /v1/soma action envelope. MCP remains one soma tool with an action argument.

MCP Tool Reference

The runtime exposes one compact MCP tool, soma, with an action argument. Built-in actions and dropped provider tools share that same dispatch path. This keeps MCP discovery small while allowing the provider catalog to grow behind the single tool.

| Action | Scope | Cost | Transport | REST route | CLI | Parameters | Description | |---|---|---|---|---|---|---|---| | greet | soma:read | cheap | MCP + CLI + REST | POST /v1/greet | soma greet [--name NAME] | name (optional string) | Return a greeting. | | echo | soma:read | cheap | MCP + CLI + REST | POST /v1/echo | soma echo --message MSG | message (required string) | Echo a message back unchanged. | | status | soma:read | cheap | MCP + CLI + REST | GET /v1/status | soma status | none | Return server status and configuration info. | | python_environment_status | soma:write | cheap | MCP + CLI + REST | GET /v1/python/environments | soma python_environment_status | none | Inspect immutable Python environment cache state without executing provider code. | | python_environment_prune_plan | soma:write | moderate | MCP + CLI + REST | POST /v1/python/environments/prune-plan | soma python_environment_prune_plan --json '{\ | stale_before_unix_seconds (required integer), max_entries (optional integer) | Plan a bounded prune of stale non-ready Python environment cache entries. | | python_environment_prune | soma:write | write | MCP + CLI + REST | POST /v1/python/environments/prune | soma python_environment_prune --json '{\ | stale_before_unix_seconds (required integer), max_entries (optional integer), confirm (required boolean) | Apply a bounded prune of stale non-ready Python environment cache entries. | | python_environment_repair | soma:write | write | MCP + CLI + REST | POST /v1/python/environments/repair | soma python_environment_repair --json '{\ | provider_path (required string), confirm (required boolean) | Repair the immutable environment for one managed Python provider. | | python_environment_update | soma:write | write | MCP + CLI + REST | POST /v1/python/environments/update | soma python_environment_update --json '{\ | provider_path (required string), confirm (required boolean) | Resolve, prepare, validate, and atomically activate an immutable update for one managed Python provider. | | python_worker_status | soma:write | cheap | MCP + CLI + REST | GET /v1/python/workers | soma python_worker_status | none | Inspect persistent Python worker health, quarantine, restart counts, and bounded redacted logs. | | python_worker_cancel | soma:write | write | MCP + CLI + REST | POST /v1/python/workers/cancel | soma python_worker_cancel --json '{\ | provider (required string), confirm (required boolean) | Cancel one active persistent Python invocation by terminating its process tree. | | python_worker_reset | soma:write | write | MCP + CLI + REST | POST /v1/python/workers/reset | soma python_worker_reset --json '{\ | provider (required string), confirm (required boolean) | Clear one persistent Python worker crash-loop quarantine. | | python_generation_status | soma:read | cheap | MCP + CLI + REST | GET /v1/python/generations | soma python_generation_status | none | Inspect the active Python provider generation and bounded rollback history. | | python_generation_rollback | soma:write | write | MCP + CLI + REST | POST /v1/python/generations/rollback | soma python_generation_rollback --json '{\ | generation_id (required integer), confirm (required boolean) | Atomically reactivate a retained Python provider generation. | | python_graduation_status | soma:read | cheap | MCP + CLI + REST | POST /v1/python/graduation/status | soma python_graduation_status --json '{\ | workspace (required string) | Inspect digest-bound Python graduation, conformance, activation, and rollback state. | | python_graduation_apply | soma:write | write | MCP + CLI + REST | POST /v1/python/graduation/apply | soma python_graduation_apply --json '{\ | operation (required string), workspace (required string), source (optional string), component (optional string), fixtures (optional string), wheelhouse (optional string), confirm (required boolean) | Scaffold, componentize, build, verify, compare, activate, or roll back a Python graduation workspace. | | elicit_name | soma:read | cheap | MCP-only | - | _MCP-only_ | none | Ask the MCP client to collect a name, then return a personalised greeting. | | scaffold_intent | soma:read | moderate | MCP-only | - | _MCP-only_ | none | Collect scaffold setup intent through MCP elicitation and return JSON for the scaffold-project skill. | | help | public | cheap | MCP + CLI + REST | GET /v1/help | soma help | none | Show the action reference. |

Python provider lifecycle administration is exposed through the same compact tool with these explicit actions:

  • environment cache: python_environment_status, python_environment_prune_plan, python_environment_prune, python_environment_repair, and python_environment_update;
  • persistent workers: python_worker_status, python_worker_cancel, and python_worker_reset;
  • provider generations: python_generation_status and python_generation_rollback;
  • Python-to-component graduation: python_graduation_status and confirmed python_graduation_apply.

Built-in business actions keep MCP + CLI + REST parity unless there is a protocol reason they cannot. elicit_name and scaffold_intent are MCP-only because they rely on MCP elicitation. serve, mcp, doctor, watch, setup, and package are CLI operator commands, not business actions.

Dropped provider tools are MCP-enabled by default and REST-executable through POST /v1/tools/{action} unless the tool explicitly sets rest.enabled=false. A rest overlay can add a custom route, method, and OpenAPI metadata; the generic route remains the web/adapter-safe execution shape. CLI exposure is opt-in through each tool's cli overlay. Provider prompts, resources, tasks, and elicitation forms are part of the provider manifest contract and registry index; they are not mirrored to CLI or REST by default.

CLI Reference

The soma binary exposes operator commands and provider-backed actions through the same registry snapshot used by MCP:

soma greet --name Alice
soma echo --message hello
soma status
soma help
soma providers validate
soma providers inspect
soma providers test status
soma providers list --dir ./examples/providers
soma providers lint --dir ./examples/providers
soma providers status --dir ./examples/providers
soma doctor
soma setup check
soma package generate --check

Provider tools opt in to CLI exposure with a cli overlay. Dynamic CLI flags are derived from the provider input schema, so the generated provider catalogs remain the source of truth for current action shapes.

Safety And Trust Model

MCP callers never provide API keys, OAuth secrets, bearer tokens, passwords, or other credentials in tool arguments. Credentials live in environment variables, config files, appdata, or the upstream provider runtime.

Provider manifests are validated before dispatch. The registry enforces surface opt-ins, JSON Schema input validation, auth scope, declared host capabilities, destructive-action confirmation, response-size limits, and structured provider errors. Python, LangChain, LlamaIndex, and TypeScript provider files are trusted local code; WASM providers run through the sandboxed WASM provider path; OpenAPI and MCP providers delegate trust to their configured upstream service.

Authentication

The HTTP server supports four auth policies:

| Policy | When | Effect | |---|---|---| | Loopback development | Loopback bind, or SOMA_MCP_NO_AUTH=true on loopback | No auth middleware, no scope checks. | | Bearer token | SOMA_MCP_TOKEN set | /mcp and /v1/* require Authorization: Bearer <token>. | | OAuth | SOMA_MCP_AUTH_MODE=oauth with at least one configured provider | Browser-based Google, Authelia, or GitHub login issues JWT bearer tokens. | | Trusted gateway | SOMA_NOAUTH=true on non-loopback | Local auth and scope checks disabled because an upstream gateway is responsible. |

The startup guard refuses non-loopback unauthenticated binds unless bearer, OAuth, or trusted-gateway mode is configured. /health, /readyz, /status, and /openapi.json are public by design and return only safe runtime metadata.

See docs/AUTH.md for the detailed auth model.

Configuration

Values load from config.toml, local appdata files, and environment variables; explicit environment variables win. The built-in offline provider works without real credentials, but generated projects should mark their real upstream/platform credentials as required.

| Variable | Required | Default | Description | |---|---|---|---| | SOMA_API_URL | no | empty | Deployed platform API or upstream service URL. Empty selects stub/offline behavior. | | SOMA_API_KEY | no | empty | Bearer token or upstream service API key. | | SOMA_PROVIDER_DIR | no | providers | Directory scanned for drop-in provider files. Relative paths resolve from the current working directory. | | SOMA_MCP_HOST | no | 127.0.0.1 | HTTP server bind host. | | SOMA_MCP_PORT | no | 40060 | HTTP server bind port. | | SOMA_MCP_SERVER_NAME | no | soma | MCP server name advertised to clients. | | SOMA_MCP_NO_AUTH | no | false | Disable auth for loopback development. | | SOMA_NOAUTH | no | false | Trusted-gateway non-loopback no-auth mode. | | SOMA_MCP_TOKEN | bearer | empty | Static bearer token. | | SOMA_MCP_ALLOWED_HOSTS | no | empty | Extra comma-separated Host header values. | | SOMA_MCP_ALLOWED_ORIGINS | no | empty | Extra comma-separated CORS origins. | | SOMA_MCP_TRACE_HEADERS | no | off | Trusted inbound HTTP trace extraction: off, trusted, or trusted-with-baggage. | | SOMA_MCP_AUTH_MODE | no | bearer | bearer or oauth. | | SOMA_MCP_PUBLIC_URL | OAuth | empty | Public URL for OAuth metadata and callbacks. | | SOMA_MCP_GOOGLE_CLIENT_ID | OAuth | empty | Google OAuth client ID. | | SOMA_MCP_GOOGLE_CLIENT_SECRET | OAuth | empty | Google OAuth client secret. | | SOMA_MCP_AUTHELIA_ISSUER_URL | Authelia | empty | HTTPS Authelia OIDC issuer URL. | | SOMA_MCP_AUTHELIA_CLIENT_ID | Authelia | empty | Authelia OIDC client ID. | | SOMA_MCP_AUTHELIA_CLIENT_SECRET | Authelia | empty | Authelia OIDC client secret. | | SOMA_MCP_GITHUB_CLIENT_ID | GitHub | empty | GitHub OAuth App client ID. | | SOMA_MCP_GITHUB_CLIENT_SECRET | GitHub | empty | GitHub OAuth App client secret. | | SOMA_MCP_AUTH_DEFAULT_PROVIDER | no | first configured | Provider used when a request omits provider; automatic priority is Google, Authelia, GitHub. | | SOMA_MCP_AUTH_ADMIN_EMAIL | OAuth | empty | Initial/admin OAuth email. | | RUST_LOG | no | info | Log filter. Stdio mode suppresses noisy logs to avoid corrupting JSON-RPC. |

Keep SOMA_MCP_TRACE_HEADERS=off unless the server is bound to loopback or a trusted gateway strips or overwrites trace headers from untrusted clients. Bearer/OAuth authentication alone is not that trust boundary. See docs/TRACE_CONTEXT.md for the complete inbound-only trace-header contract.

Samples:

Provider callback paths default to /auth/google/callback, /auth/authelia/callback, and /auth/github/callback; callback and scope overrides are listed in docs/ENV.md. GitHub OAuth Apps do not provide an upstream refresh token, so GitHub-authenticated sessions do not receive a local refresh token and must sign in again after their access token expires. See docs/AUTH.md for provider selection and security details.

Development

# Build profiles
cargo build --bin soma --no-default-features --features local-adapter
cargo build --bin soma --no-default-features --features server
cargo build --bin soma --features full

# Run checks
cargo fmt -- --check
cargo clippy --all-targets -- -D warnings
cargo nextest run
cargo xtask contract-audit
cargo xtask generate-provider-surfaces --check

# Common just recipes
just dev                 # loopback HTTP server with local no-auth
just mcp                 # stdio MCP
just greet               # CLI smoke test
just doctor              # pre-flight check
just build-local         # local adapter binary
just build-full          # web assets + full platform binary
just verify              # fmt, lint, check, test
just check-docs          # generated docs/metadata current
just scaffold-contract-check
just validate-plugin

cargo xtask ci runs the main local CI sequence. Optional tools such as cargo-nextest, taplo, and cargo-audit are used when installed.

Workspace layout

35 cargo members:

| Path | Contents | |---|---| | crates/soma/* | Product code for this server — domain, application, config, client, api, cli, mcp, runtime, integrations, palette, web, test-support | | crates/shared/* | Reusable engine crates other servers consume — auth, mcp (client/server/proxy/gateway), provider-core, provider-adapters, http-api, http-server, observability, openapi, self-update, traces, codemode, cli-core | | crates/integrations/* | Upstream service bridges — gotify, unifi | | apps/soma | The soma binary and its integration tests. The only cargo member under apps/apps/web (Next.js) and apps/palette (assets) are not Rust crates. | | packages/python | pyo3 Python provider platform (abi3-py311) | | xtask | All repository automation; scripts/*.py are thin wrappers over it |

rmcp is pinned exactly — rmcp = { version = "=3.1.0", default-features = false } in [workspace.dependencies], duplicated on the rmcp-client alias entry because TOML cannot cross-reference. Bump both together.

Known inconsistency: [workspace.package] declares no edition, so each member sets its own — currently 31 on edition 2021 and 4 on edition 2024. Since generated projects inherit this manifest shape, prefer hoisting edition = "2024" into [workspace.package] (with members using edition.workspace = true) over adding another per-crate edition line.

Client Configuration

Streamable HTTP:

{
  "mcpServers": {
    "soma": {
      "url": "http://localhost:40060/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}

Stdio:

{
  "mcpServers": {
    "soma": {
      "command": "/path/to/soma",
      "args": ["mcp"],
      "env": {
        "SOMA_API_URL": "https://api.example.com",
        "SOMA_API_KEY": "YOUR_API_KEY",
        "RUST_LOG": "warn"
      }
    }
  }
}

For generated projects, replace soma, SOMA_*, tool names, scopes, and paths with the generated service names.

Plugin Surfaces

The repo ships one shared Soma plugin package under plugins/soma for Claude Code, Codex, and Gemini surfaces. Plugin manifests are versionless; release tooling derives version identity from git state. The plugin package can use the local stdio adapter and includes setup/doctor support for appdata and environment files.

Primary docs:

Distribution Contract

The soma release component is defined in release/components.toml. Version-bearing artifacts must stay aligned across the Rust package, Cargo.lock, server.json, the npm package, generated OpenAPI metadata, OCI image identifiers, and the changelog.

Plugin manifests stay versionless. Marketplace and plugin release identity is derived from git/package metadata, while server.json and generated provider surface docs describe the currently shipped runtime surface. Run cargo xtask check-version-sync, cargo xtask generate-provider-surfaces --check, and cargo xtask check-docs before publishing release metadata.

Web UI

The web feature serves the static export bundled by soma-web. Editable frontend source lives in apps/web, and cargo xtask sync-web-source copies that source into the Rust crate bundle.

Useful commands:

cargo xtask build-web
cargo xtask sync-web-source
cargo xtask check-web-source-sync
pnpm -C apps/web validate

Generated projects that do not need a human UI should use local-adapter, server, or a custom feature set without web.

Deployment

The full platform profile is designed for one deployable soma binary. The repository also includes Docker and Compose samples:

When adapting a generated project, verify the canonical binary name, exposed port, healthcheck port, image labels, service user/group, data volume, and required environment variables. The scaffold verifier catches several scaffold-only artifacts, but deployment files still need service-specific review before publishing an image.

When Drop-In Providers Are Not Enough

Most new capabilities should start as provider files. Reach for native Rust or a scaffolded product when you need a reusable crate boundary, richer service state, custom clients, background jobs, a dedicated package identity, or hand-tuned transport behavior.

For a generated product, start by printing the profile-aware checklist:

cargo xtask scaffold --adapt-plan ../generated/myservice-mcp

Then generate reviewable starter artifacts for the repetitive action wiring:

cargo xtask scaffold \
  --write-action-starters ../generated/myservice-mcp \
  --actions actions.json

This writes docs/action-starters/ in the generated project with snippets for action metadata, MCP dispatch, CLI variants, service stubs, and test coverage.

  1. Replace the stub client in crates/soma/client/src/client.rs only when the provider file path is not enough.
  2. Put domain logic in crates/soma/application/src/service.rs or focused service modules.
  3. Register native provider/action metadata so MCP, CLI, REST, docs, and plugins stay registry-driven.
  4. Regenerate MCP schema docs, provider surface docs, and OpenAPI so generated surfaces reflect the provider registry.
  5. Add REST handlers only for infrastructure routes; business actions should stay registry-backed direct routes.
  6. Update config fields and env prefixes in crates/soma/config/src/config.rs.
  7. Update .env.example, config.soma.toml, plugin options, and setup mappings.
  8. Update server.json, plugin metadata, repository URLs, Docker labels, and release metadata.
  9. Add tests for MCP dispatch, CLI parsing, REST routes, provider loading, and service behavior.
  10. For generated/exported projects, run scaffold verification plus the project's local quality gates.

For public repositories, also review tracked docs, generated metadata, CI runner configuration, and secret-scanning allowlists before publishing.

Troubleshooting

  • soma doctor checks local configuration, appdata, and connectivity.
  • soma providers validate confirms provider manifests and compiled schemas against the loaded, live registry.
  • soma providers inspect shows provider surfaces, capability posture, and generated action inventory.
  • soma providers list|lint|status inspect drop-in provider files on disk without loading the registry or executing any handler — safe to run before the runtime touches TS/WASM/MCP/OpenAPI providers. See docs/PROVIDERS.md.
  • Stdio mode keeps logs quiet so JSON-RPC is not corrupted; use HTTP mode or file logs when investigating noisy startup failures.
  • If generated docs drift, run cargo xtask generate-provider-surfaces --write and then re-run the --check command.

Related Servers

  • runifi - UniFi controller REST API bridge.
  • rtailscale - Tailscale API bridge for devices, users, and tailnet operations.
  • unraid - Unraid monorepo: Python and Rust GraphQL MCP servers plus Unraid plugins.
  • rapprise - Apprise notification fan-out bridge for many delivery backends.
  • rgotify - Gotify push notification bridge for sends, messages, apps, and clients.
  • rarcane - Arcane Docker management bridge for containers and related resources.
  • yarr - Media-stack bridge for Sonarr, Radarr, Prowlarr, Plex, and related services.
  • rytdl - Media download and metadata workflow server.
  • synapse - Local Synapse workflow server for scout and flux actions.
  • cortex - Syslog and homelab log aggregation MCP server.
  • axon - RAG, crawl, scrape, extract, and semantic search project.
  • labby - Homelab control plane and MCP gateway project.
  • lumen - Local semantic code search MCP server.

Documentation

| Topic | Docs | |---|---| | Architecture and layering | docs/ARCHITECTURE.md, docs/PATTERNS.md | | Dynamic provider runtime | docs/specs/dynamic-provider-runtime.md, docs/generated/provider-surfaces.md | | Provider manifest contract | docs/contracts/provider-manifest.schema.json, docs/contracts/examples/provider-manifests | | Scaffold workflow | docs/SCAFFOLD.md, docs/CARGO_GENERATE.md | | Scaffold intent contract | docs/specs/scaffold-intent-handoff.md, docs/contracts/scaffold-intent.schema.json | | MCP action schema | docs/MCP_SCHEMA.md | | REST OpenAPI | docs/generated/openapi.json | | Auth | docs/AUTH.md | | Plugins | docs/PLUGINS.md | | Release/versioning | release/components.toml, docs/MCP-REGISTRY-PUBLISH-GUIDE.md | | Automation | xtask/README.md, scripts/README.md | | Tests | apps/soma/tests/README.md |

Verification

Product runtime gates:

cargo xtask check-docs
cargo xtask generate-provider-surfaces --check
cargo xtask check-schema-docs --check
cargo xtask check-openapi --check
cargo xtask validate-plugin-layout
cargo xtask check-version-sync
just verify

Scaffold/template gates are a separate lane. Run them when a change touches the scaffold contract, cargo-generate post-processing, or generated-project output:

cargo xtask check-scaffold-intent-contract
cargo xtask scaffold --verify ../generated/myservice-mcp
cargo xtask check-cargo-generate

Use targeted checks while iterating, then run the broader product and affected scaffold gates before release.

License

MIT