@aurite-ai/kai 0.2.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +190 -0
  2. package/dist/kai-mcp.cjs +1652 -0
  3. package/dist/kai-mcp.cjs.map +7 -0
  4. package/dist/templates/copilot-configs/claude-code/.claude/CLAUDE.md +272 -0
  5. package/dist/templates/copilot-configs/claude-code/.claude/agents/architect.md +133 -0
  6. package/dist/templates/copilot-configs/claude-code/.claude/agents/implementer.md +88 -0
  7. package/dist/templates/copilot-configs/claude-code/.claude/settings.json +87 -0
  8. package/dist/templates/copilot-configs/claude-code/.claude/skills/documentation/SKILL.md +54 -0
  9. package/dist/templates/copilot-configs/claude-code/.claude/skills/verification/SKILL.md +125 -0
  10. package/dist/templates/frameworks/langgraph/README.md +118 -0
  11. package/dist/templates/frameworks/langgraph/main.py +97 -0
  12. package/dist/templates/frameworks/langgraph/pyproject.toml +29 -0
  13. package/dist/templates/frameworks/langgraph/src/agent/__init__.py +31 -0
  14. package/dist/templates/frameworks/langgraph/src/agent/graph.py +257 -0
  15. package/dist/templates/frameworks/langgraph/src/agent/state.py +65 -0
  16. package/dist/templates/frameworks/langgraph/src/agent/tools.py +30 -0
  17. package/dist/templates/frameworks/openai/README.md +131 -0
  18. package/dist/templates/frameworks/openai/main.py +80 -0
  19. package/dist/templates/frameworks/openai/pyproject.toml +28 -0
  20. package/dist/templates/frameworks/openai/src/agent/__init__.py +18 -0
  21. package/dist/templates/frameworks/openai/src/agent/agents.py +122 -0
  22. package/dist/templates/frameworks/openai/src/agent/tools.py +100 -0
  23. package/dist/templates/index.d.ts +85 -0
  24. package/dist/templates/index.d.ts.map +1 -0
  25. package/dist/templates/index.js +270 -0
  26. package/dist/templates/index.js.map +1 -0
  27. package/dist/templates/knowledge-base/langgraph-best-practices.mdc +277 -0
  28. package/dist/templates/knowledge-base/openai-agents-overview.mdc +602 -0
  29. package/dist/templates/project-env +7 -0
  30. package/dist/templates/project-gitignore +26 -0
  31. package/package.json +66 -0
@@ -0,0 +1,602 @@
1
+ ---
2
+ type: knowledge
3
+ title: OpenAI Agents Overview
4
+ summary: >
5
+ Comprehensive reference for building with the OpenAI Agent SDK
6
+ created_at: "2026-03-06T00:00:00Z"
7
+ updated_at: "2026-03-06T00:00:00Z"
8
+
9
+ source:
10
+ file: openai-agents-overview.mdc
11
+ project: null
12
+ path: null
13
+
14
+ classification:
15
+ category: reference
16
+ confidence: 1.0
17
+ reasoning: >
18
+ Seed content providing technical reference documentation for the OpenAI
19
+ Agents SDK.
20
+ topics:
21
+ - OpenAI
22
+ - Agents
23
+ - Python AI Agents
24
+
25
+ status: active
26
+ ---
27
+
28
+ # OpenAI Agents SDK - Development Overview
29
+
30
+ A comprehensive guide to building AI agents with the OpenAI Agents SDK.
31
+
32
+ ---
33
+
34
+ ## Quick Start
35
+
36
+ ### Setup
37
+
38
+ ```bash
39
+ # Create project and virtual environment
40
+ mkdir my_project && cd my_project
41
+ python -m venv .venv
42
+ source .venv/bin/activate
43
+
44
+ # Install SDK
45
+ pip install openai-agents
46
+
47
+ # Set API key
48
+ export OPENAI_API_KEY=sk-...
49
+ ```
50
+
51
+ ### Basic Agent
52
+
53
+ Agents are defined with a name, instructions, and optional configuration:
54
+
55
+ ```python
56
+ import asyncio
57
+ from agents import Agent, Runner
58
+
59
+ agent = Agent(
60
+ name="History Tutor",
61
+ instructions="You answer history questions clearly and concisely.",
62
+ )
63
+
64
+ async def main():
65
+ result = await Runner.run(agent, "When did the Roman Empire fall?")
66
+ print(result.final_output)
67
+
68
+ if __name__ == "__main__":
69
+ asyncio.run(main())
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Core Concepts
75
+
76
+ ### The Agent Loop
77
+
78
+ When you call `Runner.run()`, the SDK executes a loop:
79
+
80
+ 1. Call the LLM for the current agent with current input
81
+ 2. Process the LLM output:
82
+ - **Final output** → Loop ends, return result
83
+ - **Handoff** → Update agent and input, continue loop
84
+ - **Tool calls** → Execute tools, append results, continue loop
85
+ 3. If `max_turns` exceeded → Raise `MaxTurnsExceeded` exception
86
+
87
+ ### Runner Methods
88
+
89
+ Three ways to run agents:
90
+
91
+ | Method | Type | Returns | Use Case |
92
+ |--------|------|---------|----------|
93
+ | `Runner.run()` | Async | `RunResult` | Standard async execution |
94
+ | `Runner.run_sync()` | Sync | `RunResult` | Synchronous wrapper |
95
+ | `Runner.run_streamed()` | Async | `RunResultStreaming` | Streaming LLM events |
96
+
97
+ ---
98
+
99
+ ## Tools
100
+
101
+ ### Function Tools
102
+
103
+ Use the `@function_tool` decorator to give agents capabilities:
104
+
105
+ ```python
106
+ from typing import Annotated
107
+ from pydantic import BaseModel, Field
108
+ from agents import Agent, Runner, function_tool
109
+
110
+ class Weather(BaseModel):
111
+ city: str = Field(description="The city name")
112
+ temperature_range: str = Field(description="The temperature range in Celsius")
113
+ conditions: str = Field(description="The weather conditions")
114
+
115
+ @function_tool
116
+ def get_weather(city: Annotated[str, "The city to get the weather for"]) -> Weather:
117
+ """Get the current weather information for a specified city."""
118
+ return Weather(
119
+ city=city,
120
+ temperature_range="14-20C",
121
+ conditions="Sunny with wind."
122
+ )
123
+
124
+ agent = Agent(
125
+ name="Weather Assistant",
126
+ instructions="You are a helpful agent.",
127
+ tools=[get_weather],
128
+ )
129
+
130
+ async def main():
131
+ result = await Runner.run(agent, "What's the weather in Tokyo?")
132
+ print(result.final_output)
133
+ ```
134
+
135
+ **Key Points:**
136
+ - Use type hints and Pydantic models for structured outputs
137
+ - Docstrings become tool descriptions for the LLM
138
+ - Tools are automatically called when the agent needs them
139
+
140
+ ---
141
+
142
+ ## Multi-Agent Patterns
143
+
144
+ ### Pattern 1: Handoffs (Specialist Takes Over)
145
+
146
+ Specialists take over the conversation for their domain:
147
+
148
+ ```python
149
+ from agents import Agent
150
+
151
+ # Define specialist agents
152
+ history_tutor = Agent(
153
+ name="History Tutor",
154
+ handoff_description="Specialist agent for historical questions",
155
+ instructions="You answer history questions clearly and concisely.",
156
+ )
157
+
158
+ math_tutor = Agent(
159
+ name="Math Tutor",
160
+ handoff_description="Specialist agent for math questions",
161
+ instructions="You explain math step by step and include worked examples.",
162
+ )
163
+
164
+ # Define routing agent
165
+ triage_agent = Agent(
166
+ name="Triage Agent",
167
+ instructions="Route each homework question to the right specialist.",
168
+ handoffs=[history_tutor, math_tutor],
169
+ )
170
+
171
+ async def main():
172
+ result = await Runner.run(
173
+ triage_agent,
174
+ "Who was the first president of the United States?",
175
+ )
176
+ print(result.final_output)
177
+ print(f"Answered by: {result.last_agent.name}")
178
+ ```
179
+
180
+ **When to use:** The specialist should own the final answer for that part of the conversation.
181
+
182
+ ### Pattern 2: Agents as Tools (Orchestrator Controls)
183
+
184
+ An orchestrator stays in control and calls specialists as tools. See the SDK documentation for details on this manager-style pattern.
185
+
186
+ **When to use:** You want centralized control with the orchestrator owning the final answer.
187
+
188
+ ---
189
+
190
+ ## Conversation Management
191
+
192
+ ### Strategy Comparison
193
+
194
+ | Strategy | State Location | Best For | Next Turn Input |
195
+ |----------|---------------|----------|-----------------|
196
+ | `result.to_input_list()` | Your app memory | Manual control, any provider | Previous list + new message |
197
+ | `session` | Your storage + SDK | Persistent chat, resumable runs | Same session instance |
198
+ | `conversation_id` | OpenAI server | Named server-side conversation | Same ID + new message only |
199
+ | `previous_response_id` | OpenAI server | Lightweight continuation | Last response ID + new message |
200
+
201
+ ### Manual History Management
202
+
203
+ ```python
204
+ async def main():
205
+ agent = Agent(name="Assistant", instructions="Reply very concisely.")
206
+
207
+ # First turn
208
+ result = await Runner.run(agent, "What city is the Golden Gate Bridge in?")
209
+ print(result.final_output) # San Francisco
210
+
211
+ # Second turn - manually manage history
212
+ new_input = result.to_input_list() + [
213
+ {"role": "user", "content": "What state is it in?"}
214
+ ]
215
+ result = await Runner.run(agent, new_input)
216
+ print(result.final_output) # California
217
+ ```
218
+
219
+ ### Automatic Session Management
220
+
221
+ ```python
222
+ from agents import Agent, Runner, SQLiteSession
223
+
224
+ async def main():
225
+ agent = Agent(name="Assistant", instructions="Reply very concisely.")
226
+ session = SQLiteSession("conversation_123")
227
+
228
+ # First turn
229
+ result = await Runner.run(
230
+ agent,
231
+ "What city is the Golden Gate Bridge in?",
232
+ session=session
233
+ )
234
+ print(result.final_output) # San Francisco
235
+
236
+ # Second turn - session automatically handles history
237
+ result = await Runner.run(
238
+ agent,
239
+ "What state is it in?",
240
+ session=session
241
+ )
242
+ print(result.final_output) # California
243
+ ```
244
+
245
+ ### Server-Managed Conversations
246
+
247
+ **Using conversation_id:**
248
+ ```python
249
+ from agents import Agent, Runner
250
+ from openai import AsyncOpenAI
251
+
252
+ client = AsyncOpenAI()
253
+
254
+ async def main():
255
+ agent = Agent(name="Assistant", instructions="Reply very concisely.")
256
+
257
+ # Create server-managed conversation
258
+ conversation = await client.conversations.create()
259
+ conv_id = conversation.id
260
+
261
+ while True:
262
+ user_input = input("You: ")
263
+ result = await Runner.run(agent, user_input, conversation_id=conv_id)
264
+ print(f"Assistant: {result.final_output}")
265
+ ```
266
+
267
+ **Using previous_response_id:**
268
+ ```python
269
+ async def main():
270
+ agent = Agent(name="Assistant", instructions="Reply very concisely.")
271
+ previous_response_id = None
272
+
273
+ while True:
274
+ user_input = input("You: ")
275
+ result = await Runner.run(
276
+ agent,
277
+ user_input,
278
+ previous_response_id=previous_response_id,
279
+ auto_previous_response_id=True,
280
+ )
281
+ previous_response_id = result.last_response_id
282
+ print(f"Assistant: {result.final_output}")
283
+ ```
284
+
285
+ ---
286
+
287
+ ## Streaming
288
+
289
+ Stream LLM events as they arrive:
290
+
291
+ ```python
292
+ from openai.types.responses import ResponseTextDeltaEvent, ResponseContentPartDoneEvent
293
+ from agents import Agent, Runner, RawResponsesStreamEvent
294
+
295
+ async def main():
296
+ agent = Agent(name="Assistant", instructions="Be helpful.")
297
+
298
+ result = Runner.run_streamed(agent, "Tell me about Python.")
299
+
300
+ async for event in result.stream_events():
301
+ if not isinstance(event, RawResponsesStreamEvent):
302
+ continue
303
+ data = event.data
304
+ if isinstance(data, ResponseTextDeltaEvent):
305
+ print(data.delta, end="", flush=True)
306
+ elif isinstance(data, ResponseContentPartDoneEvent):
307
+ print("\n")
308
+ ```
309
+
310
+ ---
311
+
312
+ ## Configuration
313
+
314
+ ### RunConfig
315
+
316
+ Configure global settings for a run:
317
+
318
+ ```python
319
+ from agents import Agent, Runner, RunConfig
320
+
321
+ agent = Agent(name="Assistant", instructions="Be concise.")
322
+
323
+ result = await Runner.run(
324
+ agent,
325
+ "Explain quantum computing",
326
+ run_config=RunConfig(
327
+ model="gpt-4", # Override model
328
+ max_turns=10, # Limit turns
329
+ tracing_disabled=False, # Enable tracing
330
+ workflow_name="QA Bot", # Name for traces
331
+ )
332
+ )
333
+ ```
334
+
335
+ **Key Configuration Options:**
336
+
337
+ - **Model settings:** `model`, `model_provider`, `model_settings`
338
+ - **Guardrails:** `input_guardrails`, `output_guardrails`
339
+ - **Handoff control:** `handoff_input_filter`, `nest_handoff_history`
340
+ - **Tracing:** `tracing`, `workflow_name`, `trace_id`, `trace_metadata`
341
+ - **Hooks:** `call_model_input_filter`, `session_input_callback`
342
+
343
+ ### Input Filtering
344
+
345
+ Edit model input before the LLM call:
346
+
347
+ ```python
348
+ from agents import RunConfig
349
+ from agents.run import CallModelData, ModelInputData
350
+
351
+ def drop_old_messages(data: CallModelData[None]) -> ModelInputData:
352
+ # Keep only last 5 items
353
+ trimmed = data.model_data.input[-5:]
354
+ return ModelInputData(
355
+ input=trimmed,
356
+ instructions=data.model_data.instructions
357
+ )
358
+
359
+ result = await Runner.run(
360
+ agent,
361
+ "Explain quines",
362
+ run_config=RunConfig(call_model_input_filter=drop_old_messages),
363
+ )
364
+ ```
365
+
366
+ ---
367
+
368
+ ## Error Handling
369
+
370
+ ### Common Exceptions
371
+
372
+ - `AgentsException`: Base class for all SDK exceptions
373
+ - `MaxTurnsExceeded`: Agent exceeded turn limit
374
+ - `ModelBehaviorError`: LLM produced unexpected output (malformed JSON, unexpected tool failures)
375
+ - `ToolTimeoutError`: Tool call exceeded timeout
376
+ - `UserError`: Incorrect SDK usage
377
+ - `InputGuardrailTripwireTriggered`, `OutputGuardrailTripwireTriggered`: Guardrail conditions met
378
+
379
+ ### Error Handlers
380
+
381
+ Handle errors gracefully instead of raising exceptions:
382
+
383
+ ```python
384
+ from agents import (
385
+ Agent,
386
+ RunErrorHandlerInput,
387
+ RunErrorHandlerResult,
388
+ Runner,
389
+ )
390
+
391
+ def on_max_turns(_data: RunErrorHandlerInput[None]) -> RunErrorHandlerResult:
392
+ return RunErrorHandlerResult(
393
+ final_output="I couldn't finish within the turn limit. Please narrow the request.",
394
+ include_in_history=False,
395
+ )
396
+
397
+ result = Runner.run_sync(
398
+ agent,
399
+ "Analyze this long transcript",
400
+ max_turns=3,
401
+ error_handlers={"max_turns": on_max_turns},
402
+ )
403
+ ```
404
+
405
+ ---
406
+
407
+ ## Advanced Features
408
+
409
+ ### WebSocket Transport
410
+
411
+ Use WebSocket for better performance with the Responses API:
412
+
413
+ ```python
414
+ from agents import Agent, responses_websocket_session
415
+
416
+ async def main():
417
+ agent = Agent(name="Assistant", instructions="Be concise.")
418
+
419
+ async with responses_websocket_session() as ws:
420
+ first = ws.run_streamed(agent, "Say hello in one short sentence.")
421
+ async for _event in first.stream_events():
422
+ pass
423
+
424
+ second = ws.run_streamed(
425
+ agent,
426
+ "Now say goodbye.",
427
+ previous_response_id=first.last_response_id,
428
+ )
429
+ async for _event in second.stream_events():
430
+ pass
431
+ ```
432
+
433
+ ### Durable Execution
434
+
435
+ For long-running workflows with human-in-the-loop, the SDK integrates with:
436
+
437
+ - **Temporal**: Durable workflows with retries and restarts
438
+ - **Restate**: Lightweight durable agents with single-binary runtime (requires Restate runtime)
439
+ - **DBOS**: Reliable agents with SQLite/Postgres persistence (preserves progress across failures)
440
+
441
+ These integrations support tool approval pause/resume patterns, handoffs, and session management.
442
+
443
+ ---
444
+
445
+ ## Complete Examples
446
+
447
+ ### Hello World
448
+ ```python
449
+ import asyncio
450
+ from agents import Agent, Runner
451
+
452
+ async def main():
453
+ agent = Agent(
454
+ name="Assistant",
455
+ instructions="You only respond in haikus.",
456
+ )
457
+
458
+ result = await Runner.run(agent, "Tell me about recursion in programming.")
459
+ print(result.final_output)
460
+ # Function calls itself,
461
+ # Looping in smaller pieces,
462
+ # Endless by design.
463
+
464
+ if __name__ == "__main__":
465
+ asyncio.run(main())
466
+ ```
467
+
468
+ ### Multi-Agent Routing with Streaming
469
+ ```python
470
+ import asyncio
471
+ import uuid
472
+ from openai.types.responses import ResponseTextDeltaEvent, ResponseContentPartDoneEvent
473
+ from agents import Agent, RawResponsesStreamEvent, Runner, trace
474
+
475
+ # Define language-specific agents
476
+ french_agent = Agent(
477
+ name="french_agent",
478
+ instructions="You only speak French",
479
+ )
480
+
481
+ spanish_agent = Agent(
482
+ name="spanish_agent",
483
+ instructions="You only speak Spanish",
484
+ )
485
+
486
+ english_agent = Agent(
487
+ name="english_agent",
488
+ instructions="You only speak English",
489
+ )
490
+
491
+ # Define routing agent
492
+ triage_agent = Agent(
493
+ name="triage_agent",
494
+ instructions="Handoff to the appropriate agent based on the language of the request.",
495
+ handoffs=[french_agent, spanish_agent, english_agent],
496
+ )
497
+
498
+ async def main():
499
+ conversation_id = str(uuid.uuid4().hex[:16])
500
+
501
+ msg = "Hello, how do I say good evening in French?"
502
+ agent = triage_agent
503
+ inputs = [{"content": msg, "role": "user"}]
504
+
505
+ while True:
506
+ # Each turn is a single trace
507
+ with trace("Routing example", group_id=conversation_id):
508
+ result = Runner.run_streamed(agent, input=inputs)
509
+
510
+ async for event in result.stream_events():
511
+ if not isinstance(event, RawResponsesStreamEvent):
512
+ continue
513
+ data = event.data
514
+ if isinstance(data, ResponseTextDeltaEvent):
515
+ print(data.delta, end="", flush=True)
516
+ elif isinstance(data, ResponseContentPartDoneEvent):
517
+ print("\n")
518
+
519
+ inputs = result.to_input_list()
520
+ user_msg = input("Enter a message: ")
521
+ inputs.append({"content": user_msg, "role": "user"})
522
+ agent = result.current_agent
523
+
524
+ if __name__ == "__main__":
525
+ asyncio.run(main())
526
+ ```
527
+
528
+ ---
529
+
530
+ ## Best Practices
531
+
532
+ 1. **Start Simple**: Begin with a single agent before adding tools or handoffs
533
+ 2. **Use Type Hints**: Leverage Pydantic models for structured tool outputs
534
+ 3. **Choose One Memory Strategy**: Don't mix client-managed and server-managed state
535
+ 4. **Enable Tracing**: Set `workflow_name` in RunConfig for observability
536
+ 5. **Handle Errors**: Use error handlers for graceful degradation
537
+ 6. **Stream When Possible**: Better UX with streaming for long responses
538
+ 7. **Test Tool Calls**: Verify tools work independently before integrating
539
+
540
+ ---
541
+
542
+ ## Quick Reference
543
+
544
+ ### Essential Imports
545
+ ```python
546
+ from agents import (
547
+ Agent, # Define agents
548
+ Runner, # Execute agents
549
+ function_tool, # Create tools
550
+ RunConfig, # Configure runs
551
+ SQLiteSession, # Session management
552
+ trace, # Tracing context
553
+ )
554
+ ```
555
+
556
+ ### Common Patterns
557
+ ```python
558
+ # Basic run
559
+ result = await Runner.run(agent, "user message")
560
+
561
+ # With session
562
+ result = await Runner.run(agent, "message", session=session)
563
+
564
+ # With streaming
565
+ result = Runner.run_streamed(agent, "message")
566
+ async for event in result.stream_events():
567
+ # Process events
568
+ pass
569
+
570
+ # Multi-turn
571
+ inputs = result.to_input_list() + [{"role": "user", "content": "next message"}]
572
+ result = await Runner.run(agent, inputs)
573
+ ```
574
+
575
+ ---
576
+
577
+ ## Additional Notes
578
+
579
+ ### Session Persistence
580
+
581
+ Sessions automatically:
582
+ - Retrieve conversation history before each run
583
+ - Store new messages after each run
584
+ - Maintain separate conversations for different session IDs
585
+
586
+ **Important**: Session persistence cannot be combined with server-managed conversation settings (`conversation_id`, `previous_response_id`, or `auto_previous_response_id`) in the same run.
587
+
588
+ ### Nested Handoffs
589
+
590
+ Nested handoffs are available as an opt-in beta. Enable collapsed-transcript behavior by passing `RunConfig(nest_handoff_history=True)` or set `handoff(..., nest_handoff_history=True)` for specific handoffs. By default, the raw transcript is passed through.
591
+
592
+ ### Reasoning Item ID Policy
593
+
594
+ Control how reasoning items are converted into next-turn model input:
595
+ - `None` or `"preserve"` (default): Keep reasoning item IDs
596
+ - `"omit"`: Strip reasoning item IDs from generated next-turn input
597
+
598
+ Use `"omit"` as an opt-in mitigation for Responses API 400 errors where a reasoning item is sent with an ID but without the required following item.
599
+
600
+ ### Conversation Locking
601
+
602
+ The SDK automatically retries `conversation_locked` errors with backoff. In server-managed conversation runs, it rewinds the internal conversation-tracker input before retrying. In local session-based runs, it performs best-effort rollback of recently persisted input items to reduce duplicate history entries.
@@ -0,0 +1,7 @@
1
+ # Anthropic API Key - add your key if your agent uses an Anthropic model
2
+
3
+ ANTHROPIC_API_KEY=
4
+
5
+ # OpenAI API Key - add your key if your agent uses an OpenAI model
6
+
7
+ OPENAI_API_KEY=
@@ -0,0 +1,26 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ .venv/
6
+ venv/
7
+ .pytest_cache/
8
+
9
+ # TypeScript/Node
10
+ node_modules/
11
+ dist/
12
+
13
+ # Environment & Secrets
14
+ .env
15
+ .env.*
16
+ *.pem
17
+ *.key
18
+
19
+ # IDE (optional - uncomment if desired)
20
+ # .idea/
21
+ # .vscode/
22
+
23
+ # OS
24
+ .DS_Store
25
+ Thumbs.db
26
+ .kai-test.json
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@aurite-ai/kai",
3
+ "version": "0.2.0-dev.0",
4
+ "description": "Kai MCP server - context management tools for coding copilots",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Kai Team",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Aurite-ai/kai.git",
11
+ "directory": "apps/mcp"
12
+ },
13
+ "homepage": "https://github.com/Aurite-ai/kai#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/Aurite-ai/kai/issues"
16
+ },
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "keywords": [
21
+ "mcp",
22
+ "model-context-protocol",
23
+ "ai",
24
+ "copilot",
25
+ "context-management",
26
+ "claude",
27
+ "anthropic"
28
+ ],
29
+ "main": "./dist/kai-mcp.cjs",
30
+ "bin": {
31
+ "kai-mcp": "dist/kai-mcp.cjs"
32
+ },
33
+ "files": [
34
+ "dist/kai-mcp.cjs",
35
+ "dist/kai-mcp.cjs.map",
36
+ "dist/templates",
37
+ "README.md"
38
+ ],
39
+ "engines": {
40
+ "node": ">=20.0.0"
41
+ },
42
+ "scripts": {
43
+ "build": "tsc",
44
+ "bundle": "tsx scripts/bundle.ts",
45
+ "dev": "tsx watch src/index.ts",
46
+ "start": "node dist/index.js",
47
+ "start:bundle": "node dist/kai-mcp.cjs",
48
+ "test": "vitest run",
49
+ "test:watch": "vitest",
50
+ "typecheck": "tsc --noEmit",
51
+ "prepublishOnly": "pnpm build && pnpm bundle"
52
+ },
53
+ "dependencies": {
54
+ "@anthropic-ai/sdk": "^0.32.1",
55
+ "@modelcontextprotocol/sdk": "^1.0.0",
56
+ "dotenv": "^16.4.0",
57
+ "yaml": "^2.4.0",
58
+ "zod": "^4.3.6"
59
+ },
60
+ "devDependencies": {
61
+ "@types/node": "^22.0.0",
62
+ "esbuild": "^0.27.3",
63
+ "tsx": "^4.19.0",
64
+ "vitest": "^3.1.0"
65
+ }
66
+ }