agentsclimarketplace

Monospace

Skill directus/monospace-agent-skills/skills/monospace

Use when doing ANY task against a Monospace instance. Triggers: reading, creating, updating, deleting, querying, filtering, sorting, or paginating data via the Monospace REST API or the @monospace/sdk (createClient, readMany, createOne, updateOne); generating a typed SDK client (`npx @monospace/sdk generate`, monospace.config.ts); connecting to or using the Monospace MCP server; minting API keys or authenticating; inspecting collections, fields, relations, or schema. Do NOT use for legacy Directus v9 / @directus/sdk — Monospace is a different product with a different API and SDK.From its SKILL.md

Install
npx -y skills add directus/monospace-agent-skills --skill monospace

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.8 KB, as published. Nobody here has run it

Monospace

Drive a Monospace instance from an agent: query and mutate data via the REST API or the typed SDK, generate instance-correct types, and use the MCP server. This page is a router — read the principles and the inline traps, then load the reference for the task.

Core principles

1. You almost certainly don't know this API. Don't guess — use the ground truth. Monospace is not in most training data, so do not invent endpoints, SDK methods, or types from memory. The SDK is @monospace/sdk (createClient + per-collection delegates). Get the real shape from generated types (npx @monospace/sdk generate) or the live OpenAPI doc (GET /api/<workspace>/openapi), plus the references below. (If you happen to know Directus: it is a different product — don't assume its APIs carry over.)

2. Generate types, then write against them. The most reliable way to get the data shape right is to generate a typed client from the running instance: npx @monospace/sdk generate reads the live OpenAPI document and emits a typed client matching that instance's schema. Prefer generated types over hand-written shapes. See references/sdk.md.

3. Verify against current docs / OpenAPI before implementing. For anything not covered here, fetch the canonical OpenAPI doc (GET /api/<workspace>/openapi, or /api/system/openapi) or the Monospace docs. The OpenAPI doc is generated from the live schema, so it is always correct for the instance.

4. Inspect before you mutate, then verify. Read the schema / list items (read-only) before writing. After a write, read it back to confirm. A change without verification is incomplete.

5. Recover, don't loop. If an approach fails 2-3 times, stop and reconsider — check the error body (it carries a message), the schema, and permissions. Retrying the same call rarely fixes it.

Critical traps (read before writing any data code)

These are verified, easy-to-miss behaviors. Getting them wrong fails silently.

  • Responses are enveloped as { "data": ... }. A list returns { data: [...] }, a single item { data: {...} }. The SDK strips the top-level envelope for you, but nested to-many relations stay enveloped — relation data sits under relation.data, and the SDK does NOT unwrap it. Reach into item.<relation>.data (to-one relations are accessed directly).
  • Methods take a single options object, not positional args. readOne/updateOne/deleteOne take { key, ... }; createOne({ data: <object>, fields }) (single object under data); createMany takes { data, fields }; updateMany takes { filter, data, fields }; deleteMany takes { filter, fields? }. There is no readOne(id) form. Collections are cased as named (client.Articles, not client.articles).
  • Deletes return no content unless fields is provided. deleteOne({ key }) / deleteMany({ filter }) return void; pass fields only when you need deleted rows back.
  • fields defaults to top-level primitives only. Relations are not returned unless you select them. The SDK sends fields: ['*'] by default (top-level), so request nested fields explicitly to get relations.
  • Filter operators are underscore-prefixed. _eq _neq _lt _lte _gt _gte _in _nin _between _nbetween _contains _icontains _ncontains _nicontains _starts_with _nstarts_with _ends_with _nends_with _null; combine with _and _or _not; for to-many relations use quantifiers _some _every _none. _null is only valid on nullable fields. Full table in references/rest-api.md.
  • Sort uses the object form, not -field. Use sort: [{ <field>: { direction: 'asc' | 'desc' } }]. The -created_at shorthand is rejected by the engine.
  • No search param, no page/cursor pagination, no aggregates yet. Paginate with limit (default 100) + offset; request meta=totalCount when you need the total matching row count. Aggregate/group params parse but are silently ignored today.

Connect to a Monospace instance

You need three things: the host (engine base URL), the workspace slug (Monospace is multi-workspace; most data routes are /api/<workspace>/...), and a token. Create an API key in the Studio under Account → Access → API Keys (/account/access#api-keys; API endpoint POST /api/system/api-keys), or log in with POST /api/auth/providers/<name>/password/login for a user access token. Prefer Authorization: Bearer <token> for agents/scripts; the API also accepts an access_token query parameter or session cookie, but send only one credential source per request.

Two ways an agent works with the data:

  • MCP server — best for agentic CRUD + schema work inside a chat/coding agent. Set it up below.
  • SDK / REST — best for writing application code. See references/sdk.md and references/rest-api.md.

MCP server setup (recommended for agentic work)

The Monospace MCP server is served by the engine, per workspace, over streamable-HTTP.

  • Endpoint: POST https://<host>/api/<workspace>/mcp (per-workspace; POST only; protocol 2025-11-25).
  • Auth: Authorization: Bearer <token> or, only when headers are unavailable, access_token=<token> query parameter populated from a secret store (API key or user access token). Do not send both. Use session cookies for browser flows, not agent config. The workspace needs the ai:mcp entitlement, and each tool runs under the token's RBAC.

Config (.mcp.json at the project root):

{
  "mcpServers": {
    "monospace": {
      "type": "http",
      "url": "https://YOUR_HOST/api/YOUR_WORKSPACE/mcp",
      "headers": { "Authorization": "Bearer ${MONOSPACE_API_KEY}" }
    }
  }
}

Tools exposed (7): list_items, create_items, update_item, delete_item (CRUD under the caller's permissions), read_schema (needs dataModel:read), read_data_sources (dataModel:read + dataSource:read), and mutate_schema (dataModel:edit — can be destructive).

Troubleshooting: curl -s -o /dev/null -w "%{http_code}" -X POST https://<host>/api/<workspace>/mcp — a 401 means it's up but unauthenticated (expected without a token); 403 means the credential is valid but forbidden by RBAC or missing entitlement; 404 means the path is wrong; a hang or refusal means it's unreachable. If tools aren't visible: confirm the URL includes the right <workspace>, the credential is present (Authorization: Bearer header or access_token query parameter, not both), and the workspace has ai:mcp enabled. Full details + RBAC and the per-tool input schemas: references/mcp-and-auth.md.

Generate a typed SDK client (codegen)

npx @monospace/sdk init       # scaffold monospace.config.ts (output defaults to ./src/generated/monospace)
npx @monospace/sdk login      # store credentials in the OS keyring (or set MONOSPACE_API_KEY)
npx @monospace/sdk generate   # fetch the live OpenAPI and emit <output>/index.ts

The generated index.ts exports a createClient bound to your instance's schema — import it from your generated output (default ./src/generated/monospace; match your project's path/alias), not from @monospace/sdk, for fully-typed queries. Remote mode fetches GET /api/<workspace>/openapi (auth required); local mode reads a saved OpenAPI JSON via input. Details, flags, and a zero-to-typed-client sequence: references/sdk.md.

Reference guides

TopicReferenceLoad when
Query engine, envelope, endpoints, error shapes, raw RESTreferences/rest-api.mdCalling the API directly, or in a non-TS language
createClient, typed delegates, codegen workflow, error classesreferences/sdk.mdWriting TypeScript against the SDK or generating types
CRUD recipes with the traps annotatedreferences/data-workflows.mdReading/writing data and you want a known-good pattern
MCP tools + schemas, API keys, auth modes, .mcp.jsonreferences/mcp-and-auth.mdSetting up MCP, authenticating, or choosing/using a tool

Keep looking

Skills are one crate of 628,853. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.