Contents

Docs / Concepts

What a server is made of

sokie.json, the spec and a file per tool: the repository is the server's source of truth.

A Sokie server is a directory of plain files, usually its own repository. Sokie builds the server from those files and nothing else, so the repository is the source of truth: the CLI, the app and every deploy read the same files.

petstore/
  sokie.json        what the server is, and how to reach the API
  openapi.json      the spec, committed
  tools/            one Markdown file per tool
  prompts/          optional: prompt templates
  resources/        optional: documents clients can read
  tests/            optional: test cases, one JSON file each
  .sokie/           local only, kept out of git

There's no generated code. Everything else, from the tools' input schemas to how each call reaches the API, comes from the spec when Sokie builds the server.

sokie.json

{
  "$schema": "https://sokie.sh/schema/server.v1.json",
  "schemaVersion": 1,
  "name": "Tasks",
  "description": "Read and manage tasks in a Tasks workspace.",
  "source": { "type": "openapi", "path": "openapi.yaml" },
  "upstream": {
    "auth": {
      "type": "apiKey",
      "in": "header",
      "name": "Authorization",
      "prefix": "Bearer ",
      "key": "perCaller"
    }
  },
  "settings": { "discovery": "all", "closedWorld": true }
}
  • source is the spec: openapi for OpenAPI 3 and Swagger 2, or graphql. The path is inside the repository, and a build reads only that file.
  • upstream is how to reach the API. baseUrl defaults to the spec's first server. auth is none, an apiKey, or oauth, and headers are sent on every call. Calls carry User-Agent: sokie/<runtime version> unless headers sets one. How clients sign in covers the choices.
  • settings.discovery is all, which lists every tool, or search, for large APIs. settings.closedWorld says the tools only touch this API.
  • secrets names the values the server needs, without their values. See Add secrets.

Unknown keys are errors, so a typo never goes unnoticed. sokie fmt writes the file in Sokie's own order, so a change is always a small diff.

Tools

Each file in tools/ is one tool, named for its file: tools/getTask.md is the tool getTask. The frontmatter says which operation it calls and how it behaves; the body is its description.

---
operation: GET /tasks/{taskId}
title: Get a task
risk: read
idempotent: true
tags: [tasks]
---

Get one task by its id, with its title, status, due date and project.
  • operation, required: the method and path, as in the spec. For GraphQL, query tasks or mutation createTask.
  • title: a short name for people.
  • risk: read, write, delete or external_effect.
  • idempotent: whether a retry is safe.
  • tags: up to eight.
  • project: a JMESPath expression that trims the response.

Make tools easy for agents to use says how to write each one well.

Prompts and resources

A file in prompts/ is a prompt template clients can offer. Its frontmatter has a description and any arguments, and its body is the template, with {{name}} for each argument.

A file in resources/ is a document clients can read, like a guide to the API. Its frontmatter gives it a uri, such as tasks://guide, and its body is the content.

Test cases

A file in tests/ is a test case: one call to a tool and what its result must be. sokie test runs them, and so does every deploy.

What never goes in the repository

Secret values, and keys of any kind: sokie check stops a build that contains anything that looks like one. Local secrets for sokie dev live in .sokie/dev.env, which must stay out of git.