Tools & Platform Client

Your agent reaches Sharely.ai through two layers:

  • @sharelyai/api — a typed, request-scoped client for the platform's Agent API (threads, messages, RAG). Available on every request as input.context.api.
  • @sharelyai/tools — first-party Sharely tool definitions (name, description, JSON input schema) plus a pluggable executor registry, ready to hand to your LLM's tool-use loop.

All calls forward the incoming user's token, so results are automatically scoped to that user's RBAC role — your agent cannot accidentally retrieve content the user isn't allowed to see.

The Platform Client (SharelyAPIClient)

MethodUnderlying endpointPurpose
threads.create({ title, ... })POST /v1/workspaces/{id}/agent/threadsCreate a conversation thread
threads.list({ limit, cursor, ... })GET /v1/workspaces/{id}/agent/threadsList threads (cursor-paginated)
threads.get(threadId)GET /v1/workspaces/{id}/agent/threads/{threadId}Thread with full message history
threads.messages.create(threadId, msg)POST /v1/workspaces/{id}/agent/threads/{threadId}/messagesPersist a message
rag({ text, topK, languageId })POST /v1/workspaces/{id}/agent/ragRole-scoped semantic retrieval

In normal operation you rarely call threads.* yourself — the server runtime persists your event stream automatically. The method you'll use constantly is rag():

const matches = await input.context.api.rag({
  text: input.message,
  topK: 5,
});
// matches: [{ id, score, metadata: { text, source, knowledgeId, ... } }]

See the Agent API reference for full request/response contracts.

First-Party Tools

@sharelyai/tools ships definitions for seven Sharely tools:

ToolPurposePlatform-backed executor included?
semantic_searchVector search over workspace knowledge✅ — wired to rag() via createPlatformExecutors
search_knowledgeKeyword/title searchBring your own executor
get_knowledge_itemRetrieve a single knowledge itemBring your own executor
list_taxonomiesBrowse taxonomiesBring your own executor
get_taxonomy_knowledgeKnowledge filtered by taxonomyBring your own executor
get_workspace_statsWorkspace metricsBring your own executor
list_rolesRBAC roles in the workspaceBring your own executor

Wiring tools into your agent

import { createTools, createPlatformExecutors } from '@sharelyai/tools';
 
const tools = createTools({
  // semantic_search executes against the platform's RAG endpoint
  ...createPlatformExecutors(input.context.api),
 
  // supply custom executors for anything else
  search_knowledge: async (toolInput, ctx) => {
    return await myKeywordSearch(toolInput.query, ctx);
  },
});

The definitions are plain JSON-schema tool specs, so they plug directly into Anthropic's tools parameter, OpenAI function calling, Vercel AI SDK tools, or LangChain tool nodes.

Executing first-party tools over REST

Tools can also be executed without the SDK via the platform's tool execution endpoint — useful for non-TypeScript agents:

curl -X POST \
  'https://api.sharely.ai/v1/workspaces/{workspaceId}/agent/tools/semantic_search/execute' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "input": { "text": "how do refunds work", "topK": 5 },
    "context": { "languageId": "en" }
  }'

See Execute Tool for the full catalog of input/output shapes.

RBAC in Practice

When the workspace has RBAC enabled (rbacStatus: "ACTIVE"):

  • The user's roleId rides along in AgentContext.roleId
  • rag() and semantic_search results are filtered to knowledge assigned to that role
  • Threads are bound to the creating role; a token with a different role cannot read them

You can also branch agent behavior by role — different tools, prompts, or guardrails per role — since the role is just a field on the context:

const handler: Handler = async function* (input) {
  const agent = input.context.roleId === FINANCE_ROLE_ID
    ? financeAgent
    : generalAgent;
  yield* agent(input);
};

Next Steps