blankstate-mcp
Protocol-based sensing and validation for autonomous AI agents.
PyPI: [blankstate-mcp](https://pypi.org/project/blankstate-mcp/) · import package: blankstate_mcp
The Blankstate MCP Server exposes Blankstate measurement, Programmatic Dive, and Stage / World authoring as MCP tools.
It lets any MCP-compatible agent (Cursor, Claude Desktop, and others) sense interactions against
Blankstate Protocols, validate actions before executing them, run a Stage dive
(open → act → status → close), author a Stage, run and read its Worlds, and check quota status.
Protocols are universal sensors — the same protocol measures any content modality: conversations, commands, documents, agent actions. The measurement engine determines signal, not the input type.
Features
- Twenty-three MCP tools
- Sense:
bks_sense,bks_validate,bks_status - Dive:
bks_dive_open,bks_dive_act,bks_dive_status,bks_dive_close - Stages:
bks_stage_list,bks_stage_create,bks_stage_get,bks_stage_edit,bks_stage_check,bks_stage_estimate,bks_stage_run,bks_stage_versions,bks_stage_restore,bks_stage_variant - Worlds:
bks_world_list,bks_world_get,bks_world_set,bks_world_review,bks_world_rename,bks_world_delete
- Sense:
- Token-only boot:
python -m blankstate_mcpwith onlyBLANKSTATE_API_TOKEN— Dive tools work without protocols - Optional Stage default: Atlas copies
BLANKSTATE_STAGE_IDinto MCP env.bks_dive_openuses it when you omitstage_id - Protocol and Metric support: Sense against a single Protocol or a Metric that aggregates multiple Protocols with weights
- SGM 1.0 and 1.5: Full output for both engine versions (resonance, evidence, and extended analysis in v1.5)
- Three modes:
block(reject action),feedback(allow + suggest),audit(log only) - Drop-in integration: Works with any MCP-compatible agent
Quick Start
1. Get an API Token
Sign up at atlas.blankstate.ai and generate an API token. Find your Protocol ID at API Dashboard → Explorer → /protocols.
2. Install the server
Use a virtual environment or pipx so dependencies stay isolated:
pipx install blankstate-mcp
# or: python3 -m pip install blankstate-mcp
3. Add to Your Agent Configuration
Point the MCP host at the same Python you installed into. Two common patterns:
Option A — run as a module (python3 must have blankstate-mcp installed):
{
"mcpServers": {
"blankstate": {
"command": "python3",
"args": ["-m", "blankstate_mcp"],
"env": {
"BLANKSTATE_API_TOKEN": "your-token-here",
"BLANKSTATE_STAGE_ID": "stg_xxxxxxxx", // optional — default for bks_dive_open
"BLANKSTATE_PROTOCOLS": "proto-xxxxxxxx-...:1.0" // optional — only for bks_sense / bks_validate
}
}
}
}
Option B — console script (after pipx install blankstate-mcp, the blankstate-mcp executable is on PATH):
{
"mcpServers": {
"blankstate": {
"command": "blankstate-mcp",
"args": [],
"env": {
"BLANKSTATE_API_TOKEN": "your-token-here",
"BLANKSTATE_STAGE_ID": "stg_xxxxxxxx", // optional — default for bks_dive_open
"BLANKSTATE_PROTOCOLS": "proto-xxxxxxxx-...:1.0" // optional — only for bks_sense / bks_validate
}
}
}
}
Windows: Use "command": "python" or the full path to python.exe, or the launcher, e.g. "command": "py" with "args": ["-3", "-m", "blankstate_mcp"], depending on how Python is installed. If the host cannot find the interpreter, set command to the absolute path returned by where python (cmd) or Get-Command python (PowerShell).
Important: Use the actual Protocol UUID from Atlas (e.g.
proto-6d28a7b8-...:0.1), not a friendly name. Find yours at Atlas → API Dashboard → Explorer →/protocols. Token is required. Protocol and Stage id are optional. Stage can work without protocol UUIDs.
4. Done
Your agent now has the twenty-three tools listed below. Dive works with the token alone. If Atlas filled in BLANKSTATE_STAGE_ID, bks_dive_open can run without passing stage_id. Stage writes need stages:read and stages:write; estimating, starting, pausing, and carrying on a World needs runs:dry.
MCP Tools
Once connected, your agent has these tools:
bks_sense
Measure any content against a Protocol or Metric. Returns a resonance score, per-metamarker breakdown, glass-box evidence, and fidelity assessment.
Input: content (required), protocol_id?, metric_id?, language?
Protocols are universal — they measure conversations, commands, documents, and agent actions the same way. v1.5 protocols provide extended signal analysis output.
When metric_id is provided, all component protocols are evaluated and scores are
aggregated by weight into a single composite score.
bks_validate
Validate a proposed agent action (before executing it) against all configured Protocols and Metrics. The action arguments are content-extracted and evaluated.
Input: tool_name (required), tool_args (required)
Returns ALLOWED, BLOCKED (with evidence and matched nuances), or FEEDBACK
depending on the configured mode. In block mode a blocked action is returned as
an MCP error, stopping the agent from proceeding.
bks_status
Check API connectivity, authentication, remaining ICS credits, and the full list of configured Protocols and Metrics.
Input: (none)
bks_dive_open
Open a Programmatic Dive against a published Stage (POST /api/v1/dive/open).
Returns dive_id, rules, the opening observation, and envelope.
Input: stage_id?, session_id?, password?, agent?, seed?
stage_id is optional when BLANKSTATE_STAGE_ID is set in MCP env. A tool argument still wins over the env default.
agent is { id?, version? } — your audit tag, not Blankstate's model.
bks_dive_act
Submit one action. turn is an idempotency key. Returns the next observation and
running totals, or a StageCard if the dive auto-closes.
Input: dive_id (required), action (required string or DiveAction), turn?
bks_dive_status
Inspect an open or closed Dive without advancing the world.
Input: dive_id (required)
bks_dive_close
Close the Dive and emit the StageCard (POST /api/v1/dive/{dive_id}/close).
Idempotent: closing an already-closed dive returns the same card.
Input: dive_id (required), summary?
Stage id is not baked into the package. Pass it on bks_dive_open, or set
BLANKSTATE_STAGE_ID (Atlas MCP snippet) as the default. Use a Stage your token
is entitled to dive (stg_… from Atlas).
Stage tools
Stage a situation from your agent. A Stage is the situation you author and version; a World is one run of it.
Stages are staged as Proxy Worlds (world: "proxy", dived by agents). Creating and editing are free.
Writes are applied whole or refused whole: a refusal names each item and why (issues), and an edit on an
old rev is refused with the current rev. The token needs stages:read, stages:write to create or edit, and
runs:dry to estimate, start, pause and carry on Worlds.
A World started here is the World Atlas runs and lists. It follows the Stage's run plan and this run's options, and counts in its unit
(days, or turns of a conversation, with the interactions so far): it goes on until the Stage's own stop, this run's budget, day or time, your
organisation's ICS runs out, or you pause or stop it. A World at the end of its history can be made longer with run.history (that keeps the version) and then carried on.
Opening it in Atlas carries it on in the page. What a token may spend is the ICS cap set on its
connection in Atlas, and a daily allowance; each token may also start a set number of Worlds a day (refused with
daily_cap past it, until midnight UTC).
| Tool | Input | Does |
|---|---|---|
bks_stage_list |
none | Your Stages: id, title, world, rev, Worlds run. Free |
bks_stage_create |
world ("proxy"), premise, scale?, ops? |
A Stage from a premise, with typed operations in the same call. Applied whole or refused whole. Returns id, rev 1, and the outline. Free |
bks_stage_get |
stage_id |
The outline: actants, links, principles, Moments, objectives and targets, protocols, locks, drawn agents, surfaces and their mix, rev |
bks_stage_edit |
stage_id, if_rev, ops |
Typed operations against the rev you read. An objective can be read on the seeded agents (cases), as a share (rate_*), or on the World's events (reach_*, count_*). run.history makes the history longer and keeps the version. An edit on an old rev is refused with the current rev |
bks_stage_check |
stage_id |
What is thin, each with a question, and the gaps. Free |
bks_stage_estimate |
stage_id, span, seed? |
What span days (or turns) of a World ask on a seed: interactions written, how many are already kept, agents, time (minutes, minutes_max), the ICS range, contrast pairs (pair_passages), and what each objective read on events would count (expect). Free |
bks_stage_run |
stage_id, wait_seconds?, seed?, budget_ics?, until_day?, minutes?, pauses?, target? |
Start a World. seed repeats a draw on the same version. Run options pause it by budget, day, time, or a reached objective. Waits up to wait_seconds, then returns where it is. Spends ICS as it runs |
bks_world_set |
stage_id, world_id, state (running | paused | stopped), plus the same run options when state is running |
Pause, stop, or carry on a World. Carrying on is refused at the end of its history until run.history makes that history longer |
bks_world_list |
stage_id |
The Stage's Worlds, newest first: version, status, the day each is on, who writes it while it runs, and how many objectives it met. Free |
bks_world_get |
stage_id, world_id, trajectories? |
One World's status and outcome: objectives, spread over other seeds, levers, proposals, ICS, and next_steps once paused or stopped. trajectories: true adds each protocol's trajectory evidence. Free |
bks_world_review |
stage_id, world_id, keep?, discard? |
Keep or discard what a World proposes, by id. A discard holds for that World only. Free |
bks_world_rename |
stage_id, world_id, name |
Rename a World (at most 80 characters). Free |
bks_world_delete |
stage_id, world_id |
Delete a World. One still running stops first. Free |
bks_stage_versions |
stage_id, from?, to? |
Kept versions, and what changed between two. Free |
bks_stage_restore |
stage_id, if_rev, version |
Make a kept version the Stage again, against the rev you read |
bks_stage_variant |
stage_id, world_id, label, varies, question? |
A Variant Stage that varies system, population, environment, and/or clock, and holds the rest |
Every tool declares a title, whether it is read-only or destructive, and an outputSchema; its answer comes as
structuredContent next to the text. The server also sends instructions and the ready-made prompts
build_stage, run_world, read_world, and improve_stage for the tools it offers.
Installation
Install from PyPI (recommended: pipx for a global CLI isolated from system Python):
pipx install blankstate-mcp
Other options:
python3 -m pip install blankstate-mcp
# editable from the blankstate-py monorepo:
# python3 -m pip install -e "./packages/sdk" -e "./packages/mcp"
The MCP config must use the same python3 (or the blankstate-mcp script from that environment) that has the package installed.
Configuration
Environment Variables
| Variable | Description | Default |
|---|---|---|
BLANKSTATE_API_TOKEN |
Required. Bearer token from Atlas | |
BLANKSTATE_STAGE_ID |
Optional. Default Stage for bks_dive_open (Atlas MCP tab) |
|
BLANKSTATE_API_URL |
Optional. Do not set this unless you need a custom host (local/dev). | https://api.blankstate.ai |
BLANKSTATE_PROTOCOLS |
Optional. Comma separated Protocol IDs (sense / validate) | |
BLANKSTATE_METRICS |
Optional. Comma separated Metric IDs | |
BLANKSTATE_THRESHOLD |
Score threshold (0.0 to 1.0) | 0.7 |
BLANKSTATE_MODE |
block, feedback, or audit |
block |
Config File
For advanced configuration, create ~/.blankstate/config.json:
{
"apiToken": "your-token-here",
"stageId": "stg_xxxxxxxx",
"defaultThreshold": 0.7,
"defaultMode": "block",
"protocols": [
{
"id": "circuit-breaker:1.0",
"mode": "block",
"threshold": 0.7,
"tools": ["exec", "write"]
},
{
"id": "code-quality:1.0",
"mode": "feedback",
"threshold": 0.5,
"tools": ["write"]
}
]
}
Protocol Configuration Options
| Option | Type | Description |
|---|---|---|
id |
string |
Protocol ID with version (e.g., circuit-breaker:1.0) |
mode |
block |
feedback |
threshold |
number |
Score threshold (0.0 to 1.0) for triggering the action |
tools |
string[] |
Tool types this Protocol applies to |
Metric Configuration Options
| Option | Type | Description |
|---|---|---|
id |
string |
Metric ID from Atlas |
mode |
block |
feedback |
threshold |
number |
Score threshold (overrides Atlas default if set) |
tools |
string[] |
Tool types this Metric applies to |
Tool Types
| Type | Description |
|---|---|
exec |
Shell commands, terminal execution |
write |
File creation, modification, patches |
browser |
Web navigation, form submission |
messaging |
Email, Slack, Discord, etc. |
all |
All tool types (default) |
Modes
Block Mode (Default)
When a Protocol triggers above the threshold, the tool call is rejected:
[BLANKSTATE] Action Blocked
Protocol: circuit-breaker:1.0
Nuances Matched: scope_violation, destructive_pattern
Evidence: targeting home directory with recursive deletion
Message: Action blocked by Protocol circuit-breaker:1.0.
The requested action has been suspended for safety review.
Feedback Mode
Tool call executes, but the agent receives improvement suggestions:
{
"result": { ... },
"blankstate_feedback": [
{
"source": "code-quality:1.0",
"score": 0.65,
"suggestions": ["missing_error_handling", "no_input_validation"]
}
]
}
Use feedback mode to help agents write better code or follow best practices.
Audit Mode
Tool call executes and evaluations are logged for compliance tracking:
{
"result": { ... },
"blankstate_audit": [
{
"timestamp": "2026-01-31T12:00:00Z",
"tool": "execute_command",
"source": "compliance-check:1.0",
"score": 0.3,
"action": "allowed"
}
]
}
Available Protocols
Browse available Protocols and their capabilities at doc.blankstate.ai/protocol-versions.
Circuit Breaker (circuit-breaker:1.0)
Designed for autonomous agent safety. Detects scope violations, destructive patterns, credential exposure, and risky communication patterns.
Custom Protocols
Create your own Protocols in Atlas and reference by ID:
{
"protocols": [
{ "id": "my-org/custom-policy:1.0", "mode": "block" }
]
}
Metrics
Metrics aggregate multiple Protocols into a single weighted score. Metrics are defined in Atlas and referenced by ID:
{
"metrics": [
{
"id": "agent-safety-score",
"mode": "block",
"threshold": 0.7
}
]
}
The protocol weights and composition are managed in Atlas. The threshold here is optional and overrides the Atlas default if you need different behavior for MCP.
Use Metrics when you want to combine multiple Protocols with weights, or when you need a pre configured safety suite.
Programmatic Usage
You can use the MCP server or the tool wrapper from Python (blankstate_mcp):
import asyncio
from blankstate_mcp import BlankstateMCPServer, load_config, validate_config
async def main() -> None:
config = load_config()
validate_config(config)
server = BlankstateMCPServer(config)
await server.start()
await server.wait_until_stopped()
asyncio.run(main())
Or use the tool wrapper directly (validate before executing a tool in your own agent loop):
import asyncio
from blankstate_mcp import create_tool_wrapper, load_config, validate_config
async def main() -> None:
config = load_config()
validate_config(config)
wrapper = create_tool_wrapper(config)
result = await wrapper.wrap_tool_call(
"execute_command",
{"command": "rm -rf ~/"},
)
if result.blocked and result.result is not None:
print("Blocked:", result.result.message)
else:
print("Proceed with execution")
asyncio.run(main())
Integration Examples
MCP Compatible Agents
Any agent that supports the Model Context Protocol can use Blankstate. Add to your agent's MCP configuration file:
{
"mcpServers": {
"blankstate": {
"command": "python3",
"args": ["-m", "blankstate_mcp"],
"env": {
"BLANKSTATE_API_TOKEN": "your-token",
"BLANKSTATE_STAGE_ID": "stg_xxxxxxxx",
"BLANKSTATE_PROTOCOLS": "circuit-breaker:1.0"
}
}
}
}
The exact config file location depends on your agent. Common locations:
~/.config/<agent>/config.json~/<agent>/settings.json
Direct API Integration
For agents without MCP support, you can call the Blankstate API directly. See the API documentation for details.
ICS Billing
Blankstate uses ICS (Interaction Computed Signal) billing:
- ICS consumed only on detection: no charge for tool calls that pass validation
- Usage tracked per API token in the Atlas dashboard
- Credits managed in Atlas: individual accounts receive monthly free credits
This means you can monitor thousands of tool calls and only pay when something is caught. Pricing and credit allocation are configured in your Atlas account.
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ YOUR MACHINE │
│ │
│ ┌────────────────┐ ┌──────────────────────────────┐ │
│ │ Agent │ MCP │ blankstate-mcp │ │
│ │ (Any MCP │ ──────> │ │ │
│ │ compatible │ │ Intercepts tool calls │ │
│ │ agent) │ │ Calls configured Protocols │ │
│ └────────────────┘ │ Applies mode decisions │ │
│ └──────────────┬───────────────┘ │
│ │ │
└────────────────────────────────────────────┼─────────────────────┘
│
│ HTTPS + Bearer Token
▼
┌──────────────────────────────────────────────────────────────────┐
│ BLANKSTATE CLOUD │
│ │
│ Protocol evaluation (pure sensors) │
│ Returns score, nuances, evidence │
│ │
└──────────────────────────────────────────────────────────────────┘
Contributing
git clone https://github.com/blankstate-ai/blankstate-py.git
cd blankstate-py
python3 -m pip install -e "./packages/sdk" -e "./packages/mcp[dev]"
pytest packages/mcp/tests -q
Troubleshooting
Issue in Cursor / Claude Desktop (Windows)
Some hosts spawn subprocesses without your shell PATH. Use the full path to python.exe (or to the blankstate-mcp script in your pipx/venv Scripts folder) in "command", or configure the host’s environment so python / blankstate-mcp resolves correctly.
"Missing API token"
Set BLANKSTATE_API_TOKEN in the env block of your MCP config, or in ~/.blankstate/config.json.
"stage_id" is required unless BLANKSTATE_STAGE_ID is set
bks_dive_open needs a Stage. Pass stage_id on the tool call, or set BLANKSTATE_STAGE_ID in MCP env (Atlas copies this on the Stage page).
"No protocol or metric configured" (on bks_sense / bks_validate)
The server boots with a token alone. bks_sense and bks_validate still need a protocol
or metric at call time. Set BLANKSTATE_PROTOCOLS or BLANKSTATE_METRICS in the env block:
"BLANKSTATE_PROTOCOLS": "proto-xxxxxxxx-...:1.0"
Both can be set at the same time. Protocols are evaluated directly; Metrics aggregate multiple protocols. Dive tools do not need this.
Protocol ID format
Use the UUID-based ID from Atlas (e.g. proto-6d....:0.2),
not a friendly name. Find your Protocol ID at Atlas → API Dashboard → Explorer → /protocols.
"API request failed: 401"
Token is invalid or expired. Generate a new one at atlas.blankstate.ai.
"API request failed: 404"
Protocol not found. Verify the ID and version exist in your Atlas account.
Links
License
MIT License. See LICENSE for details.
Metadata
Release files for blankstate-mcp 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| blankstate_mcp-0.5.0.tar.gz | 59.1 kB | Without provenance | Details for blankstate_mcp-0.5.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| blankstate_mcp-0.5.0-py3-none-any.whl | Python 3 | none | any | Details for blankstate_mcp-0.5.0-py3-none-any.whl |
Total release size: 114.7 kB
Release files / blankstate_mcp-0.5.0.tar.gz
| Download URL | blankstate_mcp-0.5.0.tar.gz |
|---|---|
| Size | 59.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e72e5203789a1b902e8fd9fdc47774f8f3e15e9172263be8c5493c95195dad16
|
|
BLAKE2b-256 checksum How to use checksums |
619d61e22cc20df8c097b0f6b5e944dd7fde48822fdfbb8fae1e68a377e7ed5e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / blankstate_mcp-0.5.0-py3-none-any.whl
| Download URL | blankstate_mcp-0.5.0-py3-none-any.whl |
|---|---|
| Size | 55.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fb0f34cb6791084ee32934119eb4e344223f125399698a5ef3d2a1df5c76760e
|
|
BLAKE2b-256 checksum How to use checksums |
2d5c5e5a9784f96b5a2387cddb2e6685d4e05710f65645bc22f9ca73f0d85e22
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Security for blankstate-mcp 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.