ν Integrations — Algorithm Extraction
Algorithmic content extracted from AMS
src/mcp/,src/claude/(24 sub-modules), andsrc/domains/integrations/for Colibri implementation reference.
MCP Bridge: Stdio Transport + JSON-RPC + Tool Dispatch
Transport Layer
- Protocol: JSON-RPC 2.0 over stdio (
process.stdin→process.stdout) - SDK:
@modelcontextprotocol/sdk—StdioServerTransport - Critical invariant:
console.logmust be redirected toconsole.error. Debug text on stdout corrupts the MCP wire format. The SDK holds_stdout = process.stdoutand calls.write()directly — do NOT overrideprocess.stdout.write.
Tool Dispatch Pipeline
CallTool JSON-RPC request
│
├─ withSerializedToolExecution — mutex: one tool at a time
│ ├─ runWithAclContext — ACL identity injection + project scope
│ │ ├─ runWithAuditContext — audit session propagation
│ │ │ ├─ withRateLimit — per-tool rate limiting
│ │ │ │ ├─ withCircuitBreaker — open/half-open/closed states
│ │ │ │ │ ├─ withRetry — backoff + retryable classification
│ │ │ │ │ │ └─ routeTool(name, args)
routeTool: Sequential-Probe Pattern
function routeTool(name, args):
# Priority order: fast/unaudited paths first
for controller in [performance, audit, thought, merkle]:
result = controller.handle(name, args)
if result != null: return result
# Claude API tools next
for controller in [claudeApiControllers]:
result = controller.handle(name, args)
if result != null: return result
# Core domain handlers (with audit middleware wrapping)
for controller in [roadmaps, tasks, analysis, gsd, memory, integrations, ...]:
result = controller.handle(name, args)
if result != null: return result
return { error: "MethodNotFound" }
Post-execution: applyOrchestrationAfter may attach metadata. Internal _metrics keys stripped before safeStringify.
Webhook Delivery: HMAC-SHA256 + Exponential Backoff
Delivery Mechanics
function deliverWebhook(webhook, event, payload):
body = JSON.stringify({
event: event,
timestamp: ISO8601_now(),
payload: payload
})
headers = {
"Content-Type": "application/json",
"X-AMS-Event": event
}
if webhook.secret:
signature = HMAC-SHA256(webhook.secret, body)
headers["X-AMS-Signature"] = "sha256=" + hex(signature)
attempt = 0
delay_ms = 100
while attempt <= 5:
try:
response = POST(webhook.url, headers, body, timeout=5000ms)
if response.status < 400:
return { success: true, attempt: attempt }
if is_retryable(response.status):
# fall through to retry
else:
return { success: false, reason: "permanent_error", status: response.status }
except error if is_retryable_error(error):
pass # fall through to retry
attempt++
sleep(delay_ms)
delay_ms = delay_ms * 2 # exponential backoff
return { success: false, reason: "max_retries_exceeded" }
Retryable Classification
| Type | Retryable |
|---|---|
| HTTP 408 (Request Timeout) | Yes |
| HTTP 429 (Rate Limited) | Yes |
| HTTP 5xx (Server Error) | Yes |
| HTTP 4xx (other) | No |
ETIMEDOUT |
Yes |
ECONNRESET |
Yes |
ECONNREFUSED |
Yes |
| socket hang-up | Yes |
Retry settings: base 100ms, max 5 retries, timeout clamped to 50ms–60s (default 5s).
Event → Webhook Mapping (resolveEventName)
| Tool call | Webhook event |
|---|---|
task_create |
task.created |
task_update with status=done |
task.completed |
| Session start | session.start |
| Session end | session.end |
roadmap_export |
roadmap.exported |
| Any task sync operation | task.sync |
| Error (unhandled) | error |
Notification Channels: Adapter Pattern
Four channels, each receiving a format-appropriate payload:
| Channel | Payload format |
|---|---|
| Slack | { text: string, attachments: [...] } |
| Discord | { content: string, embeds: [...] } |
{ subject, body, to } |
|
| Custom webhook | Raw JSON event body |
All channels share the same event subscription model. Notification history is capped at 200 entries (LRU eviction of oldest). Diagnostic payloads are sanitized: keys matching /secret|password|token|key/i are replaced with [REDACTED].
Git Auto-Commit State Machine
IDLE
│
├─ trigger event received (session.end, roadmap.exported, task.sync)
│
STAGING
│ git add <changed files>
│
COMMITTING
│ git commit -m "auto: <event_type> <timestamp>"
│
PUSHING (if remote configured)
│ git push origin <branch>
│
DONE → IDLE
On error at any step:
Log error
Return to IDLE
Emit notification (if configured)
Default triggers: session.end, roadmap.exported, task.sync. Toggled via setGitAutoCommitConfig.
Claude API: 24 Sub-Module Inventory
Located at src/claude/. Each sub-module follows the pattern: src/claude/{module}/index.js as barrel + implementation files.
| Sub-module | Purpose |
|---|---|
core |
Foundation: client, resilience (circuit breaker, retry), model registry, budget manager, prompt cache, request deduplication. 5,000+ lines. |
vision |
Image analysis: preprocessing, storage, batch analysis, PDF-to-vision, visual Q&A |
batch |
Bulk request submission to Anthropic’s Message Batches API |
batch-api |
Polling and result retrieval for batch jobs |
streaming |
Server-sent event (SSE) streaming for long-running completions |
extended-thinking |
Extended thinking (chain-of-thought) parameter management |
conversation |
Multi-turn conversation threading with history management |
messages |
Low-level Messages API wrapper |
tokens |
Token counting, context window budgeting |
context |
Context optimization and window management |
files |
File upload and document handling |
citations |
Source citation extraction and formatting |
computer |
Computer use tool integration |
webhooks |
Outbound webhook management for Claude events |
admin |
API key management, organization settings |
usage |
Usage and billing tracking |
analytics |
API usage analytics and reporting |
workspaces |
Workspace isolation and project scoping |
tool-chain |
Multi-step tool orchestration (ChainMode: SEQUENTIAL/PARALLEL/CONDITIONAL/LOOP/DAG) |
pdf-api |
PDF document processing via Claude |
models |
Model capability registry and selection |
router |
Request routing across Claude endpoints |
resilience |
Shared circuit breaker and health checker |
threads |
Conversation thread management |
Core Sub-Module Architecture
Key files in src/claude/core/:
| File | Lines | Purpose |
|---|---|---|
client.js |
778 | ClaudeClient: wraps fetch, handles auth, versioning, response parsing |
enhanced-client.js |
646 | Adds prompt caching, deduplication, budget enforcement on top of base client |
resilience.js |
618 | CircuitBreaker (closed/open/half-open), HealthChecker, withResilience |
retry.js |
482 | withRetry: exponential backoff, jitter, retryable error classification |
models.js |
726 | CLAUDE_MODELS registry, capability flags, context window limits, model comparison |
budget.js |
751 | BudgetManager: daily/hourly token spend tracking with alert thresholds |
prompt-cache.js |
528 | LRU cache keyed on prompt hash, with TTL and size eviction |
deduplication.js |
452 | In-flight deduplication: identical concurrent calls share one API round-trip |
Context Window Manager
Located at src/services/context-manager.js.
Token budgeting algorithm:
ESTIMATE TOKENS
token_count ≈ len(text) / 4 (heuristic: 4 chars per token)
PRIORITY QUEUE
Items are ranked by relevance score (cosineSimilarity-based)
Higher priority items are kept when budget is exceeded
COMPRESSION (when budget exceeded)
target = max_tokens * 0.80
Strategies applied in order:
1. summarize — generate shorter summary of low-priority items
2. extract — keep only key sentences from low-priority items
3. prune — drop lowest-priority items entirely
4. merge — combine similar items into one
Continue until compressed_total < target
TF-IDF Embedding Service (Local, No External API)
Located at src/services/embeddings.js.
TOKENIZATION
WordTokenizer (natural library)
Input: raw text string
Output: array of lowercase word tokens
VECTORIZATION (TF-IDF)
Vocabulary: hash-based term-to-position mapping
Dimensions: 128
TF: term frequency within document
IDF: log(N / df) where N = corpus size, df = document frequency
NORMALIZATION
L2-normalize output vectors: v / ||v||
This ensures cosine similarity = dot product
STORAGE
Vectors stored in SQLite (memory_short_term / memory_long_term tables)
Persistent similarity search without external vector DB
Cosine similarity: dot(v1, v2) / (||v1|| * ||v2||) — simplified to dot(v1, v2) after L2 normalization.
Obsidian File-Based Sync
Current Implementation (Operational)
Two mechanisms:
- File copy + git auto-commit
docs/is source of truth- Vault receives copies via
robocopy/xcopy(Windows) or equivalent - Event triggers:
session.end,roadmap.exported,task.sync - Manual sync: invoke robocopy command pattern directly
- Obsidian plugin with MCP-based bidirectional sync (
integrations/obsidian-plugin/)- Connects to Colibri via MCP stdio transport (
AmsMcpClient) BidirectionalSyncEngine: tracks pending changes, detects conflicts- Offline queue (
OfflineQueue) for disconnected editing ConflictResolverwith 4 strategies:
- Connects to Colibri via MCP stdio transport (
| Strategy | Behavior |
|---|---|
server_wins |
AMS state always takes precedence |
client_wins |
Local Obsidian edits always take precedence |
timestamp_wins |
Most recent edit (by modified timestamp) wins |
manual |
Surface conflict to user via ConflictResolutionModal |
- 8 views, 29 commands
- No real-time push, no CRDT, no WebSocket transport, no Yjs
Planned Design (Not Implemented)
CRDT/OT vault sync design:
- Text fields: Yjs CRDT (operation-based merging)
- Structured fields: Operational Transformation with causal ordering
- Transport: WebSocket push, SSE fallback
- 3-tier conflict resolution: auto (CRDT/OT) → smart merge (heuristic) → manual
Status: Zero Node.js implementation. No Yjs library, no OT engine, no WebSocket sync in src/.
See Also
-
[[concepts/ν-integrations ν Integrations]] — concept overview -
[[extractions/alpha-system-core-extraction α Core Extraction]] — MCP bridge and middleware details -
[[architecture/obsidian-sync Obsidian Sync Architecture]] — sync mechanism and planned CRDT/OT design -
[[architecture/claude-api Claude API Integration]] — Claude wrapper controller details -
[[spec/s17-mcp-surface S17 MCP Surface]] — tool surface specification