Skip to content
91 changes: 91 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ asyncio.run(main())
- 📄 **Document Management** - Full CRUD operations with type safety
- 🔍 **Semantic Search** - AI-powered document search
- 🤖 **RAG Integration** - Natural language queries to your knowledge base
- 📋 **Clipboard/Memory** - Persistent key-value storage for MCP tools and AI agents
- 📤 **File Uploads** - Support for various file formats
- 🔄 **Version Control** - Document versioning and history
- ⚡ **Async Support** - Both sync and async clients
Expand Down Expand Up @@ -377,6 +378,96 @@ async def rag_operations():
asyncio.run(rag_operations())
```

### Clipboard Operations

The clipboard provides persistent key-value storage for MCP tools and AI agents.

#### Set Named Entry

```python
entry = client.clipboard.set(
name="user_preferences",
value='{"theme": "dark", "lang": "en"}',
content_type="application/json",
encoding="utf-8",
visibility="private",
ttl_seconds=86400 # 24 hours
)

print(f"Created entry: {entry.uuid}")
print(f"Source: {entry.source}") # 'sdk' - automatically set
```

#### Get Entry

```python
# By name
entry = client.clipboard.get(name="user_preferences")
print(entry.value)

# By index (stack access)
latest = client.clipboard.get(idx=0)
```

#### Push to Stack

```python
entry = client.clipboard.push(
value="Processing step 1 result",
content_type="text/plain"
)

print(f"Pushed to index: {entry.idx}")
```

#### Pop from Stack

```python
entry = client.clipboard.pop()
if entry:
print(f"Popped value: {entry.value}")
```

#### List and Delete

```python
# List all entries
response = client.clipboard.list()
for entry in response.entries:
label = entry.name or f"idx:{entry.idx}"
print(f"{label} - source: {entry.source}")

# Delete by name
client.clipboard.delete(name="old_entry")

# Clear all
client.clipboard.clear_all()
```

#### Clipboard Entry Structure

```python
from pluggedinkit import ClipboardEntry, ClipboardSource

# ClipboardEntry fields:
# - uuid: str
# - name: Optional[str] # Semantic key
# - idx: Optional[int] # Stack index
# - value: str
# - content_type: str
# - encoding: "utf-8" | "base64" | "hex"
# - size_bytes: int
# - visibility: "private" | "workspace" | "public"
# - created_by_tool: Optional[str]
# - created_by_model: Optional[str]
# - source: Optional[ClipboardSource] # Auto-set: ui, sdk, or mcp
# - created_at: datetime
# - updated_at: datetime
# - expires_at: Optional[datetime]
```

> **Note**: The `source` field is automatically set to `ClipboardSource.SDK` when using this SDK. It indicates how the entry was created (UI, SDK, or MCP proxy).

### Error Handling

```python
Expand Down
30 changes: 30 additions & 0 deletions src/pluggedinkit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,22 @@
NotFoundError,
ValidationError,
)
from .services.clipboard import ClearAllResult
from .types import (
# Clipboard types
ClipboardEntry,
ClipboardListResponse,
ClipboardSetRequest,
ClipboardPushRequest,
ClipboardGetFilters,
ClipboardDeleteRequest,
ClipboardResponse,
ClipboardDeleteResponse,
ClipboardEncoding,
ClipboardVisibility,
ClipboardSource,
DEFAULT_CLIPBOARD_SOURCE,
# Document types
Document,
DocumentWithContent,
DocumentListResponse,
Expand All @@ -38,6 +53,21 @@
"RateLimitError",
"NotFoundError",
"ValidationError",
# Clipboard types
"ClipboardEntry",
"ClipboardListResponse",
"ClipboardSetRequest",
"ClipboardPushRequest",
"ClipboardGetFilters",
"ClipboardDeleteRequest",
"ClipboardResponse",
"ClipboardDeleteResponse",
"ClipboardEncoding",
"ClipboardVisibility",
"ClipboardSource",
"ClearAllResult",
"DEFAULT_CLIPBOARD_SOURCE",
# Document types
"Document",
"DocumentWithContent",
"DocumentListResponse",
Expand Down
3 changes: 3 additions & 0 deletions src/pluggedinkit/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
PluggedInError,
RateLimitError,
)
from .services.clipboard import ClipboardService, AsyncClipboardService
from .services.documents import DocumentService, AsyncDocumentService
from .services.rag import RagService, AsyncRagService
from .services.uploads import UploadService, AsyncUploadService
Expand Down Expand Up @@ -96,6 +97,7 @@ def __init__(
)

# Initialize services
self.clipboard = ClipboardService(self)
self.documents = DocumentService(self)
self.rag = RagService(self)
self.uploads = UploadService(self)
Expand Down Expand Up @@ -195,6 +197,7 @@ def __init__(
)

# Initialize async services
self.clipboard = AsyncClipboardService(self)
self.documents = AsyncDocumentService(self)
self.rag = AsyncRagService(self)
self.uploads = AsyncUploadService(self)
Expand Down
4 changes: 4 additions & 0 deletions src/pluggedinkit/services/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
"""Service modules for Plugged.in SDK"""

from .clipboard import AsyncClipboardService, ClearAllResult, ClipboardService
from .documents import AsyncDocumentService, DocumentService
from .rag import AsyncRagService, RagService
from .uploads import AsyncUploadService, UploadService

__all__ = [
"ClipboardService",
"AsyncClipboardService",
"ClearAllResult",
"DocumentService",
"AsyncDocumentService",
"RagService",
Expand Down
Loading
Loading