Skip to main content

MCP server

This document was generated using AI assistance

Content may include inaccuracies, outdated information, or technical errors. Users are advised to cross-check critical information before implementation.

Architeezy has a built-in Model Context Protocol server, through which an AI agent works with models directly. The agent can list projects, read a model and its metamodel, write changes, create representations and move blocks on diagrams.

Endpoint and authentication

The server speaks the Streamable HTTP transport at /mcp on the same host as the application - https://architeezy.com/mcp on the hosted service.

The endpoint requires an authenticated caller. A client that supports remote servers with OAuth needs nothing beyond the URL: it discovers the authorization server from the protected resource metadata at /.well-known/oauth-protected-resource, and that server accepts dynamic client registration. A client without OAuth support sends an access token as a bearer header, issued to the public client architeezy-api.

The agent acts on your behalf: it sees the projects you see and may change only what you may change. A tool call beyond your rights returns an error.

Client configuration

Claude Code

Add the server, then run /mcp inside Claude Code to complete the OAuth sign-in:

claude mcp add --transport http architeezy https://architeezy.com/mcp

Visual Studio Code

Put the server in .vscode/mcp.json in your workspace, or open the user configuration with the MCP: Open User Configuration command:

{
"servers": {
"architeezy": {
"type": "http",
"url": "https://architeezy.com/mcp"
}
}
}

VS Code opens a browser for sign-in and consent the first time it connects.

Cursor

Put the server in .cursor/mcp.json in the project, or in ~/.cursor/mcp.json to have it everywhere:

{
"mcpServers": {
"architeezy": {
"url": "https://architeezy.com/mcp"
}
}
}

Claude apps

On claude.ai, open Customize → Connectors, click +, choose Add custom connector, and enter https://architeezy.com/mcp. The OAuth sign-in runs when you connect it, and the connector is then available in the Claude apps signed in to the same account. Anthropic's servers reach the endpoint on your behalf, so a server on a private network is not reachable this way.

Tool conventions

Paging. Every listing takes page (from 0) and size (default 50, at most 500), and answers with items plus a page block:

{
"items": [],
"page": { "size": 50, "number": 0, "totalElements": 30, "totalPages": 1 }
}

Sorting. sort takes field,direction, for example name,asc. Separate several clauses with ;.

Filtering. filter is a JSON object whose values are arrays. Entries in an array are alternatives; a * at either end of a value matches by prefix, suffix or substring, ignoring case; a leading ! negates.

{
"name": ["Order*", "Payment*"],
"project.id": ["019b2a78-5fa0-728a-b861-e51b5ad26984"]
}

Tools

Scopes and projects

listScopes returns the top-level containers that can hold a project, with flags telling the agent whether it may create anything there. listProjects lists the projects you can reach, and createProject adds one to a scope by name. listImportedProjects walks the dependency closure of a project, which is how an agent finds the metamodels and shared models a project builds on.

Models

listAllowedModelKinds lists the kinds of model you can create in a project. The list covers kinds defined in the project itself, kinds from the projects it imports, and kinds from any other metamodel project you can see. Its id is what createModel expects; when the kind comes from a project that is not yet imported, the import is added for you.

listModels finds models; readModel returns one as a content tree. Pass objectId to read a single object's subtree instead of the whole model, and depth to stop at a given level of nesting. A large model is far cheaper to explore in slices than to fetch whole.

readMetamodel returns the metamodel behind a model in compact form: classifiers, their supertypes, their features with type and multiplicity, and enumeration literals. An agent reads it before writing so that the class and feature names it sends exist.

updateModel applies a patch, deleteModel removes a model and its content.

Objects

deleteObjects deletes objects from a model as one atomic batch. Containment cascades, so descendants of a deleted object are deleted too and are listed in the response. References to the doomed objects from elsewhere in the project block the deletion by default and are reported back; passing deleteIncomingReferencesInProject clears the references that are safe to clear. Mandatory single-valued references are never cleared automatically.

Representations

listRepresentationDescriptions enumerates the kinds of representation that can be created on a given object; createRepresentation creates one from a description id. listRepresentations finds existing ones and hands back the ids the diagram tools need, along with the URL that opens each one in the browser. deleteRepresentation removes a representation and leaves the model untouched.

Diagram layout

readDiagramLayout returns a diagram's geometry: a tree of nodes with their children and borderNodes, and a flat list of edges. Coordinates are relative to the nearest parent node. Every node and edge carries a targetObjectId, so an agent can go from a box on a diagram to the object behind it with readModel.

updateDiagramLayout writes positions and sizes back, merging by id. It moves and resizes what is already on the diagram; it neither creates nor deletes nodes, and it refuses to re-parent one. An empty edge path restores automatic routing.

Model patches

updateModel takes a partial content tree and merges it into the model. Each entry names an object by id, its type as <prefix>:<EClass>, and the features to set in data:

  • An id of tmp:<name> creates a new object. Using the same tmp:<name> as a string value elsewhere in the same patch points at the object just created.
  • Containment arrays merge by id, so listing one child adds or updates that child and leaves its siblings alone. Add an integer ordinal to place a child at a given position.
  • Multi-valued reference arrays are replaced wholesale, so send the complete list you want.
  • A reference value is <uuid> within the model, <modelId>#<uuid> for another model in the same project, and <prefix>:<EClass> <modelId>#<uuid> in full canonical form.

The whole patch succeeds or fails together; a rejected patch leaves the model exactly as it was.

Two optional arguments make writes safe to repeat:

  • idempotencyKey - the same key with the same body returns the first response instead of applying the change twice. The same key with a different body is an error.
  • expectedLastModificationDateTime - the timestamp the agent saw when it read the model. If somebody else has written since, the update is refused instead of overwriting their work.

Pass returnContent: "none" when the agent does not need the post-patch tree echoed back.

Example: adding an element and putting it on a diagram

An architect asks the agent: add a Billing Service application component to the ArchiMate model in the Showcase project, have it serve the Ordering Service, and put it on the diagram.

1. Find the model.

listModels { "filter": "{\"project.id\":[\"019b2a78-5fa0-728a-b861-e51b5ad26984\"]}" }
{
"items": [
{
"id": "019b2b46-fc08-795b-8929-4179a5ea98b9",
"name": "ArchiMate",
"type": "http://www.archimatetool.com/archimate#ArchimateModel",
"url": "https://architeezy.com/demo/showcase/dev/archimate",
"lastModificationDateTime": "2025-12-18T13:04:29.984441Z"
}
]
}

2. Learn the vocabulary. readMetamodel for the namespace http://www.archimatetool.com/archimate confirms that ApplicationComponent and ServingRelationship exist, that a Folder holds its contents in elements, and that a relationship carries source and target.

3. Find where things go. readModel with depth: 2 returns the model root and its folders. The response carries the ids of the Application and Relations folders and of the existing Ordering Service element.

4. Write the change.

updateModel {
"id": "019b2b46-fc08-795b-8929-4179a5ea98b9",
"expectedLastModificationDateTime": "2025-12-18T13:04:29.984441Z",
"returnContent": "none",
"data": {
"content": [
{
"id": "9abb47b3-0704-5e36-a76f-dde1426c31f2",
"eClass": "archimate:Folder",
"data": {
"elements": [
{
"id": "tmp:billing",
"eClass": "archimate:ApplicationComponent",
"data": { "name": "Billing Service" }
}
]
}
},
{
"id": "c9192668-0b87-563b-87c0-4550c3586d7c",
"eClass": "archimate:Folder",
"data": {
"elements": [
{
"id": "tmp:serves",
"eClass": "archimate:ServingRelationship",
"data": {
"source": "tmp:billing",
"target": "d569ff64-e964-587e-8125-82769c66c7f9"
}
}
]
}
}
]
}
}

The response carries the identifiers the two tmp: entries were given.

5. Put it on the diagram. A box on an ArchiMate view is a DiagramModelArchimateObject child of the view that points at the element, so the agent patches the view the same way:

{
"content": [
{
"id": "4332d237-8569-5b74-99f6-c6167a4afa0f",
"eClass": "archimate:ArchimateDiagramModel",
"data": {
"children": [
{
"id": "tmp:billing-box",
"eClass": "archimate:DiagramModelArchimateObject",
"data": { "archimateElement": "<id assigned to tmp:billing>" }
}
]
}
}
]
}

6. Place it. readDiagramLayout shows where everything sits:

{
"diagramId": "019b2b47-2baa-7cf6-810f-592119ba5a3b",
"modelId": "019b2b46-fc08-795b-8929-4179a5ea98b9",
"nodes": [
{
"id": "1b533efc-...",
"label": "Ordering Service",
"x": 472,
"y": 307,
"width": 137,
"height": 55
},
{
"id": "b92d6557-...",
"label": "Web Store System",
"x": 472,
"y": 420,
"width": 137,
"height": 55
}
],
"edges": [
{
"id": "9d9ada7e-...",
"sourceNodeId": "b92d6557-...",
"targetNodeId": "1b533efc-...",
"path": []
}
]
}

The agent then calls updateDiagramLayout with the id of the new node and the coordinates of free space next to Ordering Service. The block appears on the diagram for everyone who has it open.