@phosra/mcp package turns the Phosra API into Model Context Protocol tools. Point Claude Desktop, Cursor, or any MCP-compatible client at it and your agent can read a family’s Brief, audit enforcement decisions, and apply age-appropriate policy — through natural conversation, over a signed, per-family token.
Everything on this page is verified against the published package
@phosra/mcp@0.4.0 (npm), run end-to-end against the hosted sandbox https://phosra-api-sandbox-production.up.railway.app/api/v1. The binary is phosra-mcp; a live tools/list returns 79 tools. Every JSON response below is real, unedited server output.How it works
Authorization: Bearer phomcp_…; the API resolves it to your user and family, so the agent only ever sees your own data.
Step 1 — Get an MCP token
MCP tokens are scoped to a single family and start with the prefixphomcp_. They are hashed at rest (SHA-256) and shown in plaintext exactly once, at creation.
- Dashboard (recommended)
- API
- Open Dashboard → Keys & Auth → MCP Tokens (“Connect Phosra to your AI agent”).
- Enter a label (e.g.
Claude Desktop) and click Generate. - Copy the token immediately — it is displayed once and never shown again.
Step 2 — Install
Run directly withnpx (no install), pointing at the hosted sandbox while you build:
--api-key and --api-url flags also read from PHOSRA_API_KEY and PHOSRA_API_URL. When --api-url is omitted the server targets production (https://prodapi.phosra.com/api/v1).
Sandbox first. The hosted sandbox is seeded, resettable, and safe to write to — every example on this page runs against it. Switch to production only once your flow works end-to-end.
Step 3 — Configure your client
- Claude Desktop
- Cursor
- Any MCP client
Add to The config file lives at:
claude_desktop_config.json, then fully quit and reopen Claude Desktop:- macOS —
~/Library/Application Support/Claude/claude_desktop_config.json - Windows —
%APPDATA%\Claude\claude_desktop_config.json
Step 4 — Verify the connection
You don’t need a full client to smoke-test the server — pipe a JSON-RPC handshake over stdio. Against the hosted sandbox this returns the live tool list:How a tool call maps to HTTP
Every tool is a thin wrapper over one REST endpoint. The server (tools.ts → resolveToolPath) routes your arguments in a fixed, predictable way:
- Path parameters — any argument whose name matches a
{param}in the endpoint path (e.g.policy_idin/policies/{policy_id}/rules) is substituted into the URL. - Query string — on a
GETtool, every remaining argument becomes a?key=valuepair. - JSON body — on a
POST/PUT/DELETEtool, every remaining argument becomes a top-level field of the request body.
create_rule with {policy_id, category, enabled, config} sends POST /policies/{policy_id}/rules with a body of {category, enabled, config} — policy_id never appears in the body. You never construct URLs yourself; you pass flat named arguments and the server does the rest.
Reading the field reference
Every tool below lists its complete argument set with type and whether it is required:boldtype— required (the API rejects the call without it).plaintype· opt — optional.
arguments object. Types are the JSON Schema types declared in the shipped @phosra/mcp@0.4.0 source — the same schemas your MCP client sees in tools/list. Nested object shapes (create_rule.config, connect_platform.credentials, consult_advisor.context) are documented in Nested payload shapes below.
Tool reference
All 79 tools, grouped by domain. Each row links to the matching API reference page where one exists — that page documents the full response body, every field, and every status code for the underlying endpoint.Account & quick setup
quick_setup is the one-call onboarding path: it creates a family, adds a child, generates age-appropriate rules, and activates the policy. strictness is recommended (default), strict, or relaxed. Pass family_id to add the child to an existing family instead of minting a new one.
Families & members
Children
Policies
Rules
Platforms & compliance links
Enforcement
trigger_enforcement.platform_ids narrows the fan-out to a subset (e.g. ["netflix", "youtube"]); omit it and enforcement pushes to all connected platforms. Valid IDs: netflix, paramount_plus, youtube_tv, peacock, prime_video, youtube, nextdns, android, fire_tablet, apple_watch, fire_tv_stick.
Ratings
Webhooks
Sources (parental-control app adapters)
Sources are the parental-control-app adapters (Bark, Qustodio, Kidslox, …). On the sandbox they are
api_tier: guided, auth_type: none — connect them without credentials and drive setup through get_source_guided_steps. Managed sources that need credentials accept a credentials object on connect_source.Brief (what changed in child-safety)
apply_brief_item is the autonomous-loop write: it applies a Brief item’s proposed policy diff (only on items whose recommended_action.kind == "policy_diff"). Preview it first with dry_run_apply (below).
Decisions & provenance
query_decisions_by_law answers “show me everything we did because of KOSA” — pass law_id as a lowercase registry slug like kosa, coppa-2, or ca-sb-976.
Safe autonomy (preview, snapshot, revert)
snapshot_policy before any bulk autonomous change; revert_to_snapshot atomically restores the captured policy graph if a change turns out wrong.
Streaming (Server-Sent Events)
Each returns a
stream_url the agent connects to (with the same Bearer token) to replace a polling loop.
Federation (advisor agents)
register_advisor_agent has two conditionally required fields (marked · opt* above): scope_family_id is required when scope="family", and manifest_url is required when scope="global". consult_advisor calls a registered third-party advisor with an RFC 9421 Ed25519-signed request and writes an immutable audit row; list_advisor_audit_log returns those rows with preserved response signatures for non-repudiation.Nested payload shapes
Four tool arguments are typedobject / array<object> in the schema — the schema deliberately leaves them open because their shape depends on the rule category, platform, or capability. Here are the real, sandbox-verified shapes.
create_rule / bulk_upsert_rules config
config is a category-specific JSON object. create_rule.category must be one of Phosra’s supported rule categories — the shipped tool description names 45, and the canonical, per-category list is enumerated in the Create rule API reference. The table below is the real config emitted by quick_setup (captured live from list_rules against the sandbox) for the 20 categories in the recommended set — copy these shapes directly into create_rule:
A single
create_rule call, exactly as the agent sends it over tools/call:
bulk_upsert_rules takes the same objects in an array under rules:
connect_platform credentials
Platforms advertise how they authenticate via list_platforms (auth_type is api_key, oauth2, or manual). The DNS providers (nextdns, controld, cleanbrowsing) are api_key; android and microsoft are oauth2; streaming/gaming platforms are manual.
consult_advisor context
context is a free-form JSON object whose keys are defined by the advisor’s declared capability — e.g. for a homework_focus capability:
context is passed straight through; Phosra never inspects it.
Enumerated argument values
Three arguments are typed as an openstring / array<string> in the shipped schema but only accept a fixed set of values. Here is the full, source-verified enumeration for each.
create_webhook events
events is an array<string>. The schema does not constrain the members, but the census fires exactly five events today — subscribe only to these:
list_platforms_by_capability capability
capability is a single string. It must be one of the 18 capability identifiers defined in the census (internal/provider/adapter.go). An unknown capability is not an error — the endpoint returns a JSON null (empty match), so validate against this list client-side:
capabilities array is on every element of list_platforms and get_platform, so you can also filter client-side without a round-trip.
Tool results & the error format
This is the part most MCP integrations get wrong, so it is worth stating precisely. Each tool runs its HTTP request and returns the API’s JSON response as the content of a successfultools/call result. The Phosra MCP server (server.ts) sets the result’s isError flag from the HTTP status — it does not raise a JSON-RPC protocol error. A 403 or 404 therefore arrives inside a normal result, not as a transport-level failure your client would throw on:
isError (or parse content[0].text and read code) — never assume a tool “threw.”
The error envelope
Every Phosra error body is the same shape (frompkg/httputil in the census). The three base fields are always present:
Rule-plane and OCSS Trust-Framework endpoints add two more fields on a governance rejection:
Real error bodies (captured from the live sandbox)
These are unedited responses fromhttps://phosra-api-sandbox-production.up.railway.app/api/v1:
403 standing_failure — emitted by rule-plane writes and by trigger_enforcement when the authority-holder’s §6.2 standing does not back the binding — carries the extra class + failed_step fields:
End-to-end worked example
This is a real, unedited round-trip against the hosted sandbox. Set up a child in one call, then read back the generated rules — chaining the returned IDs, exactly as an agent would.1. Provision a child with quick_setup
tools/call result content (real server output, trimmed to the head):
2. Read the generated rules with list_rules
Feed the returned policy.id straight into the next tool:
addictive_design_control, age_gate, algo_feed_control, content_rating, data_deletion_request, dm_restriction, geolocation_opt_in, monitoring_activity, notification_curfew, privacy_account_creation, privacy_profile_visibility, purchase_approval, purchase_block_iap, social_chat_control, targeted_ad_block, time_daily_limit, time_scheduled_hours, usage_timer_notification, web_filter_level, and web_safesearch.
What it looks like in a real conversation
Once the server is wired into your client, this happens in plain language.Setting up a new child
You: Set up parental controls for my 8-year-old, Maya, born June 15 2017.
Claude: (calls quick_setup) Done — Maya now has an active protection policy with 20 age-appropriate rules: addictive-design controls off, a 13+ age gate, content ratings, a daily time limit, scheduled hours, and safe-search enforced. Want me to connect a device or DNS filter to enforce these?
Adjusting a rule
You: Her teacher needs her to reach youtube.com for homework. Allow it. Claude: (callslist_rules, thenupdate_ruleon the web-filter rule) Addedyoutube.comto Maya’s allowlist. Every other web filter stays in place.
A safe autonomous change
You: A new state law just dropped in my Brief — handle it, but let me undo it if I disagree. Claude: (callssnapshot_policy, thendry_run_apply) Snapshotpre-sb976saved. The dry run would add 2 rule categories across 1 policy, nothing removed. (callsapply_brief_item) Applied. If you want it reverted, just say so and I’llrevert_to_snapshot.
Security & token lifecycle
- Family-scoped. A token authorizes exactly one family. It cannot see or touch another family’s data.
- Hashed at rest. Only the SHA-256 hash and an 8-character prefix are stored. Phosra cannot show you a token again after creation.
- Revocable instantly. Revoking from the dashboard or
DELETE /mcp-tokens/{id}takes effect on the agent’s next call. - Auditable.
last_used_atupdates on every authenticated call, and autonomous writes land in the Decisions provenance log — review them withlist_unreviewed_agent_decisions. - Local execution. The server runs on your machine as a client subprocess; your token never leaves your environment except as a
Bearerheader to the Phosra API over HTTPS.
Troubleshooting
Next steps
- Authentication — how Bearer tokens and sessions work across the API.
- Create / list / revoke MCP tokens — the control-plane endpoints behind the dashboard.
- Quickstart — the same sandbox, driven by curl and the SDKs.