@penumbra-systems/sdk
v0.2.16
Published
The TypeScript interface to Penumbra. Define Shapes, structure knowledge, and deploy domain-native tools.
Maintainers
Readme
Penumbra SDK
The TypeScript interface to Penumbra.
Define Shapes, structure knowledge, stage graph changes, compile context, and deploy domain-native tools for humans and agents.
New here? Start with the Quickstart: from API key to working agent in 5 minutes.
Installation
npm install @penumbra-systems/sdk@latestimport { Penumbra } from "@penumbra-systems/sdk";
const penumbra = new Penumbra({
apiKey: process.env.PENUMBRA_API_KEY!,
});Penumbra is a programmable meaning layer for AI-native work. The SDK gives you typed access to the core runtime: Shapes for domain structure, Sources for grounding, Workspaces for governed change, Context for agent-ready boundaries, and Tool Surfaces for exposing domain-native capabilities through MCP.
Quick Start
// 1. Define a shape (domain structure)
const shape = await penumbra.shapes.get("customer-research");
// 2. Navigate the knowledge graph
const project = await penumbra.projects.getProject(projectId);
const customers = await project.search({ types: ["Customer"] });
const node = await project.getNode(customerId);
const related = await node.getRelated({
type: "placed",
direction: "outbound",
});
// 3. Extract entities from a file
const result = await penumbra.nodes.fromFile(projectId, {
shapeId: shape.id,
content: fileContent,
extractRelationships: true,
});
// 4. Stage changes in a workspace
const workspace = await project.openWorkspace("Analysis");
await workspace.addEntities(result.entities);
await workspace.submit();
// 5. Generate AI tools from shape
const config = await shape.toGeneration("insight", {
userMessage: "Analyze this feedback",
includeContext: true,
});
const result = await generateObject({ model: openai("gpt-4"), ...config });
// 6. Deploy a scoped MCP tool surface
const surface = await penumbra.tools.create({
projectId,
name: "Account Tracker",
typeBindings: [
{ type_name: "commitment", verbs: ["capture", "list"] },
{ type_name: "meeting_note", verbs: ["capture"] },
],
autoSubmit: true,
enableMemory: true,
});
console.log(surface.url); // → https://tools.pnbr.cloud/{slug}/sse
// 7. Establish a unified context for an agent
const ctx = await penumbra.context.establish({
project: "strategic-landscape",
shape: "competitive-dynamics",
workspace: "acquisition-analysis",
});
const competitors = await ctx.search({ types: ["Competitor"] });
await ctx.capture([{ type: "Insight", properties: { summary: "..." } }]);
await ctx.submit();Core Concepts
| Concept | What it does | SDK Surface |
| ----------------- | ----------------------------------------- | -------------------------------------------------------------- |
| Shapes | Define domain structure and purpose | penumbra.shapes, .design, .relationships, .projections |
| Nodes | Typed entities in the knowledge graph | penumbra.nodes |
| Workspaces | Governed staging for graph changes | penumbra.workspaces |
| Context | Composable boundaries for agent reasoning | penumbra.context, .views, ContextSpec builder |
| Tool Surfaces | Deploy scoped MCP endpoints from shapes | penumbra.tools |
| Sources | Content provenance and extraction | penumbra.sources, .collections |
| Search | Omnisearch with progressive refinement | penumbra.search, penumbra.traverse |
| Agents | Agent lifecycle, configuration, dispatch | penumbra.agents |
Resources
All resources follow the pattern: penumbra.{resource}.{method}()
Knowledge Graph
| Resource | Key Methods |
| ------------------------ | -------------------------------------------------------------------------------------------------------------- |
| penumbra.shapes | get, list, create, update, delete, search, discover, generate, refine, fromWeb, fromFile |
| penumbra.nodes | get, list, create, createBatch, update, delete, search, fromFile, fromWeb |
| penumbra.relationships | create, createBatch, list, update, delete, fromShape, fromNodes |
| penumbra.projects | get, list, create, update, delete, getStats, getManifest |
Workspaces
| Resource | Key Methods |
| --------------------- | --------------------------------------------------------------------------- |
| penumbra.workspaces | open, get, list |
| Instance methods | addEntities, addRelationships, hydrate, validate, submit, close |
Context Pipeline
| Resource | Key Methods |
| ------------------------ | ------------------------------------------------------------------------------------- |
| penumbra.context | establish, discover, spec (fluent builder), preview, compile, materialize |
| penumbra.context.views | list, get, create, update, delete, promote, addNodes, removeNodes |
| penumbra.search | omnisearch (3 depth tiers), rag, index |
| penumbra.traverse | neighborhood, path |
Tools & Agents
| Resource | Key Methods |
| ----------------- | ------------------------------------------------------------- |
| penumbra.tools | all, pick, omit, create, generate, availableTypes |
| penumbra.agents | configure, get, list, listTasks, getTask |
Content & Organizations
| Resource | Key Methods |
| ------------------------ | --------------------------------------------------------------------------------- |
| penumbra.sources | list, get, stage, approve, reject. Collections: list, get, create |
| penumbra.organizations | get, list, getSettings, updateSettings, listMembers |
| penumbra.portals | create, get, list, update |
Shape Transforms
Shapes are bidirectional. Transform domain structure into whatever your stack needs:
const shape = await penumbra.shapes.get("customer-research");
// Output: Shape to your format
shape.toForm(); // React Hook Form schema
shape.toTool(); // AI tool constraint
shape.toZodSchema("type_name"); // Zod validation schema
shape.toSystemPrompt(); // LLM scaffolding
shape.toGeneration("intent", opts); // Complete AI SDK generation config
// Input: Your format to Shape
Shape.fromZod({ name: "API", types: { user: userSchema } });
Shape.fromJsonSchema({ name: "Profile", types: { user: openAPISchema } });
await penumbra.shapes.fromWeb(url);
await penumbra.shapes.generate({ description: "SaaS risk analysis" });Context Compilation
Composable, immutable filter builder for scoping agent context:
const spec = penumbra.context
.spec(["proj-1", "proj-2"])
.withSources(["src-1"])
.withTypes({ mode: "lens", lensId: "qualification" })
.withTemporal({ field: "created_at", start: "2026-01-01" })
.withPropertyFilters([{ path: "risk_level", operator: "gte", value: 7 }]);
const preview = await spec.preview(); // Fast feedback
const compiled = await spec.compile(); // Definitive boundaries
const data = await spec.materialize({ mode: "full" });Semantic Resolution
Pass names where IDs are expected. Resolution happens transparently:
const project = await penumbra.projects.getProject("strategic-landscape");
const shape = await penumbra.shapes.get("risk-framework");Resolution statuses: exact, fuzzy, semantic, ambiguous, not_found.
Requirements
- Node.js 18+
- TypeScript 5+ (recommended)
- Zod 3.20+ (peer dependency)
Support
- Website: getpenumbra.ai
- API Docs: app.getpenumbra.ai/api-docs
- Email: [email protected]
