HarborHarbor
DocumentationGuidesPlugins

harbor.tools

Discover callable tool shapes before executing Harbor code.

Tool discovery and tool execution are separate. Use harbor.tools to search, describe, and inspect schemas; use harbor.runtime.execute to run code against selected source namespaces.

Search is the planning step for apps and agents that need to decide which workspace tool to call:

search-tools.ts
const results = await harbor.tools.search({
  query: 'create a GitHub issue',
  limit: 10,
})

const github = await harbor.tools.describe({
  namespace: 'github',
  tool: 'create_issue',
})

The returned shape is the Harbor control-plane response for that route. For raw generated route access, use harbor.api.requestJson.

Schemas

Always inspect input schemas before constructing dynamic tool calls:

tool-schema.ts
const schema = await harbor.tools.schema({
  namespace: 'github',
  tool: 'create_issue',
})

const allSchemas = await harbor.tools.schemas({
  namespace: 'github',
})

Prefer the schema returned by Harbor over a stale local copy. A workspace can have different plugin versions, OAuth scopes, or source visibility than another workspace.

Execute with bound sources

runtime.execute is the execution boundary. Pass the source namespaces the code needs, then call the discovered tool inside the Harbor runtime:

execute-with-tools.ts
const code = [
  'return await github.create_issue({',
  '  owner: "zonko-ai",',
  '  repo: "harbor",',
  '  title: "Investigate SDK docs drift",',
  '  body: "Created from a Harbor SDK execution."',
  '})',
].join('\n')

const run = await harbor.runtime.execute({
  mode: 'exec',
  sources: [{ namespace: 'github' }],
  code,
})

console.log(run.run_id)
console.log(run.result)

This keeps plugin credentials in Harbor, records the run, and returns typed content blocks for app and agent callers.

Admin operations

Administrative tool operations are explicit:

admin-tools.ts
await harbor.tools.reindex({ namespace: 'github' })
await harbor.tools.add({
  namespace: 'custom',
  name: 'lookup_customer',
  description: 'Lookup a customer by email.',
})

Use these routes for source administration or custom-source registration, not as the normal runtime invocation path.