Buffaly Logo
Core

Buffaly services

Understand services as capability boundaries that can own lifecycle, identity, state, configuration, UI ownership, and multiple related methods.

Service mental model

A flat tool is the callable interface Buffaly invokes during a task. A service is the owner behind one or more callable methods. The service gives projected tools a stable source model and operating boundary.

Use services when the capability needs more than one isolated tool call: configured identity, lifecycle, shared state, initialization, authenticated clients, multiple methods, or an external system boundary.

Services, tools, and actions

NeedPreferWhy
Reuse a prompt-driven procedurePrompt action or workflow memoryThe work is mostly instruction, judgment, or sequencing.
Add one ontology-backed operationProtoScript actionBuffaly should discover and call one typed action.
Expose one stateless helperNative toolNo identity, initialization, or related method family is needed.
Model a configured system or accountServiceIdentity, state, configuration, initialization, or multiple methods matter.
Integrate an MCP serverMCP-backed serviceEach binding can have different transport, auth, endpoint, command, tools, and boundary data.
Add host UI, routes, or JsonWs artifactsWeb module plus services/toolsWeb modules own packaging and startup behavior; services own capability boundaries.

Why services matter

Services matter when Buffaly needs to know which configured capability it is using. Examples include an MCP binding, a reporting connection, a workspace account, or a module-owned service surface.

Metadata

ServiceName, Scope, Description, projected tool names, and configured binding identity.

Lifecycle

Optional Initialize(), AutoInitialize, startup diagnostics, and per-session lifecycle state.

Configuration

Endpoint, command, working directory, timeout, secret reference, route prefix, account, or tenant.

Method family

Multiple related To* methods can project as flat tools without losing service ownership.

Service lifecycle and diagnostics

During runtime initialization, Buffaly discovers concrete descendants of the Service root. A service can auto-initialize when AutoInitialize is enabled or not declared, but automatic initialization is intentionally constrained.

  • AutoInitialize defaults on when the service does not declare it; AutoInitialize=false skips startup initialization.
  • Initialize() must be parameterless to run automatically.
  • Startup diagnostics record completed, failed, skipped, or pending initialization.
  • Initialization state is tracked by session key and service prototype name.
Operator rule: service readiness should be visible through diagnostics, not guessed from a tool name. If a service needs credentials, endpoint configuration, host runtime state, web-module routes, or JsonWs artifacts, verify those before relying on it for external or destructive work.

Default, optional, and runtime-available services

Do not treat every service-looking source file as an enabled runtime service. Availability has several levels.

  1. Service model present: a prototype descends from Service, such as UserSecretsService, McpService, WikiService, BrowserWebModuleService, or ComputerUseWebModuleService.
  2. Project-included: the active ProtoScript project includes the file through Project.pts, Core/index.pts, or Skills/index.pts.
  3. Concrete service discovered: runtime diagnostics find a concrete descendant under the Service root.
  4. Initialized or ready: diagnostics show initialization completed or no initializer is required.
  5. User-facing projected action: a selected service method follows the To* projection convention or is exposed through a nested To* action prototype.
Core service types such as UserSecretsService and the generic McpService can be part of the included core project, while domain services such as Wiki, Browser, ComputerUse, JsonWs, Google Workspace, and search/session services may depend on enabled skill folders, credentials, routes, web modules, or remote endpoints.

How to verify available services

Use this sequence when a user asks which services are available in a running Buffaly instance.

1. Inspect includes

Start with Project.pts, Core/index.pts, and Skills/index.pts.

2. Use service discovery

List services or inspect the hierarchy when the Services skill is loaded.

3. Read diagnostics

Use runtime diagnostics built from the service registrar to inspect projected names and initialization state.

4. Verify backing config

Check secrets, MCP binding fields, JsonWs base URLs, web-module routes, generated artifacts, and provider settings.

If diagnostics disagree with implementation files, trust the running-session diagnostics for current availability and inspect source to understand why a service did not load or initialize.

Source model and projected tool names

The service method is the source model. The projected tool name is the flat callable interface that Buffaly can load and call.

Service methodProjected tool name
McpService#FeedingFrenzy.ToListServerToolsMcpService_FeedingFrenzy_ToListServerTools
McpService#GitHub.ToCallToolMcpService_GitHub_ToCallTool

This preserves service identity and method ownership while still presenting a normal callable tool surface to the Buffaly agent.

Singleton versus per-binding services

Singleton-style

Appropriate only when there is genuinely one shared capability and instance identity does not change the meaning of a call.

Per-binding

Appropriate when each configured instance has its own boundary. MCP is the clearest example because different servers can have different endpoints, commands, transports, auth sources, capability sets, filesystem roots, and intended usage.

Concrete examples

MCP-backed CRM service: model the CRM server as a service instance that owns binding key, transport, endpoint or command, token secret reference, timeout, and description. Buffaly can list remote tools or call a remote tool without losing configured service identity.

UserSecretsService: treat this as a core boundary for sensitive credentials, but remember that secret values are user/environment specific and should not be copied into ontology memory or documentation.

Web modules: modules can own web-facing packaging and startup behavior. Installed web modules live under lib/web-modules, static assets are exposed under wwwroot/web-modules/<ModuleName>, and generated JsonWs manifests/stubs are copied to wwwroot/JsonWs so the JsonWs loader can discover them.

Next