Skip to main content

merofoundry-mcp

A remote MCP server (Streamable HTTP transport) that exposes 39 task tools over the MeroFoundry platform API via the shared merofoundry-client library. MeroFoundry is the platform for building entire websites.

Tools

Data plane — writes (5 tools)

Tool Description
describe_schema List models and their fields for an application
query_records Query records with optional filters and pagination
upsert_record Create or update a record (idempotency via record_id)
delete_record Delete a record by ID
run_rule_event Trigger a rule event for an application

Authoring — Plan 2 (17 tools)

Authoring tools require an API key with the appropriate authoring permissions (applications, models, fields, forms, or rules create/update/delete, and models:publish).

Authoring keys carry a larger blast radius than data-plane keys (full CRUD including delete). Treat them accordingly.

Primitives (15)

Tool Description
create_application Create a new application
update_application Update an application's metadata
delete_application Archive/delete an application (destructive)
define_model Create a data model (table). Records require a PUBLISHED model — call publish_model after adding fields, or use scaffold_model
update_model Update a model's metadata
delete_model Delete a model and all its records (destructive)
publish_model Publish a model's schema so records can be created/queried. Required after creating or changing fields
add_field Add a field to a model. Adding a field reverts the model to draft — re-publish before records work
update_field Update a field's metadata
delete_field Delete a field from a model (destructive)
define_form Create a form, optionally bound to a model
update_form Update a form's metadata or layout
delete_form Delete a form (destructive)
define_rule Create a business rule
test_rule Dry-run a rule without persisting

Reads (8 tools)

Single-item and search reads, plus the file surface.

Tool Description
get_application Fetch one application's metadata
get_model Fetch one model and its fields
get_record Fetch one record by ID
search_records Full-text search across a model's records
upload_file Upload a file to an application
get_file Fetch a file's metadata and a short-lived download URL
download_file Download a file's contents
delete_file Delete a file (destructive)

Pages (6 tools)

Tool Description
create_page Create a page
list_pages List an application's pages
get_page Fetch one page, including its layout
update_page Update a page's metadata or layout
delete_page Delete a page (destructive)
render_page Render a page's layout with composites expanded and style resolved

Queries, services and governance (3 tools)

Tool Description
run_saved_query Execute a saved query and return its rows
invoke_service Invoke a configured outbound service
set_outbound_governance Set an application's outbound-call governance policy

Composites (2)

These tools bundle multiple primitive steps into a single call for the common-case paths.

Tool Description
scaffold_model Fast path: create a model, add all its fields, and publish it in one call. fields is a list of {name, label?, type, required?, unique?, default_value?, settings?}. Returns {model_id, field_ids, published}
create_form_simple Simple mode: from a field spec, scaffold a model (create + fields + publish) and create a model-bound form in simple mode — one call. Returns {model_id, form_id, field_ids}

Publish requirement. Records require a published model. Creating a model leaves it in draft; publish_model promotes it. Adding a field after publish reverts the model to draft, requiring another publish_model. The composites handle this automatically — primitives require an explicit publish_model call.

Simple mode is an MCP-layer composite. create_form_simple is implemented entirely in the MCP server; it calls the backend primitives in sequence. The backend does not auto-generate models from forms — mode is metadata on the form. There is no magic on the server side.

Composite partial-failure. scaffold_model and create_form_simple are not transactional. If a later step fails (e.g. a field creation error), an earlier-created model may already exist in the backend, possibly in an unpublished state. The caller may need to clean up manually (e.g. delete_model) before retrying.

create_application and provisioning. create_application creates an application record, but a newly created application will not have its own API key. Key minting still requires the JWT route; it is out of scope for an app-scoped API key. provision_tenant (full control-plane onboarding) is also out of scope.

Authentication

The caller (MCP client) passes auth on every request as either:

  • Authorization: Bearer <api_key>
  • X-API-Key: <api_key>

There is no tenant header. Auth is API-key only.

Run the server

MEROFOUNDRY_SERVER_ROOT=http://localhost:8000 \
  uvicorn --factory merofoundry_mcp.server:build_app --port 9000

MEROFOUNDRY_SERVER_ROOT defaults to http://localhost:8000 if unset.

Install / dev

python -m venv .venv
source .venv/bin/activate
uv pip install -e ../merofoundry-client
uv pip install -e ".[dev]"

Run tests:

.venv/bin/python -m pytest

Eval setup — cross-model matrix

The evals/ directory contains a harness, Anthropic and OpenAI-compatible adapters, eval tasks, and a matrix runner (run_evals.py) that tests tool-use competence across models.

Prerequisites

Step 1 — Run meroweb-omo locally. The /api/v1/public routes must be the hardened version (idempotency, agent-readable errors, camelCase operationIds). This is already on its main branch.

Step 2 — Seed a sandbox application and model. Create an application and a model with at least these text fields: name, email, company.

Step 3 — Mint an API key scoped to that app with permissions:

For data-plane tasks only:

app:read,models:read,records:read,records:create,records:update,records:delete,rules:execute

For the build_app_end_to_end authoring task (Plan 2), additionally include authoring permissions:

applications:create,applications:update,models:create,models:update,models:delete,models:publish,fields:create,fields:update,fields:delete,forms:create,forms:update,forms:delete,rules:create

Step 4 — (For local models) install Ollama and pull models, or start a llama.cpp server:

ollama pull llama3.1:8b qwen2.5:7b

For llama.cpp, start llama-server with tool-call support (the --jinja flag enables the model's own chat template to handle tools; required for some models):

llama-server --jinja -m <model-file> --port 11435

Step 5 — (For the codex adapter) start the MCP server and ensure a seeded app + API key. The codex adapter drives the live MCP server directly (see Codex adapter below). The server must be running and the API key must be scoped to the seeded app.

Step 6 — Run the matrix.

Frontier model (Anthropic):

python -m evals.run_evals \
  --app <APP_ID> --model <MODEL_ID> --api-key <SK> \
  --adapter anthropic --model-name claude-opus-4-8

Local model (Ollama):

python -m evals.run_evals \
  --app <APP_ID> --model <MODEL_ID> --api-key <SK> \
  --adapter ollama --model-name llama3.1:8b \
  --base-url http://localhost:11434/v1

Remote llama.cpp server (OpenAI-compatible endpoint):

python -m evals.run_evals \
  --app <APP_ID> --model <MODEL_ID> --api-key <SK> \
  --adapter llamacpp --model-name qwen3.5-122b-a10b
  # default --base-url http://192.168.125.220:11435/v1; override with --base-url as needed

Codex external agent (drives the live MCP server):

python -m evals.run_evals \
  --adapter codex \
  --mcp-url http://localhost:9000/mcp \
  --app <APP_ID> --model <MODEL_ID> --api-key <SK>

Step 7 — Read the scorecard. The runner prints a per-task, per-model success rate: success=N/3 (default 3 runs per task).

Honest scope note

The full cross-model scorecard (tasks creating and querying real records) requires a running meroweb-omo instance with a seeded app and a scoped API key. What is verified today: llama.cpp tool-calling (qwen3.5-122b-a10b on the default server emits tool calls correctly) and codex connectivity (v0.140.0 connected and discovered all 5 tools at the time of Plan 1). The full scorecard — including the Plan 2 build_app_end_to_end authoring task — requires a live seeded sandbox and an authoring-scoped API key, and has not yet been run.

llama.cpp adapter

--adapter llamacpp treats the llama.cpp server as an OpenAI-compatible endpoint. The default base URL is http://192.168.125.220:11435/v1; override with --base-url. The model name (--model-name) is passed as-is to the API.

If a model/server does not emit tool calls, ensure llama-server was started with --jinja so the model's own chat template handles tool formatting.

Codex adapter — external agent (deepest dogfood)

--adapter codex is the highest-fidelity eval path: codex acts as the MCP client and drives the live MCP server end-to-end, exercising the full HTTP transport and auth flow. The eval runner injects the MCP server URL into each codex invocation per-run (no mutation of global codex config).

The runner sets -c sandbox_workspace_write.network_access=true so codex's sandbox can reach the local MCP server. (Note: the codex config key is sandbox_workspace_write.network_access, not sandbox_permissions; the latter is rejected by codex.)

Interactive use (not just evals). You can also register the server with codex for ad-hoc use:

codex mcp add merofoundry \
  --url http://localhost:9000/mcp \
  --bearer-token-env-var MEROFOUNDRY_API_KEY
export MEROFOUNDRY_API_KEY=<your MeroFoundry platform API key>

codex sends Authorization: Bearer <key> on every MCP request. Verified with codex 0.140.0: all 5 data-plane tools (describe_schema, query_records, upsert_record, delete_record, run_rule_event) are discovered. The 17 authoring tools (Plan 2) follow the same transport and auth flow.

Release gate — small-model legibility check

The small-model success rate is the design-legibility gate.

If a small local model (e.g. llama3.1:8b or qwen2.5:7b) cannot complete create_then_query_contacts, treat it as a signal to improve the tool descriptions or error messages before shipping — not just as model weakness.

The create_then_query_contacts task is the primary gate for data-plane tools: it requires the model to call describe_schema, create three records via upsert_record, and then query them.

The build_app_end_to_end task (added in Plan 2) is the authoring acceptance gate: the model must create a data model with fields, publish it, insert records, and query them — using scaffold_model where available. It requires an authoring-scoped API key and a live backend. If small models fail this task consistently, the authoring tool descriptions need work.

DNS-rebinding host allowlist

FastMCP enables host-header validation by default for localhost-bound servers (127.0.0.1, localhost, ::1). It accepts only Host values matching 127.0.0.1:*, localhost:*, or [::1]:* (port required).

When running behind a reverse proxy or with a real hostname, connections will receive 421 Misdirected Request unless you either:

  • Configure a transport_security allowlist that includes your proxy's Host header value, or
  • Disable the check with TransportSecuritySettings(enable_dns_rebinding_protection=False).

For test clients (e.g. Starlette TestClient, httpx), send Host: localhost:80 to satisfy the wildcard check.

For the codex eval adapter and interactive codex use, always connect via http://localhost:9000/mcp or http://127.0.0.1:9000/mcp. Using a real hostname or proxy address will produce 421 Invalid Host until that host is added to the allowlist.

Optional live contract check

Verifies the hardened /api/v1/public OpenAPI has the expected camelCase operationIds. Skipped when MERO_OPENAPI_URL is not set.

MERO_OPENAPI_URL=http://localhost:8000/api/openapi.json \
  .venv/bin/python -m pytest tests/test_baas_contract.py

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

merofoundry_mcp-0.1.0.tar.gz (98.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

merofoundry_mcp-0.1.0-py3-none-any.whl (24.2 kB view details)

Uploaded Python 3

File details

Details for the file merofoundry_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: merofoundry_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 98.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for merofoundry_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 00727cab6fef2e4158126ec7ba39684a932a93eca997857c3b7b5338147becd6
MD5 f4c64dc5f74d21b9208f789fc290be07
BLAKE2b-256 e15743d4258b2d1112586e6463ca503ed472e808e2b9b85080c7b1fb10d6b981

See more details on using hashes here.

File details

Details for the file merofoundry_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: merofoundry_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 24.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for merofoundry_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dd1c44e35af8aad5f120228a5d1a170ec703094f29db7f17a5c6486a74e27164
MD5 afebc5badc5912540098e00aa02acbc5
BLAKE2b-256 d077e31cae155b24ca1929e912125f92d3bdc4599d048f34aa9d47d11e1c972d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page