agent-nexus
AgentNexus is a service-boundary-aware coordination server for managing versioned documents and facilitating communication across heterogeneous LLM code agents.
Document Management
push_document— Push a full new document versionpatch_document— Apply a unified diff patch to an existing document (efficient partial updates)get_document— Retrieve the latest or a specific version of a documentlist_documents— List all documents in a sub-projectpublish_draft— Confirm and publish a draft, triggering subscriber notifications
Update & Notification Handling
get_my_updates_with_context— Fetch unread notifications with diffs and full content in one callget_my_updates— Fetch unread notifications without full contentack_update— Acknowledge (mark as read) a specific notificationadd_subscription— Subscribe a project to updates from a document ID or type
Task & Configuration Access
get_my_tasks— Retrieve pending/in-progress tasks for a projectget_config— Fetch configuration document for a project and lifecycle stage
Space & Project Management
create_space— Create a new Project Space grouping related servicesregister_project— Register a sub-project (service) within a spacelist_projects— List all sub-projects in a spaceget_project_id_by_name— Look up a project ID by name
AI & Search
Full-text search (FTS5/BM25) across all documents in a space
AI Planner: conversational Q&A, service-split proposals, and project overviews via integrated LLMs
Agent Onboarding (SDAOP)
generate_steering_file— Auto-generate IDE onboarding files (AGENTS.md, CLAUDE.md, Kiro steering, Cursor rules) to configure agents for automatic document-update checks
Provides integration with OpenAI's language models for the Planner AI layer, enabling conversational document Q&A and service planning.
AgentNexus
The coordination layer for heterogeneous LLM code agents. Let a backend agent, a frontend agent, and an infra agent — running on different IDEs and different models — stay in sync automatically, with zero hand-written glue.
An MCP server that coordinates AI code agents across service boundaries. (Not affiliated with the MIT Lincoln Laboratory project of the same name.)
The problem
Your product isn't one codebase. It's a backend, a frontend, some infra, a test suite — each with its own repo, stack, and agent. When the backend changes its API, the frontend has to adapt. Today that coordination is done by humans copy-pasting specs into chat, or by hand-written CLAUDE.md / AGENTS.md files that go stale the moment the service changes.
Role-playing multi-agent frameworks (ChatDev, MetaGPT) don't help here: they assume all agents live in one simulated org, one codebase. Real systems are a mesh of independently-owned parts.
Related MCP server: en-quire
What AgentNexus does
AgentNexus coordinates agents at the service boundary — the unit real systems are actually built from. Each boundary registers as a sub-project, publishes versioned Markdown documents (requirements, design, API specs, config), and subscribes to the documents it depends on. When a document changes, subscribers get a diff-aware notification — the exact change plus the full latest content — so an agent can make a targeted edit without a human in the loop.
Backend Agent AgentNexus Frontend Agent
(Claude Code) (Cursor)
│ │ │
│── POST /api/documents ▶│ │
│ (api spec, v5) │── notification ─────────▶│
│ │ │── get_my_updates_with_context()
│ │── diff + full content ──▶│
│ │ │── applies targeted code change
│ │◀──────── ack_update() ───│Two ideas make this practical, and they're the parts worth stealing even if you never run the server:
1. Content travels out-of-band → zero token cost
Coordination signals (what changed, who must react) are small and belong in the model's context. Document bodies are large and don't need to be reasoned about the moment they're written — they need to be stored and fetched on demand. So AgentNexus splits the two:
Control plane (MCP): notifications, subscriptions, queries — a notification carries a version number and a unified diff, enough to decide if and how to react.
Data plane (plain HTTP
POST /api/documents): full document body, never passed as an MCP tool argument.
A document of any size costs zero model tokens on the write path. You pay tokens for coordination, not for content.
2. SDAOP — the service onboards the agent, not the other way around
AGENTS.md, CLAUDE.md, Cursor rules, Kiro steering — they all share one model: a human writes a static file, commits it, and the IDE loads it at startup. It goes stale, it drifts, and it's per-human busywork.
Service-Driven Agent Onboarding Protocol (SDAOP) flips this. The service generates and delivers client-specific onboarding at connection time. A new agent only needs the endpoint:
generate_instruction_file(project_name="my-service", project_space_id="<space_id>", client_type="kiro")Emits the right artifact for the client —
.kiro/steering/,CLAUDE.md,AGENTS.md, or.cursor/rules/— plus a push-tool script with the server URL baked in.Each artifact is content-hash versioned. Change a convention on the server, or move the server to a new URL, and the version bumps — connected workspaces detect the drift and re-onboard. No stale files, no manual notification.
The service is the single source of truth; the client-side file is a derived artifact that regenerates as the service evolves.
Supported clients: kiro, claude, codex, cursor.
Quick Start
# 1. Install
pip install -e .
# 2. Start the server — auto-creates the database on first run
# (default: http://0.0.0.0:10086/mcp, dashboard at http://0.0.0.0:10086/)
python -m agent_nexus.mainThat's it — no separate DB migration or .env needed to get started. Everything
has sane defaults; copy .env.example to .env only when you want to change the
port, point at Postgres, or enable the Planner LLM.
Run with Docker
docker build -t agent-nexus .
docker run -p 10086:10086 agent-nexusTo persist documents and the database across restarts, mount volumes:
docker run -p 10086:10086 \
-v "$(pwd)/workspace:/app/workspace" \
-v "$(pwd)/data:/app/data" \
-e AGENT_NEXUS_DB_URL=sqlite:////app/data/agent_nexus.db \
agent-nexusConnect from Kiro / any MCP client:
{
"mcpServers": {
"agent-nexus": {
"url": "http://localhost:10086/mcp"
}
}
}First steps:
# Create a project space
create_space(name="my-project")
# Register two boundaries
register_project(name="backend-api", type="development", project_space_id="<space_id>")
register_project(name="frontend", type="development", project_space_id="<space_id>")
# Push a document via HTTP POST (content stays out of LLM context)
# curl -X POST http://localhost:10086/api/documents -H 'Content-Type: application/json' \
# -d '{"project_id":"<backend_id>","doc_id":"<backend_id>/api","content":"# API Spec..."}'
# Subscribe the frontend to the backend's API docs
add_subscription(subscriber_project_id="<frontend_id>", project_space_id="<space_id>", target_doc_id="<backend_id>/api")
# Frontend checks for updates (returns diff + full content)
get_my_updates_with_context(project_id="<frontend_id>")Web Dashboard
Once the server is running, open http://localhost:10086/ in your browser to browse spaces, sub-projects, and documents, run full-text search, and use the built-in AI Chat for conversational document Q&A and service planning.
LLM configuration: AI Chat requires
PLANNER_LLM_API_KEY. SetPLANNER_LLM_PROVIDER(openaioranthropic),PLANNER_LLM_MODEL, and optionallyPLANNER_LLM_BASE_URL(Azure / Ollama / compatible APIs). Leave the key unset to disable AI features while keeping all browse/search functionality.
Key Features
Versioned document store — SHA-256 dedup, full version history, per-boundary namespacing
Publish-subscribe notifications — subscribe by exact doc ID or doc type
Diff-aware updates —
get_my_updates_with_contextreturns unified diff + full content in one callControl/data plane split — coordination over MCP, content over out-of-band HTTP (zero LLM token cost)
SDAOP — services auto-generate versioned, client-specific onboarding files for any connecting agent
Planner — a read-only, boundary-spanning observer (
planner_chat,planner_plan,planner_overview) that answers cross-boundary questions no single agent canMCP HTTP server — streamable-HTTP transport, multiple agents connect simultaneously
FTS5 full-text search —
search_documentswith BM25 ranking, phrase/prefix/boolean queriesWeb Dashboard + AI Chat — browser UI over spaces, projects, and documents
337 tests — unit + property-based (Hypothesis)
Out-of-Band Write Endpoint
The primary document write path. Content travels via HTTP body — never entering LLM context — so it's practical for documents of any size. Supports optional base_version for optimistic concurrency control (fast-forward check).
curl -X POST http://localhost:10086/api/documents \
-H "Content-Type: application/json" \
-d '{
"project_id": "<project_id>",
"doc_id": "<project_id>/requirement",
"content": "# Requirements\n\nContent here..."
}'MCP Tools
Tool | Description |
| Create a Project Space |
| Register a sub-project (boundary) |
| List all sub-projects in a space |
| List all documents in a sub-project |
| Retrieve a document (latest or specific version) |
| Get unread notifications with diff + full content |
| Mark a notification as read |
| Get pending tasks for a project |
| Get config document for a stage |
| Add a subscription rule |
| Confirm a draft document |
| Generate client-specific onboarding file (SDAOP) |
| Look up project_id by name |
| Full-text search across documents in a space |
| Conversational Q&A with LLM over project documents (streaming) |
| Generate service-split proposal from a description |
| Get a high-level overview of a project space |
Configuration
Environment Variable | Default | Description |
|
| Database URL |
|
| Workspace root (docs live under |
|
| Server bind host |
|
| Server port |
| (derived from host/port) | Outward-facing URL baked into onboarding files; changing it bumps the SDAOP version |
|
| Default space ID for bootstrap imports |
|
| LLM provider for Planner AI ( |
| (provider default) | LLM model name |
| (none) | API key; leave empty to disable AI features |
| (none) | Custom API endpoint for OpenAI-compatible APIs (Azure, Ollama, proxies) |
Running Tests
python -m pytest tests/ -qPaper
The accompanying research papers are in the paper/ directory:
paper/agentnexus-v4.md— v4 (current): generalizes the coordination unit from service to ownership boundary, adds the control/data plane split and the Planner (中文版)paper/agentnexus-v3.md— v3: introduces SDAOPpaper/agentnexus.md— v2
dugubuyan. AgentNexus: A Boundary-Aware Coordination Architecture for Heterogeneous LLM Code Agents (v4). Zenodo, 2026. https://doi.org/10.5281/zenodo.21257426
License
MIT
Available Tools
16 toolsack_updateC
Acknowledge (mark as read) a notification.
Inputs: project_id (required), update_id (required).
add_subscriptionB
Add a subscription rule. Provide target_doc_id for exact doc or target_doc_type for all docs of that type.
Inputs: subscriber_project_id (required), project_space_id (required), target_doc_id, target_doc_type.
create_spaceC
Create a new Project Space. Returns the space_id needed for registering projects.
Inputs: name (required).
generate_steering_fileB
Generate the content for a .kiro/steering/doc-exchange.md Steering file. The sub-project Kiro should create this file to enable automatic doc-update checks.
Inputs: project_name (required), project_space_id (required).
get_configB
Return the config document for the given project and stage.
Inputs: project_id (required), stage (required).
get_documentB
Retrieve a document (latest or specific version).
Inputs: project_id (required), doc_id (required), version.
get_my_tasksC
Return all pending/in-progress tasks for the given project.
Inputs: project_id (required). Returns: result
get_my_updatesA
Return all unread notifications for the given project.
Inputs: project_id (required). Returns: result
get_my_updates_with_contextA
Return all unread notifications with diff and full latest document content. One call gives everything needed to understand what changed and act on it. After processing, call ack_update for each update_id to mark as read.
Inputs: project_id (required). Returns: result
get_project_id_by_nameB
Look up a sub-project's project_id by its human-readable name.
Inputs: name (required), project_space_id (required).
list_documentsA
List all documents belonging to the given sub-project.
Inputs: project_id (required). Returns: result
list_projectsC
List all sub-projects in the given project space.
Inputs: project_space_id (required). Returns: result
patch_documentA
Apply a unified diff patch to an existing document, producing a new version.
Use instead of push_document when only part of the document changed — avoids sending the full content and works around tool-call payload size limits.
patch must be in unified diff format (output of difflib.unified_diff). base_version must match the current latest version; if not, returns PATCH_BASE_MISMATCH — call get_document to fetch latest and regenerate.
Inputs: project_id (required), doc_id (required), base_version (required), patch (required).
publish_draftC
Confirm a draft document version, publishing it and triggering notifications.
Inputs: project_id (required), doc_id (required), version (required).
push_documentC
Push a new document version to the exchange center.
Inputs: project_id (required), doc_id (required), content (required), metadata.
register_projectC
Register a new sub-project in the given project space.
type: development | testing | ops | infra | shared | ... stage: design | development | testing | deployment | upgrade
Inputs: name (required), type (required), project_space_id (required), stage.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 16 tools
Each tool has a clearly distinct purpose. The only potential overlap (get_my_updates vs. get_my_updates_with_context) is resolved by the latter being a superset with explicit context. push_document and patch_document are differentiated by full vs. partial updates.
All tools follow a consistent verb_noun pattern in snake_case (e.g., create_space, list_documents, ack_update). Minor abbreviation like 'ack' is acceptable and does not break consistency.
16 tools cover spaces, projects, documents, notifications, subscriptions, and tasks. This is well-scoped for a project/document management server, not too many or too few.
The tool surface covers core create and read operations but lacks update and delete for projects, documents, subscriptions, and tasks. Missing create tasks and delete operations for multiple resources are notable gaps.
Maintenance
Related MCP Connectors
Agent-native notes, tasks, dev-docs, vaults, sync & handoffs. MCP + OpenAPI dual surface.
Hosted MCP memory for coding agents: persistent across sessions, editable markdown, team sharing.
Publish and share access-controlled Markdown documents from any MCP-enabled AI tool.
MCP-native collaborative markdown editor with real-time AI document editing
Related MCP Servers
- AlicenseCqualityDmaintenanceMCP protocol server for managing multi-project Markdown documents, supporting project isolation and LLM tool integration.2925 npm4MIT
- AlicenseNot gradedqualityBmaintenanceMCP server for structured document management of markdown and YAML files, with RBAC, git-based approval workflows, and semantic search, enabling agents to read, edit, and maintain documents under governance.MIT
- AlicenseNot gradedqualityBmaintenanceA local, agent-to-agent artifact exchange for LLM workflows. Enables MCP-capable tools like Claude, Codex, and Gemini to publish, list, read, update, and continue from artifacts without copying content through chat.578 npmMIT
- AlicenseNot gradedqualityBmaintenanceMCP server for Nyxdoc, a document system where humans and external agents collaborate on documents with version history, agent to-dos, and workspace permissions.MIT