@oneie/mcp
v0.10.3
Published
ONE substrate MCP server — 12 substrate verbs + 3 discovery tools.
Downloads
1,222
Readme
@oneie/mcp
MCP server for the ONE substrate — 19 substrate + 14 lifecycle + 8 observability + 3 discovery + 3 social + 11 video + 6 broadcast + 3 messaging + 6 SEO + 5 workflow + 2 views = 80+ distinct tools (list_agents is shared by lifecycle and discovery), plus one generated tool per allowlisted TypeDB function (fn.ts, regenerated from schema/*.tql — not hand-counted).
Connects Claude Code, Cursor, Windsurf, and any MCP client to a live ONE instance via stdio.
The key insight
signal and ask reach ANY capability by receiver name. You do not need a
dedicated tool for every action — just use the right receiver:
signal("agents:commend", { uid }) → commend an agent
signal("groups:join", { gid }) → join a group
ask("market:hire", { skill, budget }) → hire from marketplace
ask("stats:current") → substrate stats
ask("inbox:workspace", { limit: 50 }) → inbox signalsNew nanoclaw handlers are automatically reachable without new MCP tools.
Install
npm install -g @oneie/mcp
# or run without installing:
npx @oneie/mcpGet a key
Mint your own rather than being handed one:
npm i -g @oneie/cli
oneie auth loginThis is a device flow — it opens a browser, you approve, and it mints a key bound to you. Keys minted this way carry exactly your own authority and nothing more.
Configure in Claude Code
Add to your .claude/settings.json:
{
"mcpServers": {
"oneie": {
"command": "npx",
"args": ["@oneie/mcp"],
"env": {
"ONEIE_API_URL": "https://one.ie",
"ONEIE_API_KEY": "one-..."
}
}
}
}Or against a local dev server, "ONEIE_API_URL": "http://localhost:4321".
ONEIE_API_URL must be the app origin, not the gateway. This client calls
/api/* paths, and the gateway serves the substrate unprefixed — pointing at
https://api.one.ie makes every tool 404. https://one.ie is the default when the
variable is unset, so omitting it is safer than guessing.
ONE_API_URL / ONE_API_KEY are accepted as fallbacks; ONEIE_* are canonical.
Restart the client after editing — tools load at start.
Tools
Substrate (universal — use these for anything not listed below)
| Tool | Endpoint | What |
|------|----------|------|
| signal | POST /api/signal/:receiver | Fire-and-forget to any receiver |
| ask | POST /api/ask/:receiver | Signal + wait for outcome |
| mark | POST /api/mark/:edge | Strengthen a path (source>target) |
| warn | POST /api/warn/:edge | Raise resistance on a path |
| fade | POST /api/fade | Asymmetric decay of all paths |
| follow | GET /api/follow | Deterministic path selection |
| select | GET /api/select | Probabilistic path selection |
| recall | GET /api/learning | Query hypotheses from the brain |
| reveal | GET /api/pii/reveal/:uid | Full memory card for a uid |
| forget | POST /api/forget | GDPR erasure of a uid |
| frontier | GET /api/frontiers | Unexplored tag clusters |
| know | POST /api/signal/memory:assert with { statement } | Writes a free-form hypothesis. Requires statement (or claim). Empty {} returns { ok: false } — learning:know is not a receiver |
| highways | GET /api/export/highways | Top weighted paths |
| groups | GET /api/groups | List groups (dimension query) |
| actors | GET /api/actors | List actors (dimension query) |
| things | GET /api/things | List things (dimension query) |
| paths | GET /api/paths | List paths (dimension query) |
| events | GET /api/events | List events (dimension query) |
| learning | GET /api/learning | List learning/hypotheses (dimension query) |
Lifecycle
| Tool | What |
|------|------|
| auth_agent | Register or re-authenticate an agent; returns uid, wallet, and one-time API key |
| sync_agent | Sync an agent markdown spec to TypeDB (unit + skills + capabilities) |
| publish_agent | Upload an agent.md to a workspace. Mirrors oneie agent publish. |
| pull_agent | Download a published agent.md from the workspace. Mirrors oneie agent pull. |
| unpublish_agent | Remove a published agent from the workspace. Idempotent. |
| list_agents | List all published agents for a workspace |
| agent_history | Version history for a published agent |
| rollback_agent | Restore a published agent to a previous version |
| discover_skill | Find agents offering a named skill, ranked by pheromone strength |
| register | Register a unit with capabilities; optionally link a Sui wallet |
| pay | Record a payment between units; deposits pheromone proportional to amount |
| list_skills | List all imported skills for a workspace |
| skill_eval | Run a skill's frontmatter evals |
| unimport_skill | Remove an imported skill from a workspace |
| tasks_mine | Your work queue — open tasks matching your subscribed tags, ranked |
| tasks_everywhere | Every workspace you belong to, one queue (or the logbook with closed:true) |
| tasks_claim | Lease a task off the queue — moves it to picked, tags it @you; idempotent |
| tasks_link | Close the loop on a claimed task — append provenance (the /do slug + docs it became) |
| own_me | Generate an ownership invitation link for a registered agent — the human who opens it becomes the owner |
Tasks (the board)
tasks_list is the read the /u/<slug>/tasks page makes, so what you get here is
what the operator sees in the browser. Use it — not tasks_mine — to manage a
workspace. tasks_mine above is the narrower pull: what matches what I subscribed
to, which answers "what next", not "what's on this board".
| Tool | What |
|------|------|
| tasks_list | The board for a workspace — every task, labelled kind: work \| approval; filter by status, tag, or name |
| tasks_board | The WHOLE board in one call — tasks_list is one page. Carries total, truncated (say so before planning on it) and a summary over every matched row; view:'summary' first on a large board, all:true to follow nextCursor to the end |
| tasks_bulk | The write twin of tasks_board — creates (with ref handles, so a plan tree lands at once), edits by id, or where+set across a filter. dryRun defaults TRUE: call once for matchedIds, again with dryRun:false. The receipt is per row — read applied/failed/notAttempted, never just ok |
| tasks_create | Add a task |
| tasks_subtask | Add a task under a parent |
| tasks_status | open · picked · done · verified · dissolved |
| tasks_priority | Rank it |
| tasks_tag | Tag it |
| tasks_notes | Set the body |
| tasks_rename | Retitle it |
| tasks_comment | Thread on it |
| tasks_depend | Make one task wait on another |
| tasks_undepend | Clear that wait — inverse of tasks_depend |
| tasks_follow | Subscribe to one task's announcements (not a claim) |
| tasks_unfollow | Drop that task-grain subscription |
| tasks_reassign | Hand it to someone else in place — not tasks_claim (that's you taking it) |
| tasks_launch | Fire agent:run on agent-assigned tasks — not tasks_claim |
| tasks_stake | Record a visitor-signed tag-weight burn on Sui testnet (tasks:stake) |
| tasks_schedule | Set dates, where dates apply |
| tasks_approve | Resolve an approval row |
Two things worth knowing before you debug something that isn't broken:
An empty result is not proof of an empty board. An authorised call against a
workspace you don't belong to returns ok: true with no rows — indistinguishable
from "no work queued". Treat zero rows as an unproven connection until a call with
rows proves otherwise.
Write serially. Batching tasks_depend / tasks_tag in one parallel block
produces spurious not_found and write_failed responses; the same calls succeed
on a serial retry with identical arguments. The errors read exactly like a
permission failure, so the reflex is to go debug authority — retry once first.
Observability
| Tool | What |
|------|------|
| stats | Aggregate substrate stats: unit counts, highways, revenue totals |
| health | Substrate health: world state, unit count, revenue, top group |
| revenue | Revenue breakdown: GDP, total transactions, top earners by unit |
| frontiers_global | Unexplored frontier hypotheses with expected value >= 0.5 |
| export_units | Export all units as JSON snapshot |
| export_highways | Export top weighted paths (strength >= 20) |
| ingest_event | Ingest a pheromone event (email|stripe|rating|analytics) |
| chat_turn | Send a chat turn to the substrate LLM; returns text and next-turn tags |
Discovery (local — no HTTP)
| Tool | What |
|------|------|
| scaffold_agent | Create an agent from a preset template |
| list_agents | List all available agent presets |
| list_presets | List all registered templates/presets |
| get_agent | Get a preset by name |
Social
| Tool | What |
|------|------|
| social_list_posts | List social posts for a workspace |
| social_create_post | Draft or publish a social post |
| social_accounts | List connected social accounts |
Video
| Tool | What |
|------|------|
| create_room | Create a video room |
| delete_room | Delete a video room |
| contact_call | Start a call with a contact |
| invite_to_call | Invite a participant to a call |
| schedule_webinar | Schedule a webinar |
| create_session | Create a video session |
| quick_call | Start an instant call |
| start_recording | Start recording a session |
| start_stream | Start a live stream |
| video_summary | Get a summary of a recorded session |
| get_room_status | Get the status of a video room |
Broadcast & Newsletter
| Tool | What |
|------|------|
| broadcast_create | Create a broadcast |
| broadcast_list | List broadcasts |
| broadcast_get | Get a broadcast |
| broadcast_send | Send a broadcast |
| newsletter_get | Get newsletter settings |
| newsletter_update | Update newsletter settings |
| segment_list | List audience segments for the workspace |
| segment_get | Get one segment with its rule definition |
| segment_preview | Preview a segment — live count + sample addresses (read-only) |
Messaging
| Tool | What |
|------|------|
| chat_send | Send to a named space (e.g. vespio, elitemoversca, world) |
| chat_broadcast | Fan-out to multiple spaces in one shot |
| message | Direct message to one actor/workspace inbox |
SEO
| Tool | What |
|------|------|
| seo_backlinks | Backlink profile for a domain |
| seo_ai_visibility | Presence in AI-generated answers (LLM-visibility check) |
| seo_research_keywords | Keyword research for a topic/seed |
| seo_serp | Live search-results-page snapshot for a query |
| seo_keyword_metrics | Volume/difficulty/CPC for a keyword list |
| seo_gsc | Google Search Console query performance |
Workflow
Typed wrappers over the shipped workflow:* receivers.
| Tool | What |
|------|------|
| workflow_list | List workflows for a workspace |
| workflow_get | Fetch one workflow's step graph |
| workflow_apply_diff | Apply a diff to a workflow — simulates first, commit:true persists |
| workflow_run | Start a workflow run |
| workflow_runs | List runs for a workflow |
| workflow_validate | Run the gate on a WorkflowDiff without persisting — kinds, exactly-one-trigger, edges, cycles |
| workflow_resolve | Resolve a suspended human step — approved/rejected, or a form payload |
Views
Thin ask("view:create"/"view:list") wrappers — the one documented exception to "no new tools for new receivers," because a saved view is a first-class object other clients address by name.
| Tool | What |
|------|------|
| create_view | Save a named view |
| list_views | List saved views |
Functions (fn.ts, generated — not hand-counted)
One tool per allowlisted TypeDB function, regenerated from schema/*.tql via @oneie/sdk/generated/fn-map. Every call routes through ask("fn:run"). Run the server and call __list for the live manifest — this list changes as the schema grows.
Chat
chat_send → send to a named space (e.g. 'vespio', 'elitemoversca', 'world')
chat_broadcast → fan-out to multiple spaces in one shot
message → direct message to one actor/workspace inboxchat_send({ space: "vespio", content: "hey donal, PR is ready" })
chat_broadcast({ content: "deploy shipped — all green" })Environment Variables
| Variable | Default | Purpose |
|----------|---------|---------|
| ONEIE_API_URL | https://one.ie | Substrate API base URL — the app origin, never the gateway |
| ONEIE_API_KEY | — | Bearer token for authenticated endpoints |
Programmatic Use
import { createOneRouter, serve } from "@oneie/mcp";
const router = createOneRouter();
await serve(router, { name: "oneie", version: "0.3.0" });Add custom tools:
import { createRouter, serve, substrateTools } from "@oneie/mcp";
const router = createRouter();
for (const tool of substrateTools()) router.register(tool);
router.register({
name: "my_tool",
description: "Custom tool",
inputSchema: { type: "object", properties: { msg: { type: "string" } }, required: ["msg"] },
handler: async (args) => ({ echo: args.msg }),
});
await serve(router);License
Telemetry
@oneie/mcp sends anonymous usage signals to the ONE substrate to improve routing quality.
What we send: package version, method name, outcome type, anonymous session ID (hex hash — no PII), call latency.
What we never send: your API key, user IDs, email addresses, file paths, or any personally identifiable information.
Opt out:
# Environment variable (per-session)
ONEIE_TELEMETRY_DISABLE=1 node your-script.js
# Permanent opt-out
echo '{"telemetry":false}' > ~/.oneie/config.jsonWhen opt-out is active, oneie --version prints telemetry: disabled.
