Core ideas
Everything else assumes three things: an organization contains departments, and a department contains projects; a credential is issued for one project, so Wexa reads the scope from it and you never pass project_id, projectID, organization_id or executed_by; and the same tools answer on four surfaces. You need no credential to read this.
- Overview: what Wexa is and where to start.
- Quickstart: get a key and make your first call.
- Connect an AI client: add Wexa to Claude, Cursor or ChatGPT.
- Authentication: see how a credential carries scope.
- Errors and retries: what a refusal means.
- Changelog: what changed in each SDK.
Where your work lives
Know where your work lives
An organization is a customer and the strongest isolation boundary: nothing is shared across organizations. A quota caps what an organization may consume and credits are the balance usage draws down, so two teams in one organization can exhaust each other's quota and two organizations never can.
A department is a division that owns projects and groups members. One person can administer several departments, and the department decides who looks after a project. It organizes people and is not the boundary a call runs inside.
A project is the unit of work and of isolation, and the one you will think about most. It owns four stores (context graph, knowledge base, data catalog, project ontology), its agents and process flows with every execution, its connectors and skills, and its repository connections and code graph. An agent defined in one project cannot be run from another, and two projects in one department are as separate as two in different organizations.
Writes follow the same rule. Saved nodes land only in the calling project's context graph, and the project is pinned server-side before the write.
| Level | Answers | Enforced per call |
|---|---|---|
| Organization | Who is the customer, and what may they consume? | No |
| Department | Who owns and administers the work? | No |
| Project | What can this call see, and where do its writes land? | Yes |
Governance is project-bound too. A policy decision rules on one project's rules, an approver must be able to see that project, and the audit record names the scope. Each project also has a project mode that decides how context is written and how much approval that takes.
Use a separate project for isolation: different customers, production against experiments, or teams whose agents must not read each other's work. Use one project when agents need the same context, because you cannot join across two. Splitting later is real work.
See organizations, departments and projects to set them up, and where your data goes to choose a store.
What scope a call carries
Know what scope a call carries
A scope is the organization, department and project you are acting in, plus who you are. It comes from the credential, not the call, and is fixed when the credential is issued. For the Wexa MCP server, that is the consent screen where you pick the project.
A credential is a key to one project, not to Wexa, and an API key never widens, so a second project needs a second key. The same scope applies on every surface.
Four argument names describe scope rather than work, and you may never pass them. These are the server-bound arguments:
project_idandprojectID: both spellings are refused because two parts of the platform spell the project differently, and neither may become a way around the other.organization_id.executed_by: a caller who could assert who ran something could sign someone else's name into the audit record.
Both SDKs check the payload's keys before a request is built and raise a validation error naming them. It is a run-time check at the client, not a restriction in the types, and it fires before anything reaches the network.
// ValidationError: ['project_id'] are bound server-side from your
// token scope; sending them is rejected
await fabric.call('query-context', {
project_id: 'proj_123',
query: 'MATCH (c:Customer) RETURN c LIMIT 10',
})The refusal replaced something worse. The gateway never reads these arguments, so a REST query-context call carrying another project's project_id returns 200 about your own project, and nothing says so.
Tool argument tables mark server-bound arguments as what Wexa supplies, not fields you left blank. Routes with a project in the URL are checked against your credential and answer 403 when they disagree. See authentication.
How to call Wexa
Pick how you call Wexa
Wexa exposes the same tools four times over: the Wexa MCP server, the REST API, the TypeScript SDK and the Python SDK. The tool, its arguments, the policy decision, the audit record and the result are identical on all four, and a surface is never a way around a rule. That is why the tool reference describes each tool once, with every example showing all four call syntaxes.
| If the caller is | Use | Why |
|---|---|---|
| A product someone else wrote, such as an editor or desktop assistant | The Wexa MCP server | Configure the client once and every tool appears. No code. |
| TypeScript or Python application code | The matching SDK | Typed arguments, results and errors, and a bad call is refused before it leaves your process. |
| Another language, a shell script, or somewhere a dependency is the hard part | The REST API | POST /v1/<tool-name> with a bearer token. Nothing to install. |
Moving between surfaces later rewrites syntax and nothing else. The Quickstart covers getting a credential before it asks you to authenticate.