Skip to main content
Glama
alainux

MeaningSpace MCP

by alainux
README.md
# MeaningSpace MCP

![MeaningSpace banner](./docs/header.png)

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
[![Model Context Protocol](https://img.shields.io/badge/Model%20Context%20Protocol-Streamable%20HTTP-6b4eff)](https://modelcontextprotocol.io)
[![Cloudflare Workers](https://img.shields.io/badge/Cloudflare%20Workers-free%20tier-f38020)](https://developers.cloudflare.com/workers/)
[![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6)](./tsconfig.json)
[![Node.js >= 20](https://img.shields.io/badge/Node.js-%3E%3D20-339933)](./package.json)
[![CI](https://github.com/alainux/MeaningSpace/actions/workflows/ci.yml/badge.svg)](https://github.com/alainux/MeaningSpace/actions/workflows/ci.yml)

**An engine of creative strategies for AI agents — free, deterministic, theory-traceable, as an MCP server.**

MeaningSpace does not generate ideas. It hands the caller *moves*: theory-grounded transformations to perform on their own material, each with the structure to borrow, the steps to run, what to suppress, a check that says whether the move actually happened, and the ways it usually fails.

The server never receives, represents, transforms, or judges your concept. It contributes method; you contribute content.

## The distinction that matters

| MeaningSpace does | MeaningSpace does not |
|---|---|
| Return procedures drawn from computational-creativity theory | Generate ideas or write prose for you |
| Name a relation worth borrowing from a remote domain | Hold a model of your concept |
| Give you a test for whether a move succeeded | Score, rank, or assess your candidates |
| Cite its sources and state what it does not implement | Claim to measure creativity |

## Try the live demo

```text
https://meaningspace-mcp.alnx.workers.dev
```

MCP endpoint:

```text
https://meaningspace-mcp.alnx.workers.dev/mcp
```

## What is new in v0.5

v0.5 is a breaking replacement of the v0.4 tool surface. The previous tools transformed a
server-side `CreativeState` and produced candidate ideas and ordinal assessments. That was the
wrong shape: it put the creative act and the judgment on the server.

- Replaced the seven generation, development, evaluation, and synthesis tools with five strategy tools.
- Removed server-side concept representation entirely. There is no `CreativeState`, no concept extraction, and no prose rendering.
- Removed all assessment. `evaluate_ideas` became `get_review_protocol`, which returns criteria, what evidence each needs, and a question to ask yourself — and explicitly does not rank.
- Every operator gained a playbook: intent, what to identify first, an ordered procedure, what to project, what to suppress, a success check, failure modes, questions, and ways to push further.
- Strategies now cite their sources inline (`Gentner (1983), Structure-Mapping…`) alongside implementation status and omitted constructs.
- Roughly 3× faster, because nothing is transformed: about 0.04 ms for a set of eight strategies.

See [`CHANGELOG.md`](./CHANGELOG.md) for the full v0.4-to-v0.5 migration notes.

## Architecture

```text
Static site
└─ landing page, with the operator catalogue rendered from the engine at build time

Cloudflare Worker
├─ JSON API
├─ Streamable HTTP MCP endpoint
├─ native fair-use rate limiter
└─ static asset binding

External services
└─ none
```

Sessions are carried by the caller: pass moves you have already run back into `deepen_strategy`
or `contrast_strategies`. The server stores nothing between requests.

## Requirements

- Node.js 20 or newer; Node.js 22 is recommended.
- npm.

## Run locally

```bash
npm install
npm run dev:node
```

Open `http://127.0.0.1:8787`; the MCP endpoint is at `/mcp`. No environment variables, migration,
API key, or payment setup is required.

## Test the MCP directly

Initialize:

```bash
curl http://127.0.0.1:8787/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{
    "jsonrpc":"2.0",
    "id":1,
    "method":"initialize",
    "params":{
      "protocolVersion":"2025-11-25",
      "capabilities":{},
      "clientInfo":{"name":"local-test","version":"1.0"}
    }
  }'
```

Get strategies:

```bash
curl http://127.0.0.1:8787/mcp \
  -H 'content-type: application/json' \
  -d '{
    "jsonrpc":"2.0",
    "id":2,
    "method":"tools/call",
    "params":{
      "name":"get_strategies",
      "arguments":{
        "challenge":"Find directions for a painting about absence, avoiding empty rooms and chairs.",
        "domain":"contemporary painting",
        "audience":"a gallery visitor who has seen many paintings about loss",
        "novelty":5,
        "count":3,
        "seed":"local-painting-test"
      }
    }
  }'
```

## What a strategy looks like

```json
{
  "operator": "bisociation",
  "operatorName": "Bisociation",
  "basis": "Cross-domain matrices",
  "whenToUse": "Your material feels coherent but predictable, and you want a collision rather than a refinement.",
  "theory": {
    "ids": ["koestler-bisociation", "boden-conceptual-spaces"],
    "status": "operationalized",
    "sources": ["Arthur Koestler (1964), The Act of Creation", "…"],
    "constructsImplemented": ["…"],
    "constructsOmitted": ["learned associative matrices", "…"]
  },
  "borrow": {
    "domain": "ant colony stigmergy",
    "distance": 5,
    "mechanism": "evaporating signals",
    "relation": "unused traces weaken while reinforced paths persist",
    "consequence": "memory is maintained by continued relevance",
    "roles": ["agent", "trace", "environment"]
  },
  "intent": "Make one element of your concept belong to two frames at once…",
  "identify": ["One element of your concept that will sit in both frames…"],
  "procedure": ["Describe your chosen element using only the conventions of…", "…"],
  "project": ["The relation \"unused traces weaken…\"", "…"],
  "suppress": ["ant colony stigmergy's vocabulary, imagery, and setting…"],
  "check": "If either description alone still fully explains your result, the frames have not collided…",
  "failureModes": ["ant colony stigmergy becomes decoration or simile rather than structure.", "…"],
  "questions": ["Which part of the relation is structural, and which is surface resemblance?"],
  "pushFurther": ["A minimal version that expresses only the bridging relationship.", "…"]
}
```

`intent`, `identify`, `procedure`, `project`, `suppress`, `check`, `failureModes`, `questions`,
and `pushFurther` are all instructions addressed to you. The server performs none of them.

## MCP capabilities

### Tools

- `get_strategies` — moves to execute against your own concept.
- `deepen_strategy` — more moves inside one operator family, excluding the mechanism you already ran.
- `contrast_strategies` — moves unlike everything you report having tried.
- `get_review_protocol` — criteria, evidence, and questions for you to apply. Returns no verdicts.
- `list_operators` — the catalogue with theory status and the situation each operator suits.

### Resources

- `creativity://operators`
- `creativity://theories`
- `creativity://lenses`
- `creativity://remote-domains`
- `creativity://workflow`

### Prompt

- `run_strategy_session`

## Running a session

```text
get_strategies        → pick one move
  ↓ complete its identify list against your own material
  ↓ run its procedure, honour its suppress list
  ↓ apply its check — if it fails, the move did not happen
deepen_strategy       → push that operator further
contrast_strategies   → leave the region entirely
get_review_protocol   → compare candidates yourself
```

Pass the strategy object you ran straight back into `deepen_strategy` or into the `used` array of
`contrast_strategies`; both also accept a bare `{ operator, domain, mechanism }`.

## Review protocol

Generation is separate from judgment, and MeaningSpace does neither. `get_review_protocol`
returns, per criterion, what to look for and a question to ask yourself:

```json
{
  "lens": "fiction",
  "criteria": [
    {
      "id": "tension",
      "name": "Narrative tension",
      "lookFor": "Unresolved opposition, changed agency, or consequential incompatibility.",
      "askYourself": "What is at stake if the opposition resolves too early?"
    }
  ],
  "procedure": ["Assess each candidate against every criterion on its own, before comparing…"],
  "caution": "These are review aids. Nothing here measures creativity…"
}
```

Lenses: `general`, `business`, `fiction`, `visual_art`, `prompt_design`, `research`, `education`.

## JSON API

All endpoints are free and unauthenticated:

```text
GET  /api/health
GET  /api/operators
GET  /api/theories
GET  /api/lenses
GET  /api/domains
POST /api/v1/strategies
POST /api/v1/deepen
POST /api/v1/contrast
POST /api/v1/review-protocol
POST /mcp
```

## MCP Inspector

Create `mcp.local.json`:

```json
{
  "mcpServers": {
    "meaningspace-local": {
      "type": "http",
      "url": "http://127.0.0.1:8787/mcp"
    }
  }
}
```

Launch a current MCP Inspector release and choose `meaningspace-local`. To inspect the live
deployment, swap the URL for `https://meaningspace-mcp.alnx.workers.dev/mcp`.

## Test and validate

```bash
npm run check
```

That runs strict TypeScript, the unit and integration suite, the browser asset build, a real
local HTTP MCP smoke test, and the determinism benchmark. The suite verifies, among other things:

- deterministic output for a fixed seed;
- that every operator returns a complete, executable playbook;
- that no idea, score, verdict, or representation of the caller's concept appears in any response;
- that procedures address the caller and name what they borrow;
- that `deepen_strategy` stays in its family and excludes the mechanism already run;
- that `contrast_strategies` avoids every move it was told about;
- that the review protocol never leaks a ranking;
- graceful degradation when the avoid lists exhaust the catalogue.

## Deploy to Cloudflare

```bash
npm install
npx wrangler login
npm run deploy
```

No D1, KV, secrets, model provider, or payment account is required. `APP_URL` in
`wrangler.jsonc` is optional: same-origin and localhost requests are allowed automatically.

## Theory and claims

See [`THEORY.md`](./THEORY.md) for the implementation matrix and [`REFERENCES.bib`](./REFERENCES.bib)
for bibliographic data.

The intended claim for v0.5 is:

> MeaningSpace is a deterministic, theory-traceable library of creative procedures, with an
> explicit account of which constructs from each cited theory it does and does not implement.

It does not claim to reproduce human cognition, to measure creativity, or to fully implement
every cited theory. It makes no claim about the quality of what you produce with it.

## Current limitations

- The catalogue is hand-authored: eight operators and twenty-two source domains with two mechanisms each. Long sessions will exhaust it, and `diagnostics.avoidanceRelaxed` tells you when they have.
- Source-domain distance is a catalogue constant, not measured against a corpus or an observer.
- Operator selection is deterministic traversal, not a diagnosis of your brief. `whenToUse` is there for you to choose with; the server does not read your challenge.
- Structure mapping is a procedure to follow, not a Structure-Mapping Engine.
- Blending does not search recursive blend networks or formal optimality principles.
- No empirical study has established that these procedures improve creative outcomes.

## License

MIT