Skip to main content

max / makenotwork

4.4 KB · 83 lines History Blame Raw
1 # Kberg
2
3 MCP bridge for connecting local LLMs to desktop apps.
4
5 Named after Königsberg — the city whose seven bridges seeded graph theory (Euler, 1736). The library is a bridge in that sense: it routes tool-call edges between an LLM node and a set of app nodes.
6
7 ## Ships
8
9 - `Tool` trait + `ToolRegistry` — the app-side action surface.
10 - `ResourceRegistry` — the app-side object surface: live things a client lists, reads, and subscribes to. Dynamic (register/remove at runtime); `notify_updated` pushes a change to subscribed clients.
11 - Streamable HTTP MCP server (JSON-RPC 2.0) — how any MCP-speaking client reaches your app. POST for requests, a GET SSE stream for server-initiated notifications, DELETE to end a session.
12 - Provider-agnostic `Agent` + `InferenceProvider` trait — the tool-use loop is decoupled from the LLM backend.
13 - `provider::ollama::OllamaProvider` — reference implementation for a local Ollama server.
14
15 ## Scope
16
17 Kberg is a *bridge*, not a model manager. You bring the inference endpoint (a local Ollama, LM Studio, vLLM, or a hosted API); Kberg wires it to the app-side tool surface. Future providers (OpenAI, Anthropic, OpenAI-compatible) drop in behind `InferenceProvider` without touching the agent loop.
18
19 ## Guardrails
20
21 Every tool is classified when it's registered:
22
23 | Kind | Meaning |
24 |---|---|
25 | `Read` | No state change. Freely callable subject to app-level connection auth. |
26 | `Write(WriteCapability)` | Mutates app state. Bound to a named capability, granted per session. |
27
28 Writes are the finite, app-declared vocabulary of permissions the LLM can be given — webhook-style. A driver session holds a `HashSet<String>` of granted capability IDs; any write tool call whose capability is not in the set is refused with a stable, model-visible error.
29
30 Capability IDs are a public contract the app owns. Renaming means a new capability + a deprecated old one — you do not silently reassign an existing id.
31
32 ## v1 primitive matrix
33
34 | Primitive | Status | Purpose |
35 |---|---|---|
36 | `Tool` + `ToolRegistry` | shipped | register app functions as MCP tools |
37 | `ToolKind::Read / Write(capability)` | shipped | webhook-style write permissions |
38 | Streamable HTTP MCP server | shipped | speak MCP over local HTTP (POST + GET SSE + DELETE) |
39 | `ResourceRegistry` (list / read) | shipped | expose live objects a client lists and reads |
40 | Resource subscriptions + server push | shipped | `resources/subscribe` + `notifications/resources/updated` over SSE |
41 | Request cancellation | shipped | `notifications/cancelled` both ways; app aborts an in-flight call and tells the client |
42 | `InferenceProvider` + `Agent` | shipped | provider-agnostic tool-use loop |
43 | Ollama provider | shipped | drive tools from a local Ollama model |
44 | Hard refusals (`Refusal`) | shipped | registered "not offered" tools with stable reason |
45 | Compact surface projection | shipped | `SurfaceProjection::Compact` filters to `small_model_safe` tools |
46 | Handles | planned | opaque, wire-safe entity IDs (never leak SHA-256 / row PKs to the model) |
47 | Preview / commit | planned | two-step writes: dry-run returns a preview, commit executes |
48 | Scope | planned | first-class scope arg (`book`, `library`, `inbox`) so small models don't re-specify it |
49 | Human-confirm gating | planned | writes above app-defined thresholds return `pending_human_confirm(ticket)` |
50 | Audit log | planned | every call recorded, especially writes |
51 | Sidecar aggregator | planned | one driver, N apps, namespaced tool ids |
52 | Additional providers | planned | OpenAI, Anthropic, generic OpenAI-compatible |
53
54 ## Layout
55
56 ```
57 src/
58 lib.rs
59 error.rs
60 tool.rs # Tool, ToolKind, WriteCapability, ToolRegistry, Refusal, SurfaceProjection
61 resource.rs # ResourceRegistry, ResourceDescriptor, ResourceContents (+ notify_updated)
62 agent.rs # Agent, InferenceProvider, Message, RunOutcome
63 server/ # feature = "server"
64 mod.rs # POST/GET-SSE/DELETE routes, JSON-RPC dispatch
65 protocol.rs
66 session.rs # per-session subscriptions, SSE out channel, cancellation
67 stdio.rs
68 provider/ # provider adapters (feature-gated)
69 mod.rs
70 ollama.rs # feature = "ollama"
71 examples/
72 toy.rs # end-to-end: register tools, serve, drive via Ollama
73 ```
74
75 ## Example
76
77 ```
78 ollama pull qwen2.5
79 cargo run --example toy
80 ```
81
82 Override the model with `KBERG_MODEL=llama3.2 cargo run --example toy`.
83