MCP Object-Authz Lab
Vulnerable-by-design multi-tenant MCP note server for practicing BOLA/IDOR; you can exercise note operations and authorization gaps via 18 tools and 1 resource.
Identify your session (
whoami).List, get, create, update, delete, search, and batch-fetch notes.
Export org notes, including
org_id='*'global export.Use admin/cross-org, foreign-org create, and query-resolved get tools.
Prepare/redeem share grants.
Use HTTP-transport tools:
X-Org-Id-scoped listing and quota-limited creation.Get notes by token scope claim.
Read
note://{token}/{orgId}/{noteId}resources.Run 13 BOLA scenarios locally with vuln/fixed toggles, Semgrep detection rules, and an audit skill.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Object-Authz Labrun the cross-tenant delete exploit"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Object-Authz Lab
A vulnerable-by-design MCP server for practising object-level authorization bugs (BOLA / IDOR, CWE-639, CWE-862) in MCP tools. Thirteen hands-on scenarios, each one a different variant of the bug, each with a vulnerable build and a fixed build.
git clone https://github.com/WRG-11/mcp-objauthz-lab && cd mcp-objauthz-lab
npm install && npm run poc # Node.js 20 or newerThe PoC is an MCP client. It starts the server on your machine and sends the same cross-tenant request to both builds. Two rows of its 38-row output:
SC BUILD ACTION OUTCOME EXPECT OK
S2 vuln note_search scope-as-param (Alice→org_globex) LEAKED LEAKED ✓
S2 fixed note_search scope-as-param (Alice→org_globex) SCOPED SCOPED ✓
Two-way gate: PASS (38/38 rows OK)Same caller, same request: the vulnerable build returns another tenant's notes, the fixed build scopes the result to the caller's own tenant.
Try the scenarios without the answers · Walkthroughs · Hunt checklist
Why this lab exists
Most MCP security attention goes to prompt injection and tool poisoning. Object-level authorization is a different class, and the usual prompt-injection test suites and scanners do not find it. When an MCP server is multi-tenant, every tool that resolves an object from a client-supplied id must verify the caller is allowed to touch that object. Miss the check on a single tool and a caller in one tenant can read or change another tenant's objects.
This is not theoretical. Asana's MCP connector (Jun 2025) leaked data across tenant boundaries for roughly 1,000 customer organizations (Pomerium's writeup). In n8n-mcp, CVE-2026-54052 let any caller read or delete another tenant's stored API keys: sequential integer ids on a table with no tenant-id column. Both are S1/S3-shaped bugs, in production instead of a lab.
Related MCP server: vuln-mcp-server
Try the challenges
The scenarios are in challenges/, with no hints until you
open solutions/. Each runs locally in under 5 minutes.
Scenario | Pattern |
Inconsistent authorization: find the single outlier | |
Client-supplied scope trusted as authorization | |
List→get asymmetry: batch skips per-object check | |
Wildcard/sentinel value bypasses scope filter | |
Role/token-type bypass: admin-named tool, no role check | |
Foreign-parent injection: create trusts a caller-supplied org | |
Unscoped query: tenant key omitted from the filter (the real-world shape) | |
Resource-URI-as-scope: the resources/read surface, not tools/call | |
Authz-from-client-round-tripped-value: an editable share grant | |
Forwarded-header-as-scope: a trusted request header (HTTP transport) | |
X-Forwarded-For quota bypass: a trusted request header for rate limiting (HTTP transport) | |
Batch/bulk endpoint BOLA: multi-object endpoint without per-item tenant filter | |
JWT/token scope confusion: token's scope/aud claim vs actual permissions mismatch |
Walkthroughs with hints and answers are in docs/scenarios.md.
Quickstart (< 5 minutes)
Requirements: Node.js 20 or later.
npm install
npm test # 77 tests: unit, docs-consistency, CI-hardening and PoC-output checks
npm run poc # 38-row two-way gate: the tools/resources wired end-to-end over MCP
npm run poc -- --json-output poc-chain-evidence.json --sarif-output poc-chain-evidence.sarifExpected npm run poc output (38/38 rows, all scenarios + the hardened build):
MCP object-level authorization lab — two-way gate (13 scenarios + hardened build)
SC BUILD ACTION OUTCOME EXPECT OK
S1 vuln note_get cross-tenant (Bob→Acme) DENIED DENIED ✓
S1 vuln note_delete cross-tenant (Bob→Acme) DELETED DELETED ✓
S1 fixed note_delete cross-tenant (Bob→Acme) DENIED DENIED ✓
S1 fixed note_delete same-tenant (Bob→Globex) DELETED DELETED ✓
S2 vuln note_search scope-as-param (Alice→org_globex) LEAKED LEAKED ✓
S2 fixed note_search scope-as-param (Alice→org_globex) SCOPED SCOPED ✓
S3 vuln note_batch_get list→get asymm (Alice+Globex) LEAKED LEAKED ✓
S3 fixed note_batch_get list→get asymm (Alice+Globex) SCOPED SCOPED ✓
S4 vuln note_export wildcard org_id='*' (Alice) LEAKED LEAKED ✓
S4 fixed note_export wildcard org_id='*' (Alice) SCOPED SCOPED ✓
S5 vuln note_admin_get cross-org as Bob (user) LEAKED LEAKED ✓
S5 fixed note_admin_get cross-org as Bob (user) DENIED DENIED ✓
S5 fixed note_admin_get cross-org as Dana (real admin) ALLOWED ALLOWED ✓
S6 vuln note_create_in_org org_id=org_globex (Alice) INJECTED INJECTED ✓
S6 fixed note_create_in_org org_id=org_globex (Alice) SCOPED SCOPED ✓
S7 vuln note_get_by_query cross-tenant (Alice→Globex) LEAKED LEAKED ✓
S7 fixed note_get_by_query cross-tenant (Alice→Globex) DENIED DENIED ✓
S8 vuln resources/read cross-tenant (Alice→Globex) LEAKED LEAKED ✓
S8 fixed resources/read cross-tenant (Alice→Globex) DENIED DENIED ✓
S9 vuln note_share_redeem tampered grant (Alice→Globex) LEAKED LEAKED ✓
S9 fixed note_share_redeem tampered grant (Alice→Globex) DENIED DENIED ✓
S9 fixed note_share_redeem own grant (Alice→Acme) ALLOWED ALLOWED ✓
S10 vuln note_get_scoped X-Org-Id=org_globex (Alice over HTTP) LEAKED LEAKED ✓
S10 fixed note_get_scoped X-Org-Id=org_globex (Alice over HTTP) SCOPED SCOPED ✓
S11 vuln note_create_limited quota exhausted (same XFF) BLOCKED BLOCKED ✓
S11 vuln note_create_limited quota key is 1.2.3.4 MATCH MATCH ✓
S11 vuln note_create_limited fresh server XFF=5.6.7.8 (quota key logic) CREATED CREATED ✓
S11 vuln note_create_limited quota exhausted XFF=5.6.7.8 BLOCKED BLOCKED ✓
S11 fixed note_create_limited quota exhausted (same XFF) BLOCKED BLOCKED ✓
S11 fixed note_create_limited quota key is u_alice MATCH MATCH ✓
S11 fixed note_create_limited fresh server XFF=5.6.7.8 (quota key logic) CREATED CREATED ✓
S11 fixed note_create_limited quota exhausted XFF=5.6.7.8 BLOCKED BLOCKED ✓
S12 vuln note_batch_resolve batch with Globex id (Alice) LEAKED LEAKED ✓
S12 fixed note_batch_resolve batch with Globex id (Alice) SCOPED SCOPED ✓
S13 vuln note_get_by_token_scope scope=org_globex (Alice) LEAKED LEAKED ✓
S13 fixed note_get_by_token_scope scope=org_globex (Alice) SCOPED SCOPED ✓
ALL fixed 13 cross-tenant routes (Bob→Acme) BLOCKED BLOCKED ✓
ALL fixed legitimate access (Dana admin + Bob own note) ALLOWED ALLOWED ✓
Two-way gate: PASS (38/38 rows OK)The PoC is a real MCP client. It spawns the server over stdio, locally, with no
network and no third party, and runs a two-way gate per scenario: in the vuln
build the exploit succeeds; in the fixed build it is blocked and legitimate
same-org access still works (no false positive).
--json-output writes the structured evidence contract used by the optional
toolkit adapter. --sarif-output writes only observed vulnerability outcomes
from the intentionally vulnerable build; fixed controls and expected denials
are not emitted as findings.
The final ALL rows apply that same two-way discipline to the whole server at
once. With every scenario fixed, each cross-tenant route is closed while legitimate
access (an admin's cross-org read, a user's own note) still works. Each S1-S13
arm deliberately pins one toggle and leaves the rest at their vuln default, so
without these rows the hardened build that Run modes tells you to run
would have no coverage at all.
Detection rules
detection/ ships 45 Semgrep
rules that flag these patterns in your own MCP server source, not just this
lab's. There is one per code shape above, with Python siblings where the
JavaScript spelling cannot parse as Python, plus Go, Rust, Kotlin, Java, Ruby, PHP, C#,
and Swift language packs. Eleven of them run against Python as well as
JavaScript/TypeScript, which matters because the reference MCP SDKs ship in both.
Measured against this lab's own source, the rules flag 7 of the 13 scenarios (S1, S2,
S6, S7, S8, S12, S13). The other six sit behind a runtime toggle or a
transport-header shape. Against the official @modelcontextprotocol/sdk the ruleset
produces zero findings, measured with a planted canary that proves the scan reached
the tree. The per-scenario breakdown is in detection/README.md
and the measurement notes are in docs/detection-notes.md.
Drop it into your own MCP server's CI as a GitHub Action. Findings upload to
your repo's Security tab, so the calling workflow needs
security-events: write:
permissions:
security-events: write # only needed for the SARIF upload
steps:
- uses: WRG-11/mcp-objauthz-lab@main
with:
path: src/ # your MCP server sourceAudit a whole MCP server
The rules look at one bug class. skills/mcp-audit/
is a Claude Code skill that reviews the
rest of a server's tool surface as well: how each tool describes itself, whether
result shapes and errors agree across tools, which tools have tests, which look
unused, and how state is written. On a multi-tenant server it runs these rules
and walks the hunt checklist as one of its steps. It is read-only and writes a
single report with a severity per finding.
Run modes
The lab is a multi-tenant note server exposing eighteen MCP tools and one MCP resource
across thirteen independent BOLA scenarios. Each scenario has its own toggle, LAB_S1
to LAB_S13, and every toggle defaults to vuln. Run all scenarios in their fixed state:
# Linux / macOS
LAB_S1=fixed LAB_S2=fixed LAB_S3=fixed LAB_S4=fixed LAB_S5=fixed LAB_S6=fixed LAB_S7=fixed LAB_S8=fixed LAB_S9=fixed LAB_S10=fixed LAB_S11=fixed LAB_S12=fixed LAB_S13=fixed npm start
# Windows PowerShell
$env:LAB_S1='fixed'; $env:LAB_S2='fixed'; $env:LAB_S3='fixed'; $env:LAB_S4='fixed'; $env:LAB_S5='fixed'; $env:LAB_S6='fixed'; $env:LAB_S7='fixed'; $env:LAB_S8='fixed'; $env:LAB_S9='fixed'; $env:LAB_S10='fixed'; $env:LAB_S11='fixed'; $env:LAB_S12='fixed'; $env:LAB_S13='fixed'; npm startWhat each toggle changes, and how to isolate one scenario, is in
docs/configuration.md.
More documentation
docs/scenarios.md: one walkthrough per scenario.docs/hunt-checklist.md: what to read when auditing a real multi-tenant MCP server.docs/architecture.md: the file map and the identity model.docs/configuration.md: the environment variables.docs/detection-notes.md: what the rules were measured to catch and miss.skills/mcp-audit/: the agent skill that audits a whole MCP server.
Scenario reference
Rule messages link to the headings below. Each one points to its challenge and walkthrough.
Scenario S1 — Missing org-scope check (the original)
Inconsistent authorization: find the single outlier. note_delete, CWE-639 / CWE-862, toggle LAB_MODE / LAB_S1.
Challenge, walkthrough.
Scenario S2 — Scope-as-param
Client-supplied scope trusted as authorization. note_search, CWE-639, toggle LAB_S2.
Challenge, walkthrough.
Scenario S3 — List→get asymmetry
List→get asymmetry: batch skips per-object check. note_batch_get, CWE-862, toggle LAB_S3.
Challenge, walkthrough.
Scenario S4 — Wildcard/sentinel bypass
Wildcard/sentinel value bypasses scope filter. note_export, CWE-639, toggle LAB_S4.
Challenge, walkthrough.
Scenario S5 — Role/token-type bypass
Role/token-type bypass: admin-named tool, no role check. note_admin_get, CWE-863, toggle LAB_S5.
Challenge, walkthrough.
Scenario S6 — Foreign-parent injection
Foreign-parent injection: create trusts a caller-supplied org. note_create_in_org, CWE-639, toggle LAB_S6.
Challenge, walkthrough.
Scenario S7 — Unscoped query
Unscoped query: tenant key omitted from the filter (the real-world shape). note_get_by_query, CWE-639, toggle LAB_S7.
Challenge, walkthrough.
Scenario S8 — Resource-URI-as-scope
Resource-URI-as-scope: the resources/read surface, not tools/call. note://{token}/{orgId}/{noteId}, CWE-639, toggle LAB_S8.
Challenge, walkthrough.
Scenario S9 — Authz-from-client-round-tripped-value
Authz-from-client-round-tripped-value: an editable share grant. note_share_prepare, note_share_redeem, CWE-639, toggle LAB_S9.
Challenge, walkthrough.
Scenario S10 — Forwarded-header-as-scope
Forwarded-header-as-scope: a trusted request header (HTTP transport). note_get_scoped, CWE-639 / CWE-290, toggle LAB_S10.
Challenge, walkthrough.
Scenario S11 — Forwarded-header quota bypass
X-Forwarded-For quota bypass: a trusted request header for rate limiting (HTTP transport). note_create_limited, CWE-639 / CWE-290, toggle LAB_S11.
Challenge, walkthrough.
Scenario S12 — Batch resolve without a per-item check
Batch/bulk endpoint BOLA: multi-object endpoint without per-item tenant filter. note_batch_resolve, CWE-639 / CWE-862, toggle LAB_S12.
Challenge, walkthrough.
Scenario S13 — Token scope claim trusted as permission
JWT/token scope confusion: token's scope/aud claim vs actual permissions mismatch. note_get_by_token_scope, CWE-639 / CWE-290, toggle LAB_S13.
Challenge, walkthrough.
Safety / scope
This server is vulnerable by design. Do not deploy it on a reachable network or use it as a starting point for real code. Run it locally for learning only.
Everything in it is synthetic. The orgs and users are made up, and so are their notes and tokens; there is no real target. The PoC never makes a network request. It only spawns the local server process over stdio.
Contributing
The most useful contribution to a detection ruleset is a false positive:
a rule that fires on correctly authorized code. A gate wider than the defect
it targets gets switched off, and a switched-off rule protects nothing, so
those are treated as real defects here. Misses are just as welcome; the rules
catch 7 of the 13 scenarios against this lab's own source and
detection/README.md says why.
There is an issue template for each. CONTRIBUTING.md has
the fixture convention and the exact-count CI gate. It also describes the
multi-language rule trap that costs an afternoon if you meet it the hard way.
Participation is covered by the Code of Conduct.
Security reports go through SECURITY.md. Please do not
report the planted flaws; they are the point.
Citing this
CITATION.cff, or use GitHub's "Cite this repository" button.
License
MIT.
Available Tools
18 toolsnote_admin_getA
Get any note by id, across organizations. Admin/support use only.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It discloses the cross-organization admin behavior and access restriction, which are meaningful. However, it does not describe authentication consequences, permission bypass, or error/return behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no wasted words. The core action, scope, and access restriction are all delivered efficiently and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity tool with two required string parameters and no output schema, the description gives enough context to select and invoke it. It could be more complete by naming a regular alternative and explicitly stating expected returns, but the essential selection criteria are present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It gives meaning to the 'id' parameter via 'by id', but leaves the 'token' parameter almost entirely implicit. Admin/support-only usage hints at token relevance, but no format, source, or role requirements are stated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description has a specific verb and resource: 'Get any note by id, across organizations.' It clearly distinguishes itself from sibling tools like note_get and note_get_scoped by emphasizing cross-organization scope and admin/support-only access.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Admin/support use only' provides a clear who-can-use exclusion, and 'across organizations' clarifies when this tool is appropriate. It does not explicitly name an alternative like note_get for normal scoped access, so it stops short of full alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_batch_getA
Fetch multiple notes by id in a single call (up to 20 ids).
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | ||
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It conveys a read-only operation through 'Fetch' and explicitly states the one-call and 20-item limit. However, it does not disclose behavior for missing/invalid IDs, partial failure, authentication via token, or return ordering/shape. Basic transparency exists but is incomplete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the action, resource, and key constraint. Every word contributes: 'Fetch multiple notes by id', 'single call', and 'up to 20 ids'. No filler, no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description gives a basic adequate overview for a simple batch get, but it lacks details that an agent would need given there is no output schema and no annotations: return format, order, behavior for missing IDs, and auth expectations. It also fails to distinguish from note_batch_resolve, making full context incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema property descriptions have 0% coverage, so the description must add meaning. It does clarify that 'ids' are note identifiers, which maps directly to the IDs array. However, it says nothing about the 'token' parameter, its role, or any format details beyond the schema. The compensation is only partial.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Fetch'), names the resource ('notes'), specifies the selection criterion ('by id'), and highlights the batch/single-call behavior with a hard cap (20 ids). This clearly distinguishes it from note_get (single note) and other siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage context is implied: fetch multiple notes by ID in one call. However, it does not explicitly name alternatives like note_get for single fetches or note_batch_resolve, nor does it say when not to use this tool. The sibling note_batch_resolve creates ambiguity that the description does not address.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_batch_resolveC
Fetch multiple notes by id in a single batch call (up to 50 ids). Returns all requested notes.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | ||
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the 50-id cap and that all requested notes are returned, but does not explain what happens with invalid or missing ids, whether results preserve request order, what token scope is required, or how errors are surfaced. For a batched fetch tool this is a noticable gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one sentence, front-loaded with the core action, and adds the important 50-id bound without padding. It is appropriately concise, though it sacrifices behavioral nuance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations, no output schema, and 0% schema coverage, the description is too thin to fully support correct invocation. It leaves out error handling, the meaning of token, ordering behavior, and relationship to note_batch_get, making the tool incomplete for an agent encountering it among many note tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains that ids are note identifiers and that up to 50 can be provided, but it completely omits the meaning of the required token parameter, leaving the agent without enough information to construct a correct call.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb (fetch), the resource (multiple notes by id), and the batching behavior, making the basic purpose easy to grasp. However, it does not distinguish itself from the sibling note_batch_get, which appears to cover the same operation, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'in a single batch call' implies this tool should be used when retrieving multiple notes at once, so usage context is partially conveyed. But it provides no explicit guidance on when to prefer this over note_get or note_batch_get, and no exclusions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_createC
Create a note in your organization.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | ||
| title | Yes | ||
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral disclosure burden, but it only restates the mutation. It does not mention auth requirements, what the token represents, side effects, permissions, or failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence with the action and scope front-loaded and no filler. Brevity is good, though it sacrifices useful guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the many sibling note creation tools and no annotations or output schema, the description is too thin for confident tool selection and invocation. Token semantics and differentiation from sibling tools are missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description adds no meaning for body, title, or token. The required token parameter is completely unexplained, leaving an agent without enough information to populate parameters confidently.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Create') and the resource ('a note') with an organizational scope, so the basic purpose is evident. However, it does not distinguish note_create from siblings like note_create_in_org or note_create_limited.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus the many sibling creation variants, nor any exclusions or prerequisites. 'In your organization' hints at scope but does not tell an agent when to prefer note_create over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_create_in_orgA
Create a note inside a specific organization (cross-team collaboration). The org_id parameter targets the destination org.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | ||
| title | Yes | ||
| token | Yes | ||
| org_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden of behavioral disclosure. It reveals only that the tool creates a note and that org_id targets the destination org; it does not disclose permission requirements, whether org_id is mandatory, side effects, or response/error behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the core operation and scope first, followed by the critical parameter clarification. Every sentence earns its place and no filler is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no annotations and no output schema, this is thin. It omits return value, error behavior, required auth, and how this tool relates to note_create or note_create_limited, leaving an agent without enough context to invoke it confidently beyond simple cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds meaning only for org_id ('targets the destination org'); token, title, and body are left to inference, and the description does not resolve whether org_id is required even though the schema marks it optional.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action—create a note—and a precise scope: inside a specific organization, with cross-team collaboration intent. It also clarifies that org_id targets the destination org, distinguishing this from generic note_create siblings even without naming them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear context ('inside a specific organization', 'cross-team collaboration') that tells an agent when this tool is appropriate. It does not explicitly name note_create as the alternative or exclude cases where organization targeting is not needed, so it stops one step short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_create_limitedA
Create a note with a per-client quota (max 3 notes). The quota is tracked by client identity.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | ||
| title | Yes | ||
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It usefully discloses the quota limit (max 3) and that tracking is per client identity. However, it does not explain what happens when the quota is exceeded, authorization requirements, or the creation outcome, leaving meaningful behavioral gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded, and each sentence earns its place: the first defines the action and limits, the second clarifies how the limit is tracked. There is no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite a small parameter set, the lack of annotations, zero schema descriptions, no output schema, and close sibling tools make the description insufficient. An agent cannot confidently determine what 'token' means, how to identify the client, or what error/response to expect when the quota is reached.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description needed to compensate for the three parameters. It does not mention token, title, or body by name, and 'client identity' is only an oblique reference to what is likely the token. The description adds little beyond the generic act of creating a note.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: 'Create a note'. It also distinguishes this tool from sibling note_create by naming the per-client quota constraint (max 3 notes), making the tool's specialized role clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The quota and client-identity tracking imply this tool is for creating notes under a client-scoped limit, but there is no explicit when-to-use or when-not-to-use guidance, and no alternative sibling is named. The usage context is only implied, not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_deleteC
Delete a note by id.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states that a note is deleted but does not mention whether deletion is permanent, whether it requires specific permissions, if it can be undone, or what side effects occur. For a destructive operation, this transparency is insufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single short sentence with no fluff. It is front-loaded and easy to parse, though it sacrifices informative detail for brevity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations, no output schema, and two required parameters, the description is too minimal. It omits critical context about authorization, permanence, failure behavior, and the meaning of the token parameter, leaving the agent under-equipped to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description only clarifies the 'id' parameter indirectly by saying deletion is 'by id.' The 'token' parameter is not explained at all, leaving the agent without guidance on what token is expected or how it is used.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Delete') with a clear resource ('a note') and identifying key ('by id'). It is immediately distinguishable from sibling tools like note_get, note_update, and note_create.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives, such as when to delete versus update, or whether deletion is scoped to certain note types. The user must infer usage solely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_exportB
Export all notes for an organization. Pass org_id='*' for a global export (admin only).
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes | ||
| org_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It only mentions the admin-only restriction for the wildcard org_id; it does not reveal whether the operation is read-only, returns a downloadable file, triggers a side effect, or produces a large payload, and it offers no information about rate limits or failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no fluff: the core purpose is front-loaded, and the admin-only caveat is a natural follow-up. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations and no output schema, this description is incomplete. The required token parameter is undocumented, the export output format is entirely unspecified, and the behavior when org_id is omitted is not addressed. The only complete context is the wildcard global-export path.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for both parameters. It explains org_id's special '*' value and the admin constraint, but it never mentions token—the only required parameter—or even what a normal org_id should look like. This leaves a significant gap for the required parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('export') and a clear resource ('all notes for an organization'), and it adds the wildcard behavior for global exports. However, it does not explicitly contrast itself with sibling tools like note_list or note_get, so the agent must infer the distinction from the word 'export' alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides a clear context for org-scoped exports and flags global export as admin-only, which gives some usage boundary. But it does not state when to use this tool over alternatives like note_list or note_search, nor does it explain what happens when org_id is omitted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_getC
Get one note by id.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It only says 'Get one note by id' and does not mention whether the operation is read-only, what permissions or token scopes are required, whether errors are thrown for missing notes, or what the response contains.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded with the core action, which is good. However, it is under-specified even as a minimal viable definition; a single terse sentence does not provide enough surrounding structure or context to be genuinely helpful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations, no output schema, and two required parameters that are completely undocumented, the description is not complete enough. It fails to explain token usage, return values, error behavior, or how this tool differs from its many similarly named siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for the undocumented parameters. It does not mention 'token' at all and only indirectly implies 'id' through 'by id.' The agent receives no added meaning about token purpose, id format, or relationships between the parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Get'), the resource ('one note'), and the selection criterion ('by id'). This distinguishes it from tools like note_list and note_batch_get, though it does not explicitly name those alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus closely related siblings such as note_get_by_query, note_get_scoped, note_batch_get, or note_search. The intended use is only implicitly 'when you need a single note by its id,' but no exclusions or alternatives are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_get_by_queryC
Fetch a single note by id, resolved through a filtered store query.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that the operation fetches, implying read-only behavior, but does not explain what 'filtered store query' means, whether token scoping applies, what happens on missing IDs, or any side effects. This is too thin.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded, but 'resolved through a filtered store query' is vague and potentially confusing. Brevity is good, but here it sacrifices necessary clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations, no output schema, two undocumented required parameters, and many similar siblings, this description is incomplete. It lacks parameter explanations, behavior on not-found, and guidance on how this differs from note_get.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description adds no meaning to the 'id' or 'token' parameters beyond their string types. The token is presumably an auth token, but that is never stated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the operation ('Fetch a single note by id') and the resource ('note'). It is distinct from list/search tools, but does not differentiate it from the sibling note_get, which likely does the same thing directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus note_get, note_search, note_get_scoped, or note_get_by_token_scope. The phrase 'resolved through a filtered store query' hints at a different mechanism, but no conditions or alternatives are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_get_by_token_scopeB
Get notes for the organization indicated by the token's scope claim. The token carries the intended scope.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | Optional scope override from token claims (aud/scope) | |
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of explaining behavior. It does disclose the key behavioral trait: notes are fetched read-only based on the token's scope claim rather than an explicit org parameter. It does not mention token validity, error behavior, pagination, or response shape, but this is minimally adequate for a read-only get operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief and front-loaded, stating the primary purpose in the first sentence. The second sentence reinforces the token-based scoping behavior and is not filler, but it is somewhat redundant with the first sentence, preventing a perfect score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter retrieval tool, the description provides enough information to understand the core call: pass a token and optionally override the scope. However, without an output schema or annotations, missing details such as return shape, error behavior, and how this differs from note_get_scoped leave moderate gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: the optional scope parameter is documented, while the required token parameter has no schema description. The description adds meaning to token by explaining that it carries the intended scope, but it does not elaborate on the optional scope override semantics or token format, so it only partially compensates for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear action ('Get notes') and resource ('organization indicated by the token's scope claim'), so an agent understands what the tool returns and how the target organization is determined. However, it does not differentiate it from closely named siblings like note_get_scoped or note_get_by_query, so it stops short of full clarity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the intended use case: retrieve notes when the token's scope claim selects the organization. It does not explicitly say when to use this tool over note_get_scoped, note_get, or note_get_by_query, and it provides no exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_get_scopedB
List the caller's notes. Honors an X-Org-Id routing header set by the API gateway.
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure. It does reveal a meaningful behavior: the tool honors an X-Org-Id routing header set by the API gateway. However, it does not mention return format, pagination, or whether the org header changes which notes are visible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no filler. The primary purpose is front-loaded, and the routing behavior is added concisely without redundancy or repetition of schema information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter list tool, the description provides the core operation and a useful routing detail. However, with no annotations, no output schema, and many sibling tools, it would benefit from clarifying the token's role and how 'scoped' differs from note_list or note_get_by_token_scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description never explains the required 'token' parameter. 'List the caller's notes' indirectly implies that token identifies the caller, but the agent is left to infer this rather than being told.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the operation ('List') and the resource ('the caller's notes'), giving an unambiguous purpose and a specific scope. It stops short of explicitly distinguishing itself from similar siblings like note_list or note_get_by_token_scope, so it misses a perfect score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'List the caller's notes' implies the main use case: returning notes owned by the current caller. However, it does not state when to prefer this tool over note_list, note_get_by_token_scope, or note_search, nor does it give any exclusions or alternative routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_listC
List the notes in your organization.
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral disclosure burden, but it only states the scope ('in your organization') and the read-style verb 'List'. It does not mention whether this is read-only, what is returned, pagination/ordering, authorization requirements, or the meaning/role of the token.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single clear, front-loaded sentence with no filler. It is concise, though not fully adequate for the missing parameter and usage semantics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without annotations, output schema, or parameter descriptions, the description alone is too thin for safe invocation. It covers the basic purpose but lacks token semantics, return shape, pagination, and when-to-use context, making it incomplete against the rich sibling toolset.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the only required parameter, token, is a bare string. The description never mentions token, so the agent cannot know whether it is an auth token, a pagination token, or an organization token. The description must compensate for the missing parameter documentation and does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and resource ('notes in your organization'), making the tool's core purpose clear. It differentiates from note_get/note_create but does not explicitly separate list from the similarly broad note_search or note_get_by_query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use note_list instead of note_search, note_get_by_query, or note_export. There are no exclusions, prerequisites, or alternative conditions, so the agent must infer usage from the tool name and siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_searchB
Search notes by substring. The optional org_id parameter restricts the scope (admin use).
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | ||
| token | Yes | ||
| org_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It does disclose the core behavior (substring search) and an important scoping restriction (org_id for admin use), but it omits details such as pagination, result format, auth semantics, and error behavior, so transparency is only partial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the primary action front-loaded. Every clause adds information, and there is no filler or repetition of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, no output schema, and zero schema coverage, the description is too thin. An agent cannot tell when to choose this over note_get_by_query, what the response contains, or whether the result set is limited, which are significant gaps for a search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It gives meaning to q as the substring and explains org_id as an optional admin scope restrictor, but token is left entirely to inference from its name rather than described.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Search notes') and adds a distinguishing matching criterion ('by substring'). This separates it from list/get tools at a basic level, though it does not explicitly call out sibling alternatives like note_get_by_query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance about when to use note_search versus note_list, note_get_by_query, or note_get_scoped. The only contextual hint is that org_id is admin-only, which tells the agent nothing about when substring search is preferred over other query mechanisms.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
note_updateA
Update a note's body by id.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| body | Yes | ||
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It states the core mutation but does not mention required authentication, overwrite behavior, error cases for missing or invalid ids, or whether the update is reversible. This leaves important behavioral context unstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It conveys the operation, target, and identifier efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter mutation with no annotations and no output schema, this description is too thin. It does not explain return values, error outcomes, authentication prerequisites, or when to prefer this tool over a sibling such as note_create or note_get.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must add parameter meaning. It clarifies that 'id' selects the note and 'body' supplies the new content, but it says nothing about the required 'token' parameter, leaving one of three parameters unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Update a note's body by id.' It clearly identifies the operation, the target entity, and the selection method, and it distinguishes the tool from siblings like note_create, note_get, and note_delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Update a note's body by id' gives clear context: use this tool when an existing note's body needs to be changed. It does not explicitly name alternatives or exclusions, but the operation and target are clear enough to route an agent correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoamiA
Return the session (user + org) your token authenticates as.
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral-transparency burden. It correctly implies a read-only introspection and specifies what is returned, but it does not disclose behavior for invalid or expired tokens, nor does it explicitly state that no side effects occur.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler. The core scope ('session (user + org)') is front-loaded, and every word contributes meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no output schema, the description covers both input semantics and return content. The only notable omission is error/edge-case behavior for invalid tokens, which is a minor gap for such a simple read-only operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It clarifies that the 'token' parameter is the caller's authentication token and the basis for the session lookup. However, it does not specify token format or how the token is expected to be supplied, leaving some ambiguity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Return') and resource ('session (user + org)') tied to token authentication, making the tool's purpose unambiguous. It is clearly distinct from the sibling note_* tools, which all handle note operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: use this when you need to know which user and org a token authenticates as. It does not explicitly discuss alternatives or exclusions, but no sibling tool overlaps with this identity-resolution task, so the missing exclusion is low-risk.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
18 tool updates
v3.10.0- Added
note_admin_get - Added
note_batch_get - Added
note_batch_resolve - Changed
note_create1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Added
note_create_in_org - Added
note_create_limited - Changed
note_delete1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Added
note_export - Changed
note_get1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Added
note_get_by_query - Added
note_get_by_token_scope - Added
note_get_scoped - Changed
note_list1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
note_search2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / org_idAdded value: +{ + "type": "string" +}
- Added
note_share_prepare - Added
note_share_redeem - Changed
note_update1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
whoami1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
7 tool updates
v1.0.0- First observed
note_create - First observed
note_delete - First observed
note_get - First observed
note_list - First observed
note_search - First observed
note_update - First observed
whoami
TDQS
Scored across 18 tools
There are many overlapping read operations: note_get, note_get_by_query, note_get_scoped, note_get_by_token_scope, note_admin_get, and two batch getters. note_batch_resolve and note_batch_get especially are nearly indistinguishable, so an agent would struggle to pick the right tool for a simple fetch.
Most tools follow a consistent note_<action> pattern, e.g. note_list, note_get, note_create, note_update, note_delete. Minor deviations like whoami and the inconsistent note_batch_resolve versus note_batch_get keep it from being a perfect 5.
18 tools is above the comfortable 3-15 range and feels heavy for a notes/authz lab. Many read variants inflate the count when fewer, more distinct tools could express the same authorization scenarios.
The toolset covers the core note lifecycle: create, get, list, search, update, delete, export, plus authz-specific operations like admin access, org-scoped creation, token-scoped reads, and sharing. Minor gaps like share revocation and scoped update/delete variants exist, but core workflows are not dead-ended.
Maintenance
Related MCP Connectors
Security research canary remote MCP server for owned-account testing.
MEOK MCP Hardening MCP — automated security red-team for any MCP server. Maps OWASP LLM Top 10
Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.
Security scanner for MCP servers. Detect vulnerabilities, prompt injection, and tool poisoning.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA deliberately insecure MCP server designed as a pentest lab to demonstrate common vulnerabilities in MCP deployments.-
- FlicenseNot gradedqualityDmaintenanceA vulnerable-by-design MCP server pair (NotesServer and VaultServer) for testing MCP security tools, featuring confused-deputy, prompt injection, and authorization bypass scenarios.-
- FlicenseNot gradedqualityDmaintenanceA vulnerable MCP server designed for educational CTF challenges. It demonstrates various MCP security vulnerabilities in a controlled environment.8-
- FlicenseNot gradedqualityCmaintenanceAn intentionally vulnerable MCP server for security education, demonstrating flaws like missing auth, SSRF, SQLi, and file system abuse.-