Developer documentation

Meow Meow Scratch® developer documentation

Learn how APIs work, connect Raspberry Pi projects, and build IoT applications without creating or operating a backend. This reference covers the web app, REST API, Python SDK and CLI, MCP, and examples.

Learn the basics

Build your first API in 10 minutes

An API is a way for two programs to exchange data. One program sends an HTTP request to an endpoint; the endpoint returns a response. In this lesson, you will create a private temperature API, send it a reading, and retrieve that reading.

What you will build

A Weather Station app with a Readings collection. Each record contains a numeric temperature value, ready for a script, Raspberry Pi, or another application to use. You do not need any hardware for this lesson.

The request-response loop

1 · Request

Your browser, terminal, or device asks an endpoint to read or change data.

2 · Endpoint

The endpoint authenticates the request, validates the data, and performs the action.

3 · Response

The API returns a status code and usually a JSON body describing the result.

Five parts of an HTTP request

URL

Where to send it

Method

GET reads, POST creates, PATCH updates, DELETE removes

Headers

Context such as authentication and content type

Body

JSON—the text format of keys and values sent with a write

Status

The numeric result, such as 200 or 404

Before you start

You need a Meow Meow Scratch® account and a terminal withcurl. The commands use macOS, Linux, Git Bash, or WSL shell syntax. On Windows, Git Bash is the simplest way to run them exactly as written. PowerShell uses different environment-variable and line-continuation syntax.

1. Create the app and collection

Complete these steps in the web app. Slugs become parts of the API URL, so enter them exactly as shown.
  1. 1Open Apps → New App. Use name Weather Station and slug weather-station.
  2. 2Open the app and choose New Endpoint. Use name Readings, slug readings, and type Collection.
  3. 3Open the endpoint and choose Add Field. Use label Temperature, key temperature, type Number, and enable Required.

Private by default

New apps and endpoints start private. Keep this tutorial private; you will authenticate each request with an API key restricted to this app.

2. Create an app API key

Return to Weather Station → API Keys → New API Key. Name it API tutorial, enable both Read and Write, then copy the value immediately. The full key is shown once.
terminal · set your values
export MEOW_APP_API_KEY="YOUR_APP_API_KEY"
export MEOW_USERNAME="YOUR_USERNAME"
export MEOW_API="https://meowmeowscratch.com/api"

Replace both YOUR_APP_API_KEY andYOUR_USERNAME. Keep the quotation marks. Do not paste a real token into source code, chat, or a public repository.

3. Send your first POST request

POST creates data. This request sends one temperature record to the collection management endpoint.
terminal · create a record
curl -i -X POST "$MEOW_API/apps/weather-station/endpoints/readings/records/"   -H "Authorization: Bearer $MEOW_APP_API_KEY"   -H "Content-Type: application/json"   -d '{"data":{"temperature":22.5}}'
expected response shape
HTTP/... 201 Created


{
  "uuid": "…",
  "data": {"temperature": 22.5},
  "created_at": "…",
  "updated_at": "…"
}

201 Created means the API accepted the request and created a new resource. Your UUID identifies that record.

4. Read it back with GET

GET reads data without changing it. The consumer URL is the stable address a website, script, or device uses.
terminal · read the collection
curl -i "$MEOW_API/v1/$MEOW_USERNAME/weather-station/readings/"   -H "Authorization: Bearer $MEOW_APP_API_KEY"
expected response shape
HTTP/... 200 OK


{
  "count": 1,
  "fields": [
    {"name": "temperature", "label": "Temperature", "field_type": "number"}
  ],
  "records": [
    {"uuid": "…", "data": {"temperature": 22.5}, "created_at": "…"}
  ]
}

What the command means

curl

The command-line HTTP client sending the request.

-i

Show the response status and headers as well as the JSON body.

-X POST

Use the POST method. GET is curl's default, so the read command does not need -X GET.

-H

Add a header. The Bearer header proves who you are; Content-Type says the body is JSON.

-d

Send the following JSON as the request body.

5. Experiment

Learning APIs becomes much easier when you change one thing and observe the response.
  • Send a second POST with temperature set to 18.4, then GET the collection again.
  • Add ?temperature__gte=20 to the GET URL and predict which record remains.
  • Send temperature as "warm" and inspect the 400 validation response.
  • Open Request Logs in the endpoint and find the GET request's status and response time.

You have built an API

You created a schema, authenticated a write, sent JSON with POST, interpreted a 201 response, and retrieved data with GET. The rest of this page shows every supported way to build on that loop.

Core product concepts

A Meow Meow Scratch® app is a project containing endpoints. Each endpoint has a stable consumer URL and can be managed through the web app, REST API, Python SDK, CLI, or MCP.

Collection

Many typed records

Sensor readings, events, form submissions, inventories

Static payload

One JSON document

Device state, configuration, flags, status documents

Proxy / integration

A guarded upstream request

Weather, games, or a third-party JSON service

Quick glossary

API
A defined way for programs to request data or actions from one another.
Endpoint
A URL that accepts a particular kind of API request.
JSON
A text format that represents data as objects, arrays, keys, and values.
Schema
The rules describing which fields exist and what type of value each accepts.
Slug
A short URL-safe name, such as weather-station.
Token
A secret credential sent with a request to prove identity and permission.

01 · Web app

Use the Meow Meow Scratch® web app

Use the dashboard to define schemas, edit data, configure integrations, inspect logs, manage credentials, and create control panels.

Create your first API

  1. 1

    Create an app

    Open Apps, choose New app, then set its display name, URL slug, and description. The app starts private.

  2. 2

    Add an endpoint

    Inside the app, choose Collection, Static Payload, or Proxy / Integration and give it a stable slug.

  3. 3

    Configure its data

    Add typed fields to a collection, edit the JSON payload for a static endpoint, or configure the upstream proxy.

  4. 4

    Test the consumer URL

    Open the endpoint page to copy its URL, inspect code snippets or QR code, and make a request.

Collection schemas

Collection fields drive validation, dashboard inputs, and public response metadata. Available types are text, long text, number, boolean, date, date-time, time, color, email, URL, select, rating, image URL, and JSON.

A field can be required, have a default, include help text, and carry type-specific options such as numeric bounds, select choices, rating maximums, or text placeholders. Records keep a UUID, timestamps, and the validated data object.

Endpoint behavior and operations

Chaos mode

Add a controlled delay or simulated error rate when testing clients.

Record expiry

Set a TTL so old collection records are automatically removed.

Transforms

Round or clamp numbers, normalize text case, or set missing defaults.

Webhooks

Deliver record and payload events to another HTTPS service.

Request logs

Inspect recent method, status, timing, client IP, and user-agent data.

Response encryption

Encrypt consumer responses and request plaintext with X-Encryption-Key.

Control panels

Controls expose endpoint values through a dashboard. Add toggle, color, slider, number, text, select, or display widgets and optionally share the panel by link.

Remote configuration without building a backend

Put device settings in one static endpoint, bind dashboard controls to keys such as camera.thresholds.confidence, and let the Raspberry Pi poll that document with an app API key. A dashboard change updates the same JSON the device reads. Collection widgets are display-only and show values from the latest record; proxy endpoints do not support widgets.

Credentials

Create platform tokens under Account for the SDK, CLI, MCP, and automation that works across apps. Create an app API key inside the relevant app for a Raspberry Pi, device, or integration that only needs that app. Give app keys only the Read and Write scopes they require. The full value is shown once.

02 · REST API

Call the REST API directly

The management API creates and updates resources. The consumer API reads endpoint data. Send Content-Type: application/json with JSON request bodies. If HTTP is new to you, complete the beginner tutorial before using this section as a reference.

Management API

Create and configure apps, endpoints, schemas, records, keys, webhooks, and control panels. Every request requires a Bearer token.

Consumer API

Read the stable URL used by websites, scripts, and devices. Private resources require a token; public resources allow anonymous reads.

Authentication

Authorization: Bearer YOUR_TOKEN

Keep the trailing slash

API routes are slash-terminated. Use /api/apps/, not /api/apps, to avoid an HTTP redirect—especially for POST, PATCH, and DELETE requests.

Choose the narrowest credential

App API key · one app

Recommended for Raspberry Pis, devices, and direct API integrations. The key can access only its app, and Read and Write scopes are enforced independently.

Platform token · all your apps

Recommended for the SDK, CLI, MCP, and account-wide resource automation. It can manage Meow resources across your account.

API credentials are accepted only by Meow resource routes, not authentication, profile, billing, chat, or CMS management. App keys also cannot create apps, manage credentials, or access account-wide control panels and provider configuration.

Use role-specific environment variables

Store account-wide tokens in MEOW_PLATFORM_API_KEY and app-scoped credentials in MEOW_APP_API_KEY. The SDK and tooling do not read the ambiguous legacy name MEOW_API_KEY.

Set reusable shell values

The examples below use these environment variables. Replace the placeholders with the app API key and username from the beginner tutorial.
terminal
export MEOW_API="https://meowmeowscratch.com/api"
export MEOW_APP_API_KEY="YOUR_APP_API_KEY"
export MEOW_USERNAME="YOUR_USERNAME"

Consumer API

Every endpoint is read from the same stable URL shape. Collection endpoints return paginated records, static endpoints return their JSON document, and proxy endpoints return the transformed upstream response.
http
GET /api/v1/{username}/{app}/{endpoint}/
GET /api/v1/{username}/{app}/{endpoint}/{record_uuid}/
GET /api/v2/dashboards/{share_token}/


# Public reads omit the header; replace these slugs with a public app and endpoint
curl "$MEOW_API/v1/$MEOW_USERNAME/YOUR_PUBLIC_APP/YOUR_PUBLIC_ENDPOINT/"


# Supply a token for a private consumer endpoint
curl "$MEOW_API/v1/$MEOW_USERNAME/weather-station/readings/" \
  -H "Authorization: Bearer $MEOW_APP_API_KEY"

Filter, aggregate, and export collections

Filters

Use a field name for equality. Number and rating fields also accept __gt, __gte, __lt, and __lte.

Aggregates

Pass aggregate=avg,min,max,sum,count and a numeric field. Count does not require a field.

CSV

Pass format=csv to export up to 500 records. CSV export is unavailable for encrypted endpoints.

terminal
BASE="$MEOW_API/v1/$MEOW_USERNAME/weather-station/readings/"


curl "$BASE?temperature__gte=20&limit=50"   -H "Authorization: Bearer $MEOW_APP_API_KEY"
curl "$BASE?aggregate=avg,max&field=temperature"   -H "Authorization: Bearer $MEOW_APP_API_KEY"
curl "$BASE?format=csv" -H "Authorization: Bearer $MEOW_APP_API_KEY" -o readings.csv

Consumer response shape

A collection response includes schema metadata alongside the data, so clients can render useful controls without a separate schema request.
json
{
  "count": 1,
  "limit": 100,
  "offset": 0,
  "fields": [
    {"name": "temperature", "label": "Temperature", "field_type": "number"}
  ],
  "records": [
    {"uuid": "…", "data": {"temperature": 22.5}, "created_at": "…"}
  ]
}

Update and delete a record

Use the UUID returned when the record was created. A successful PATCH returns the updated record; a successful DELETE returns204 No Content with no JSON body.
terminal
export RECORD_UUID="UUID_FROM_THE_POST_RESPONSE"


curl -i -X PATCH "$MEOW_API/apps/weather-station/endpoints/readings/records/$RECORD_UUID/"   -H "Authorization: Bearer $MEOW_APP_API_KEY"   -H "Content-Type: application/json"   -d '{"data":{"temperature":23.0}}'


curl -i -X DELETE "$MEOW_API/apps/weather-station/endpoints/readings/records/$RECORD_UUID/"   -H "Authorization: Bearer $MEOW_APP_API_KEY"

Successful status codes

200 OK

A read or update succeeded and returned a body.

201 Created

A POST created a new resource.

204 No Content

A delete succeeded and returned no body.

Management route reference

Path placeholders use the app, endpoint, or dashboard slug unless the placeholder is explicitly a UUID. List endpoints return JSON; record lists use limit/offset pagination with a default of 25 and maximum of 100. Account-wide app creation, dashboards, and key management require a platform token or web session; an app key can use the routes bound to its own app and permitted scopes.

Apps and endpoints

GET, POST/api/apps/List or create apps
GET, PATCH, DELETE/api/apps/{app}/Read, update, or delete an app
GET, POST/api/apps/{app}/endpoints/List or create endpoints
GET, PATCH, DELETE/api/apps/{app}/endpoints/{endpoint}/Manage one endpoint

Collection data

GET, POST/api/apps/{app}/endpoints/{endpoint}/fields/List or add schema fields
PATCH, DELETE/api/apps/{app}/endpoints/{endpoint}/fields/{uuid}/Update or remove a field
GET, POST/api/apps/{app}/endpoints/{endpoint}/records/List or create records
POST/api/apps/{app}/endpoints/{endpoint}/records/batch/Atomically create up to 100 records
GET, PATCH, DELETE/api/apps/{app}/endpoints/{endpoint}/records/{uuid}/Manage one record

Endpoint configuration

GET, PUT/api/apps/{app}/endpoints/{endpoint}/payload/Read or replace a static payload
GET, PUT/api/apps/{app}/endpoints/{endpoint}/proxy/Read or replace proxy configuration
GET, POST, DELETE/api/apps/{app}/endpoints/{endpoint}/encryption/Inspect, enable, or disable encryption
GET/api/apps/{app}/endpoints/{endpoint}/logs/Read the latest 50 request logs
GET, POST/api/apps/{app}/endpoints/{endpoint}/webhooks/List or create webhooks
GET, PATCH, DELETE/api/apps/{app}/endpoints/{endpoint}/webhooks/{uuid}/Manage one webhook
GET, POST/api/apps/{app}/keys/List or create app-associated keys
DELETE/api/apps/{app}/keys/{uuid}/Revoke an app-associated key

Control panels

GET, POST/api/dashboards/List or create control panels
GET, PATCH, DELETE/api/dashboards/{dashboard}/Manage a control panel
GET/api/dashboards/{dashboard}/widgets/List widgets
POST/api/dashboards/{dashboard}/widgets/{app}/{endpoint}/Create a widget with a slug-based binding
PATCH, DELETE/api/dashboards/{dashboard}/widgets/{uuid}/Update or remove a widget
GET/api/dashboards/{dashboard}/state/Read configured widget values
PATCH/api/dashboards/{dashboard}/widgets/{uuid}/value/Write through an interactive widget

Capacity and credentials

GET/api/limits/Read enforced plan limits and remaining capacity
GET/api/auth/context/Inspect the non-secret credential context

Check capacity before provisioning

A platform token can call GET /api/limits/. The response names the current plan, every enforced limit, and remaining global app and dashboard capacity. App, endpoint, and dashboard detail responses also include scoped capacity. Successful creation responses include X-Meow-Quota-* headers.
LimitFreePro
Apps350
Endpoints per app325
Records per endpoint5010,000
Fields per endpoint1050
Dashboards315
Widgets per dashboard1250
Webhooks per endpoint320
App API keys220
Maximum record payload64 KB512 KB
Maximum static payload256 KB1 MB

Atomic batch ingestion

Send one to 100 records in a request. The API applies transforms, size limits, schema validation, and record capacity to the whole batch before writing. If one item fails, none are created and the error identifies its array index. The HTTP request must remain under 1 MB.
terminal
curl -X POST "$MEOW_API/apps/weather-station/endpoints/readings/records/batch/" \
  -H "Authorization: Bearer $MEOW_APP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"records":[
    {"data":{"temperature":21.8}},
    {"data":{"temperature":21.9}}
  ]}'

Static payload envelope and nested key paths

The HTTP management endpoint reads and writes an envelope withdata and read-only updated_at. Dashboard bindings use dot notation. Missing objects are created for static writes, but a non-object intermediate value is rejected.
json
{
  "data": {
    "camera": {
      "thresholds": {"confidence": 0.65}
    }
  },
  "updated_at": "2026-07-25T10:00:00Z"
}

Schema changes after data exists

Labels, required state, defaults, help text, options, and ordering remain editable. A field's machine name and type become immutable after the endpoint has records. Create a replacement field and migrate deliberately instead of changing how stored values are interpreted.

Encryption and errors

Encrypted consumer responses

Without a decryption header, an encrypted endpoint returns a Fernet envelope containing encrypted, algorithm, fingerprint, and data. Send the one-time key as X-Encryption-Key to request a plaintext response. A wrong key returns 403.
400

Invalid input

401

Bad or missing auth

403

Not permitted

404

Resource not found

429

Rate limited

Writes are strict

Unknown top-level fields return 400 and are never discarded. Errors include a stable code, message, details, and request ID. Quota errors also include the resource, plan, limit, usage, remaining capacity, and a remediation hint. API routing and proxy errors under /api/* are JSON.

03 · Python SDK & CLI

Python SDK and CLI

meow-sdk wraps the REST API and installs the meow CLI. It supports Python 3.8 and newer and uses the same resource names as the web app.

Recommended credential: platform token

The SDK and CLI can discover and manage multiple apps, so configure them with a platform token from Account → Platform Tokens. Use an app API key instead only when a client must be confined to one app.

Installation details, complete examples, releases, and package metadata.

Read the meow-sdk docs on PyPI ↗

Install and configure

terminal
pip install meow-sdk


export MEOW_PLATFORM_API_KEY="YOUR_PLATFORM_TOKEN"
export MEOW_APP_API_KEY="YOUR_APP_API_KEY"
export MEOW_USERNAME="YOUR_USERNAME"
# Optional for a self-hosted or local backend:
export MEOW_URL="https://meowmeowscratch.com"
python
import os
from meow_sdk import Meow


api = Meow(
    base_url=os.getenv("MEOW_URL", "https://meowmeowscratch.com"),
    username=os.getenv("MEOW_USERNAME"),
    api_key=os.environ["MEOW_PLATFORM_API_KEY"],
    timeout=30,
)


# Check enforced capacity before provisioning a schema or dashboard.
print(api.limits())

Collection workflow

This reference example explicitly publishes harmless sample data so the following anonymous-read example works. Omitis_public=True to keep both resources private.
weather_station.py
from meow_sdk import Meow
import os


api = Meow(api_key=os.environ["MEOW_PLATFORM_API_KEY"])


api.create_app("Weather Station", "weather-station", is_public=True)
api.create_endpoint(
    "weather-station",
    "Readings",
    "readings",
    endpoint_type="collection",
    is_public=True,
)
api.create_field(
    "weather-station",
    "readings",
    "temperature",
    "Temperature",
    "number",
    required=True,
    options={"min": -50, "max": 80, "step": 0.1},
)


created = api.send(
    "weather-station",
    "readings",
    {"temperature": 22.5},
)
api.send_many(
    "weather-station",
    "readings",
    [{"temperature": 22.6}, {"temperature": 22.7}],
)


page = api.records("weather-station", "readings", limit=25)
api.update(
    "weather-station",
    "readings",
    created["uuid"],
    {"temperature": 23.0},
)
print(page["results"])

Static settings and a remote control

The SDK returns the bare static document, so an empty endpoint is simply {}. Use get_payload_state() when the update timestamp matters. A widget binding names the app and endpoint once; later value changes target only the widget UUID.
device_settings.py
api.create_endpoint(
    "weather-station", "Device Settings", "settings", endpoint_type="static"
)
api.set_payload("weather-station", "settings", {
    "camera": {"thresholds": {"confidence": 0.65}}
})
settings = api.get_payload("weather-station", "settings")


api.create_dashboard("Camera Controls", "camera-controls")
widget = api.create_dashboard_widget(
    "camera-controls",
    "weather-station",
    "settings",
    "camera.thresholds.confidence",
    "slider",
    "Tracking confidence",
    config={"min": 0, "max": 1, "step": 0.05},
)
api.set_dashboard_widget_value("camera-controls", widget["uuid"], 0.7)

Public reads do not need a token

Public reads use the owner username to build the consumer URL. Keep an API key on the client only if the same process also writes, manages resources, or reads a private endpoint.
python
from meow_sdk import Meow


public = Meow(username="YOUR_USERNAME")


readings = public.get(
    "weather-station",
    "readings",
    temperature__gte=20,
    limit=25,
)
stats = public.aggregate(
    "weather-station",
    "readings",
    ["avg", "max"],
    field="temperature",
)
csv_text = public.export_csv("weather-station", "readings")

Client method reference

These method names match the published client. Ellipses omit arguments shown in the examples above.

Public reads

  • get(app, endpoint, **filters)
  • get_record(app, endpoint, record_id)
  • aggregate(app, endpoint, aggregates, field=None)
  • export_csv(app, endpoint, **filters)
  • public_dashboard(share_token)

Apps and endpoints

  • apps() / get_app(slug)
  • create_app(...) / update_app(...) / delete_app(...)
  • endpoints(app) / get_endpoint(app, endpoint)
  • create_endpoint(...) / update_endpoint(...) / delete_endpoint(...)

Collection data

  • records(app, endpoint, limit=25, offset=0)
  • all_records(app, endpoint)
  • send(app, endpoint, data)
  • send_many(app, endpoint, records)
  • update(app, endpoint, record_id, data)
  • delete_record(app, endpoint, record_id)
  • fields(...) / create_field(...) / update_field(...) / delete_field(...)
  • field_types()

Payloads and integrations

  • get_payload(...) / get_payload_state(...) / set_payload(...)
  • get_proxy(...) / set_proxy(...)
  • webhooks(...) / get_webhook(...)
  • create_webhook(...) / update_webhook(...) / delete_webhook(...)
  • get_encryption(...) / enable_encryption(...) / disable_encryption(...)
  • request_logs(app, endpoint)

Control panels

  • dashboards() / get_dashboard(slug)
  • create_dashboard(...) / update_dashboard(...) / delete_dashboard(...)
  • dashboard_widgets(dashboard)
  • create_dashboard_widget(...) / update_dashboard_widget(...) / delete_dashboard_widget(...)
  • dashboard_state(dashboard)
  • set_dashboard_widget_value(dashboard, widget_uuid, value)

Keys and capacity

  • app_keys(app) / create_app_key(app) / delete_app_key(app, uuid)
  • platform_tokens() / create_platform_token(name) / revoke_platform_token(uuid)
  • limits() / auth_context()

Limits are token-safe; billing is session-only

API credentials cannot access authentication, account, or billing subscription endpoints. Use limits() for provisioning and manage checkout or the customer portal in the web app. billing_status() is deprecated.

Exceptions

All SDK exceptions inherit from MeowError and include the HTTP status and response when available. Structured failures also expose code, field, hint, and details without string matching.
python
from meow_sdk.exceptions import (
    AuthError,
    MeowError,
    NotFoundError,
    RateLimitError,
    ValidationError,
)


try:
    api.send("weather-station", "readings", {"temperature": "hot"})
except ValidationError as exc:  # HTTP 400
    print(exc.code, exc.field, exc.hint)
except AuthError:               # HTTP 401 or 403
    print("Check the token and resource access")
except NotFoundError:           # HTTP 404
    print("Check the app and endpoint slugs")
except RateLimitError:          # HTTP 429
    print("Retry with backoff")
except MeowError as exc:
    print(f"Request failed: {exc}")

CLI quick reference

Management commands read MEOW_PLATFORM_API_KEY. Data-plane commands read MEOW_APP_API_KEY. The CLI also reads MEOW_USERNAME and optional MEOW_URL. Commands return JSON.
terminal
meow apps
meow endpoints weather-station
meow fields weather-station readings
meow limits
meow send weather-station readings temperature=22.5
meow send-batch weather-station readings @records.json
meow records weather-station readings --limit 25
meow get weather-station readings temperature__gte=20
meow payload-get weather-station status
meow payload-get weather-station status --metadata
meow logs weather-station readings
meow webhooks weather-station readings
meow dashboards
meow widget-create camera-controls weather-station settings \
  camera.thresholds.confidence slider "Tracking confidence" \
  --config '{"min":0,"max":1,"step":0.05}'
meow widget-set camera-controls WIDGET_UUID 0.7
meow --help

Package documentation

The PyPI project page includes installation, quickstarts, Raspberry Pi examples, CLI usage, error handling, and the method map.

View meow-sdk on PyPI ↗

04 · MCP server

Connect an AI agent with MCP

The MCP server exposes your resources as schema-defined tools for compatible agents, including Codex and Claude Code.

Transport

Streamable HTTP · stateless

Remote endpoint

https://meowmeowscratch.com/mcp/

Authentication

Open Account → Platform tokens, create a token, and store the value. Export it in the shell that launches the MCP client. MCP needs account-wide discovery, so use a platform token rather than an app API key.
terminal
export MEOW_PLATFORM_API_KEY="YOUR_PLATFORM_TOKEN"

Install Meow Agent Tools

The official Agent Tools repository packages the shareduse-meow skill and the hosted MCP connection for Codex and Claude Code. The skill teaches the agent how to choose between the web app, REST API, SDK, CLI, and MCP; design endpoints; work safely with credentials; and build Raspberry Pi or IoT projects.

meowmeowscratch/meow-agent-tools

One shared skill with native plugin and MCP packaging for both supported agent clients. Review the source and release notes before installing updates.

View Agent Tools on GitHub ↗

Codex

terminal
codex plugin marketplace add meowmeowscratch/meow-agent-tools
codex plugin add meow-meow-scratch@meow-agent-tools

Start a new Codex thread after installation. Ask for a Meow Meow Scratch® task naturally, or inspect /mcp if the tools are not available.

Claude Code

terminal
claude plugin marketplace add meowmeowscratch/meow-agent-tools
claude plugin install meow-meow-scratch@meow-agent-tools

Start a new session or run /reload-plugins. Claude Code can select the skill automatically, or you can invoke/meow-meow-scratch:use-meow directly.

The plugin does not contain your token

Both packages read MEOW_PLATFORM_API_KEY from the environment of the process that launches the agent. Keep the token out of repositories, project configuration, prompts, and logs. Agent Tools supports Codex and Claude Code; it is not a Claude.ai or Claude Desktop connector.

Configure Codex manually

Use this setup when you want the MCP tools without installing the Agent Tools skill. Codex CLI and the Codex IDE extension share MCP configuration on the same host. This command stores the environment-variable name rather than the token.
terminal
codex mcp add meow \
  --url https://meowmeowscratch.com/mcp/ \
  --bearer-token-env-var MEOW_PLATFORM_API_KEY


codex mcp list

The equivalent user configuration is:

~/.codex/config.toml
[mcp_servers.meow]
url = "https://meowmeowscratch.com/mcp/"
bearer_token_env_var = "MEOW_PLATFORM_API_KEY"

Restart Codex or the IDE extension after editing the file. Run/mcp to verify the connection. For a project-specific setup, put the same table in .codex/config.toml; Codex loads it only for trusted projects. See the official Codex MCP guide ↗.

Configure Claude Code manually

Use this setup when you want the MCP tools without installing the Agent Tools skill. Put the server in the project's .mcp.json. Claude Code expands MEOW_PLATFORM_API_KEY from the local environment, so the configuration can be committed safely.
.mcp.json
{
  "mcpServers": {
    "meow": {
      "type": "http",
      "url": "https://meowmeowscratch.com/mcp/",
      "headers": {
        "Authorization": "Bearer ${MEOW_PLATFORM_API_KEY}"
      }
    }
  }
}
terminal
export MEOW_PLATFORM_API_KEY="YOUR_PLATFORM_TOKEN"
claude mcp list
claude

The type field is required and may behttp or streamable-http. Approve the server when Claude Code first opens the project, then run /mcp to verify the connection. See the official Claude Code MCP guide ↗.

Claude web and Desktop connectors

The MCP server uses a Bearer header. Claude's account-level connector flow documents OAuth but not fixed custom headers, so use Claude Code for this integration. Do not include the token in the URL.

Connection checks

Missing authentication returns 401. Keep the trailing slash on/mcp/ to avoid a redirect. If tools are unavailable, verify MEOW_PLATFORM_API_KEY, restart the client, and inspect /mcp. Once tools load, call connection_status to confirm that the MCP Authorization header contains a platform token and to inspect its scopes without exposing the token.

Available tool families

Agents should discover before acting: list apps and endpoints, inspect schemas and capacity, then use returned slugs. Widget creation binds by app and endpoint slug; value updates use the widget UUID and do not repeat an endpoint identifier or key path.

Structure

Discover, create, update, and delete apps and endpoints.

Collections

Define fields and create, batch, update, or delete validated records.

Endpoint behavior

Configure static payloads, proxies, encryption, webhooks, and inspect request logs.

Control panels

Create slug-bound widgets, read only configured state, and write through widget UUIDs.

Consumer reads

Read public endpoints and records, aggregate values, export CSV, and open shared dashboards.

Discovery

Check the connection, enforced limits, field types, and resources before making changes.

Recommended tool workflow

  1. 01Call connection_status, then get_limits before provisioning.
  2. 02List apps and endpoints before making changes.
  3. 03Inspect the endpoint and field schema before writing data.
  4. 04Require confirmation before destructive operations.
  5. 05Call the narrowest applicable tool and read the resource back to verify the result.
  6. 06Return the consumer URL and relevant resource identifiers.

Limits and safety

60 tool calls per minute

The MCP service allows 60 tool calls per token each minute. Avoid polling unchanged resources.

Destructive calls need an approval policy

MCP does not enforce a server-side human approval gate. Require client approval for deletes, key revocation, encryption changes, and other sensitive writes.

Account routes stay out of scope

API credentials cannot access authentication, profile, or billing subscription routes. The dedicated get_limits tool is safe for platform-token provisioning; manage checkout and the billing portal in the web app. Do not expose tokens in prompts, repositories, browser bundles, or logs.

05 · Open source

Example projects

These projects demonstrate API concepts, Raspberry Pi hardware, IoT data collection, and control panels using the Python SDK.

GitHub

meowmeowscratch

SDK source, Raspberry Pi projects, classroom examples, issues, and releases.

View all projects ↗

Ship safely

Production checklist

Verify credentials, visibility, retries, and agent approval policy before exposing an endpoint to production traffic.
  • Keep platform tokens and app API keys in a secret manager or environment variable and rotate them after suspected exposure.
  • Prefer an app API key with the minimum Read and Write scopes for each device or single-app integration.
  • Use public visibility only for data that is genuinely safe for anonymous internet access.
  • Preserve trailing slashes on REST and MCP URLs to avoid redirects during writes and protocol negotiation.
  • Apply timeouts and exponential backoff for 429 and transient 5xx responses; do not retry validation failures.
  • Store API and encryption keys when they are created; full values are shown once.
  • Treat shared control-panel links as bearer secrets and expire or disable sharing when it is no longer needed.
  • Verify proxy targets and transformations with non-sensitive data before enabling a public integration.
  • Require explicit human confirmation before an agent deletes apps, endpoints, records, keys, or dashboards.