Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/content/docs/getting-started/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ Install and use OCP libraries for API tool discovery and context management.

## Installation & Quick Start

{{< tabs items="Python,JavaScript,VS Code" >}}
{{< tabs >}}

{{< tab >}}
{{< tab name="Python" >}}
**Prerequisites:** Python 3.8+

```bash
Expand Down Expand Up @@ -51,7 +51,7 @@ result = agent.call_tool("findPetsByStatus", {"status": "available"}))
```
{{< /tab >}}

{{< tab >}}
{{< tab name="JavaScript" >}}
**Prerequisites:** Node.js 16+

```bash
Expand Down Expand Up @@ -89,7 +89,7 @@ const result = await agent.callTool('findPetsByStatus', {status: 'available'});
```
{{< /tab >}}

{{< tab >}}
{{< tab name="VS Code" >}}
**Prerequisites:** VS Code

```bash
Expand Down
146 changes: 110 additions & 36 deletions docs/content/docs/tool-discovery/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,42 +31,116 @@ agent.call_tool("createPaymentIntent", {"amount": 2000})
- **Automatic Caching**: Specs cached locally for 7 days with configurable expiration
- **Built-in Validation**: Parameters validated against OpenAPI schemas automatically

## Tool Naming Rules

OCP generates predictable camelCase tool names from OpenAPI specifications with automatic normalization:

**1. Use `operationId` (when present) with camelCase normalization:**
```yaml
# OpenAPI spec
paths:
/repos/{owner}/{repo}/issues:
get:
operationId: "listRepositoryIssues" # → Tool name: "listRepositoryIssues"
/meta:
get:
operationId: "meta/root" # → Tool name: "metaRoot"
/admin/apps:
put:
operationId: "admin_apps_approve" # → Tool name: "adminAppsApprove"
/accounts:
get:
operationId: "FetchAccount" # → Tool name: "fetchAccount"
```

**2. Generate from HTTP method + path (when `operationId` missing) with camelCase normalization:**
```yaml
# OpenAPI spec # Generated tool name
GET /items # → "getItems"
POST /items # → "postItems"
GET /items/{id} # → "getItemsId"
DELETE /repos/{owner}/{repo} # → "deleteReposOwnerRepo"
```

**Normalization Rules:**
- Special characters (`/`, `_`, `-`, `.`) are removed and surrounding words capitalized
- PascalCase is converted to camelCase (e.g., `FetchAccount` → `fetchAccount`)
- Numbers and version prefixes are preserved (e.g., `v2010/Accounts` → `v2010Accounts`)
- Multiple consecutive separators are collapsed (e.g., `api//users` → `apiUsers`)
## Tool Naming

OCP generates consistent, predictable tool names from path structure regardless of how individual vendors wrote their specs.

The basic pattern is **verb + resource chain** in camelCase:

```
GET /repos/{owner}/{repo}/issues → listRepoIssues
POST /repos/{owner}/{repo}/issues → createRepoIssue
GET /repos/{owner}/{repo}/issues/{id} → getRepoIssue
DELETE /repos/{owner}/{repo}/issues/{id} → deleteRepoIssue
```

The verb comes from the HTTP method (`GET` on a collection → `list`, `GET` on an item → `get`, `POST` → `create`, etc.). Path parameters are dropped. Intermediate container segments — segments that exist only to scope a sub-resource — are skipped. The remaining resource words are singularized (except the final word of a `list` call) and assembled into camelCase.

### API Schema Phenomena

Real-world API schemas present a number of structural patterns that a naive path-to-name mapping can't handle correctly. Here's what OCP addresses and why.

**Path structure noise**

Path parameters and file extensions carry no resource semantics and are stripped before name generation. API-specific path prefixes (version strings, account identifiers) can be configured per API and are stripped too:

```
GET /rest/api/3/issue/{issueId}/remotelink/{linkId} → getIssueRemotelink
(prefix /rest/api/3 configured for Jira)
GET /v1/balance/history → listBalanceHistory
(prefix /v1 configured for Stripe)
```

**Container segments**

Some path segments exist purely to scope a sub-resource — they don't name the thing being acted on. OCP detects and skips these:

```
GET /repos/{owner}/{repo}/issues → listRepoIssues
↑ container ↑ resource
```

Without this, you'd get `listRepoRepoIssues` or similar noise.

**Dot-notation paths**

Slack-style APIs use dots instead of slashes to express hierarchy. OCP treats the dot as a segment boundary:

```
GET /bots.info → getBotInfo
POST /chat.postMessage → createChatMessage
GET /dnd.endDnd → endDnd
```

The action word after the dot becomes the verb when it's a recognized action (e.g. `post`, `end`), and the resource word follows from the remainder.

**Terminal action verbs**

Some paths end in an action word rather than a resource noun. The terminal segment drives the verb, overriding the HTTP method:

```
POST /disputes/{id}/close → closeDispute (not createDispute)
PUT /issues/{id}/lock → lockIssue (not updateIssue)
```

**Collection vs. singleton**

`GET` on a resource-final path usually means a collection (`list`), but some terminal words are semantically singular by nature — they refer to one object, not a set. OCP recognises these and uses `get` instead:

```
GET /users → listUsers (collection)
GET /bots.info → getBotInfo (singleton: info)
GET /repos/{id}/actions/cache/usage → getActionCacheUsage (singleton: usage)
```

Singleton terminals: `info`, `count`, `default`, `usage`, `public-key`.

**Compound resource names**

Resources are often expressed as hyphenated, snake\_case, or camelCase compounds. Inflection and deduplication operate on the tail word only — leaving the prefix intact:

```
GET /repos/{id}/direct-children → listRepoDirectChildren
(children, not childrens)
GET /team.billableInfo → getTeamBillableInfo
(info is uncountable → no plural)
```

**Adjacent prefix repetition**

A common REST convention is for a sub-resource to prefix itself with its parent's name (`workflow` → `workflowSchemes`, `source` → `source_transactions`). This produces stutter in the assembled name, so OCP collapses it:

```
GET /workflow/{id}/workflowSchemes → listWorkflowSchemes
GET /sources/{source}/source_transactions → listSourceTransactions
```

Non-adjacent repetition is left intact — stripping it would lose structural context:

```
DELETE /issues/{id}/sub-issues/{sub_id} → deleteIssueSubIssue (unchanged)
```

**Inflection irregularities**

Standard pluralization rules break on irregular forms, Latin/Greek words, uncountable nouns, and opaque compound strings. OCP uses a purpose-built inflector that handles these correctly:

```
children → children (irregular, not childrens)
analysis → analyses (Greek -sis → -ses)
datum → datums (geographic datum, not data)
info → info (uncountable)
```

## Handling Tool Conflicts

Expand Down
2 changes: 1 addition & 1 deletion docs/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ module github.com/opencontextprotocol/specification

go 1.24.1

require github.com/imfing/hextra v0.11.1 // indirect
require github.com/imfing/hextra v0.12.1 // indirect
2 changes: 2 additions & 0 deletions docs/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ github.com/imfing/hextra v0.9.5 h1:lG6wnklT9PNLepq69Gj3GZyHRUkBWwv6bkPVL9yAcIQ=
github.com/imfing/hextra v0.9.5/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI=
github.com/imfing/hextra v0.11.1 h1:8pTc4ReYbzGTHAnyiebmlT3ijFfIXiGu1r7tM/UGjFI=
github.com/imfing/hextra v0.11.1/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI=
github.com/imfing/hextra v0.12.1 h1:3t1n0bmJbDzSTVfht93UDcfF1BXMRjeFojA071ri2l8=
github.com/imfing/hextra v0.12.1/go.mod h1:vi+yhpq8YPp/aghvJlNKVnJKcPJ/VyAEcfC1BSV9ARo=
Loading
Loading