Skip to main content
workspace.yml is the configuration file at the root of every Friday space. It defines agents, jobs, signals, memory stores, and MCP server connections. Friday Studio reads this file at startup and applies it live when you save changes. The annotated example below is drawn from the GitHub Digest starter space — a scheduled job that summarizes open PRs and review requests every Monday and Thursday.

Complete annotated example

# Schema version. Always "1.0".
version: '1.0'

workspace:
  name: GitHub Digest
  description: Scheduled GitHub PR and review digest every Monday and Thursday

# ---------------------------------------------------------------------------
# Signals — define what triggers your jobs
# ---------------------------------------------------------------------------
signals:
  github-digest-schedule:
    description: 'Fires every Monday and Thursday at 8:30am Pacific'
    provider: schedule           # schedule | http | fs-watch | slack | telegram | discord | whatsapp | teams
    config:
      schedule: '30 8 * * 1,4'  # Standard cron expression
      timezone: America/Los_Angeles

# ---------------------------------------------------------------------------
# Jobs — define what runs when a signal fires
# ---------------------------------------------------------------------------
jobs:
  github-digest-job:
    description: 'Every Monday and Thursday: summarize open PRs and review requests'
    triggers:
      - signal: github-digest-schedule   # Must match a key in `signals`
    fsm:
      initial: idle
      states:
        idle:
          'on':
            github-digest-schedule:
              target: run
        run:
          entry:
            - type: agent
              agentId: github-digest-agent   # Must match a key in `agents`
              outputTo: digest-result        # Saves agent output as a named artifact
            - type: emit
              event: DONE
          'on':
            DONE:
              target: done
        done:
          type: final

# ---------------------------------------------------------------------------
# Agents — define the AI components jobs can invoke
# ---------------------------------------------------------------------------
agents:
  github-digest-agent:
    type: llm              # llm | atlas | user | system
    description: >-
      Fetches open PRs and review requests for the authenticated GitHub user,
      then produces a concise digest grouped by repository.
    config:
      provider: anthropic
      model: claude-sonnet-4-6
      prompt: >-
        You are a GitHub digest assistant.

        1. Call `get_me` to find the authenticated user's login.
        2. Call `list_pull_requests` filtering for open PRs authored by the user.
        3. Call `list_pull_requests` filtering for PRs where review is requested.
        4. Group results by repository. For each PR include: title, number, URL,
           author, and age in days.
        5. Produce a concise digest sorted by oldest first within each group.

        REQUIRED: Call complete() with a summary of how many PRs were found.
        The job will time out if complete() is not called.
      tools:
        - github/get_me           # Format: serverId/toolName
        - github/list_pull_requests

# ---------------------------------------------------------------------------
# Tools — configure MCP server connections
# ---------------------------------------------------------------------------
tools:
  mcp:
    client_config:
      timeout:
        progressTimeout: 2m
        maxTotalTimeout: 30m
    servers:
      github:                      # Server id — referenced in agent tools lists
        transport:
          type: http               # http | stdio
          url: 'https://api.githubcopilot.com/mcp'
        auth:
          type: bearer
          token_env: GH_TOKEN
        env:
          GH_TOKEN:
            from: link             # Reads credential from Friday Link (connected account)
            provider: github
            key: access_token

# ---------------------------------------------------------------------------
# Memory — define stores and cross-space mounts
# ---------------------------------------------------------------------------
memory:
  own:
    - name: notes
      type: short_term             # short_term | long_term | scratchpad
      strategy: narrative
    - name: memory
      type: long_term
      strategy: narrative
  mounts:
    - name: user-notes
      source: user/narrative/notes
      mode: ro                     # ro (read-only) | rw (read-write)
      scope: workspace             # workspace | job | agent
    - name: user-memory
      source: user/narrative/memory
      mode: ro
      scope: workspace

Field reference

version

FieldTypeRequiredDescription
versionstringYesAlways "1.0".

workspace

FieldTypeRequiredDescription
namestringYesDisplay name shown in Friday Studio.
descriptionstringNoOne-line description of what the space does.

signals

Each entry under signals is a named trigger. The key becomes the signal id referenced in job triggers and FSM states.
FieldTypeRequiredDescription
descriptionstringYesHuman-readable description.
providerstringYesOne of: schedule, http, fs-watch, slack, telegram, discord, whatsapp, teams. (system is reserved for internal signals.)
configobjectYesProvider-specific config. See Signal providers.
Schedule config:
FieldTypeDescription
schedulestringStandard 5-field cron expression.
timezonestringIANA timezone string, e.g. America/Los_Angeles.
HTTP config:
FieldTypeDescription
pathstringURL path that triggers the webhook, e.g. /hooks/my-trigger. The method is always POST.
timeoutdurationOptional timeout for signal processing.

jobs

Each entry under jobs is a named job. Jobs are FSM (finite state machine) definitions that describe which agent runs in which state and what transitions to make.
FieldTypeRequiredDescription
descriptionstringNoHuman-readable description.
triggersarrayNoList of { signal: signalId } objects. Omit for jobs invoked only from chat or run manually.
fsmobjectYes*FSM definition. *A job specifies exactly one of fsm (shown here) or execution, an agent-pipeline alternative.
fsm.initialstringYesName of the starting state.
fsm.statesobjectYesMap of state name to state definition.
State entry actions:
TypeFieldsDescription
agentagentId, prompt?, outputTo?Invoke a configured agent. outputTo saves the result as a named artifact.
llmprovider, model, prompt, tools?, outputTo?Run an inline LLM step without defining a named agent.
emiteventEmit a named event to drive a state transition.
notificationmessage, communicators?Send a message to configured communicators (Slack, Telegram, …).

agents

Each entry under agents is a named agent. The key is the agentId referenced in job FSM entry actions.
FieldTypeRequiredDescription
typestringYesOne of: llm, atlas, user, system.
descriptionstringYesHuman-readable description.
configobjectVariesAgent-specific config. Required for llm; optional for system; atlas and user take top-level agent/prompt instead.
LLM agent config:
FieldTypeRequiredDescription
providerstringYesInference provider. Common values: anthropic, openai, gemini, groq.
modelstringYesModel identifier, e.g. claude-sonnet-4-6.
promptstringYesSystem prompt for the agent.
toolsarrayNoMCP tool allowlist in serverId/toolName format. Omit to allow all tools from all enabled servers.
Atlas agent config:
FieldTypeRequiredDescription
agentstringYesAtlas Agent ID from the registry, e.g. web, gh, slack, hubspot.
promptstringYesTask-specific context layered on the bundled agent’s behavior.
configobjectNoAgent-specific configuration passed to the agent.
envobjectNoEnvironment variables. Values can be literals or a Link reference ({ from: link, … }).

tools.mcp

FieldTypeDescription
client_config.timeout.progressTimeoutdurationHow long to wait between tool call progress updates before timing out.
client_config.timeout.maxTotalTimeoutdurationMaximum total time for a single tool call.
serversobjectMap of server id to server config.
Server config:
FieldTypeDescription
transport.typestringhttp or stdio.
transport.urlstringFor http transport: the MCP server URL.
transport.commandstringFor stdio transport: the command to run.
transport.argsarrayFor stdio transport: command arguments.
auth.typestringbearer (the only supported value). Omit the entire auth block for servers that need no auth.
auth.token_envstringName of the env var holding the bearer token.
envobjectEnv var definitions. Values can be literals or a Link reference: { from: link, key, … } with either provider (e.g. github) or a specific credential id.

memory

FieldTypeDescription
ownarrayMemory stores owned by this space. Each entry: { name, type, strategy? }.
mountsarrayCross-space memory mounts. Each entry: { name, source, mode, scope, scopeTarget? }.
Own store fields:
FieldValuesDescription
typeshort_term, long_term, scratchpadRetention policy.
strategynarrativeHow entries are written and retrieved. Optional; narrative is the only value.
Mount fields:
FieldValuesDescription
sourcestring{spaceId}/narrative/{storeName} path to the source store.
modero, rwRead-only or read-write access. Defaults to ro.
scopeworkspace, job, agentHow broadly the mount is visible within this space.
scopeTargetstringRequired when scope is job or agent — the id of the job or agent to scope the mount to. Omit for scope: workspace.

More examples

Browse the Friday Studio Examples repo for a dozen ready-made spaces with complete workspace.yml files covering email, GitHub, Telegram, Google Sheets, price monitoring, and more.