Skip to content

Commit 79bb241

Browse files
refactor: remove all resource templates with tools (#44)
* refactor: remove all resource templates with tools Resource templates are not widely supported in many clients so for consistency we are converting resource templates to paginated tool calls with resource identifier * add listing reserved ipv4 and ipv6 * fix: remove tool names from top level readme
1 parent f95ac6c commit 79bb241

File tree

75 files changed

+4065
-3474
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+4065
-3474
lines changed

README.md

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,7 @@ The MCP DigitalOcean Integration supports a variety of services, allowing users
6464
| **Apps** | Manage DigitalOcean App Platform applications, including deployments and configurations. |
6565
| **Droplets** | Create, manage, resize, snapshot, and monitor droplets (virtual machines) on DigitalOcean. |
6666
| **Account** | Get information about your DigitalOcean account, billing, balance, invoices, and SSH keys. |
67-
| **Networking** | Manage domains, DNS records, certificates, firewalls, reserved IPs, VPCs, CDNs, and partner attachments. |
68-
69-
### Service Tools
70-
71-
Each service provides a toolset to interact with DigitalOcean.
72-
73-
| **Service** | **Tools** (examples, see per-service README for full list) |
74-
|----------------|------------------------------------------------------------------------------------------------------|
75-
| **Account** | `digitalocean-key-create`, `digitalocean-key-delete`, `account://current`, `balance://current`, `billing://{last}`, `invoice://{last}`, `actions://{id}`, `keys://{id}` |
76-
| **Apps** | `digitalocean-create-app-from-spec`, `digitalocean-apps-update`, `digitalocean-apps-delete`, `digitalocean-apps-get-info`, `digitalocean-apps-usage`, `digitalocean-apps-get-deployment-status`, `digitalocean-apps-list` |
77-
| **Droplets** | `digitalocean-droplet-create`, `digitalocean-droplet-delete`, `digitalocean-droplet-power-cycle`, `digitalocean-droplet-resize`, `digitalocean-droplet-snapshot`, `digitalocean-droplet-enable-backups`, `digitalocean-droplet-get-neighbors`, `digitalocean-droplet-rename`, `digitalocean-droplet-rebuild`, `digitalocean-droplet-get-kernels`, ... (see [Droplet README](./internal/droplet/README.md)) |
78-
| **Networking** | `digitalocean-domain-create`, `digitalocean-domain-delete`, `digitalocean-domain-record-create`, `digitalocean-domain-record-delete`, `digitalocean-certificate-create`, `digitalocean-certificate-delete`, `digitalocean-firewall-create`, `digitalocean-firewall-delete`, `digitalocean-reserved-ip-reserve`, `digitalocean-reserved-ip-release`, `digitalocean-vpc-create`, `digitalocean-vpc-delete`, `digitalocean-vpc-peering-create`, `digitalocean-vpc-peering-delete`, `digitalocean-cdn-create`, `digitalocean-cdn-delete`, `digitalocean-partner-attachment-create`, ... (see [Networking README](./internal/networking/README.md)) |
67+
| **Networking** | Manage domains, DNS records, certificates, firewalls, reserved IPs, VPCs, CDNs, and Partner Network attachments. |
7968

8069
---
8170
## Service Documentation
@@ -90,17 +79,6 @@ See the following files for full documentation:
9079

9180
---
9281

93-
### Example Resource URIs
94-
95-
Each service exposes resources that can be queried directly. Examples:
96-
97-
- **Account:** `account://current`, `balance://current`, `billing://3`, `invoice://6`, `actions://123456`, `keys://987654`
98-
- **Apps:** `apps://{id}`, `apps://{id}/deployments/{deployment_id}`
99-
- **Droplets:** `droplets://{id}`, `droplets://{id}/actions/{action_id}`, `images://distribution`, `images://{id}`, `sizes://all`
100-
- **Networking:** `domains://{name}`, `domains://{name}/records/{record_id}`, `certificates://{id}`, `firewalls://{id}`, `reserved_ipv4://{ip}`, `vpcs://{id}`, `cdn://{id}`, `partner_attachment://{id}`, `vpc_peering://{id}`
101-
102-
---
103-
10482
### Example Tool Usage
10583

10684
- Deploy an app from a GitHub repo: `digitalocean-create-app-from-spec`
@@ -109,8 +87,6 @@ Each service exposes resources that can be queried directly. Examples:
10987
- Create a new domain: `digitalocean-domain-create`
11088
- Enable backups on a droplet: `digitalocean-droplet-enable-backups`
11189
- Flush a CDN cache: `digitalocean-cdn-flush-cache`
112-
- List all available droplet sizes: `sizes://all`
113-
- Get account balance: `balance://current`
11490
- Create a VPC peering connection: `digitalocean-vpc-peering-create`
11591
- Delete a VPC peering connection: `digitalocean-vpc-peering-delete`
11692

internal/account/README.md

Lines changed: 112 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,123 @@
1-
# Account MCP Tools
1+
# DigitalOcean Account Tools
22

3-
This directory contains tools and resources for interacting with DigitalOcean account-related features via the MCP Server. These tools allow you to query and manage account information, billing, invoices, SSH keys, and actions.
3+
This directory provides tool-based handlers for interacting with DigitalOcean account-related features via the MCP Server. All account operations are exposed as tools that accept structured arguments—no resource URIs are used. Pagination and filtering are supported where applicable.
44

55
## Supported Tools
66

7-
- `digitalocean-key-create`: Create a new SSH key for your account. This tool lets you add a new public SSH key, which can then be used for Droplet or App Platform deployments.
8-
- `digitalocean-key-delete`: Delete an existing SSH key by its ID. Useful for removing unused or compromised keys from your account.
7+
### Actions
98

10-
## Supported Resources
9+
- **digitalocean-action-get**
10+
- Get a specific action by its ID.
11+
- Arguments:
12+
- `ID` (number, required): The action ID.
1113

12-
- `account://current`: Retrieve information about the current DigitalOcean account, such as email, UUID, status, and more.
13-
- `balance://current`: Get the current account balance, including outstanding charges and account credits.
14-
- `billing://{last}`: Fetch billing history for the last N months. Replace `{last}` with the number of months you want to retrieve.
15-
- `invoice://{last}`: Retrieve invoice history for the last N months. Replace `{last}` with the number of months you want to retrieve.
16-
- `actions://{id}`: Get information about a specific action (such as Droplet creation, deletion, etc.) by its numeric ID.
17-
- `keys://{id}`: Retrieve information about a specific SSH key by its numeric ID.
14+
- **digitalocean-action-list**
15+
- List actions with pagination.
16+
- Arguments:
17+
- `Page` (number, default: 1): Page number.
18+
- `PerPage` (number, default: 30): Items per page.
1819

19-
## Example Queries Using Account MCP Tools
20+
### Balance
2021

21-
- Show me my current account information.
22-
- What is my current DigitalOcean balance?
23-
- List my billing history for the last 3 months.
24-
- Get all invoices from the past 6 months.
25-
- Show details for action ID 12345678.
26-
- Retrieve information about SSH key with ID 987654.
27-
- Add a new SSH key to my account.
28-
- Remove SSH key with ID 12345.
22+
- **digitalocean-balance-get**
23+
- Get balance information for the user account.
24+
- Arguments: _none_
25+
26+
### Billing
27+
28+
- **digitalocean-billing-history-list**
29+
- List billing history with pagination.
30+
- Arguments:
31+
- `Page` (number, default: 1): Page number.
32+
- `PerPage` (number, default: 30): Items per page.
33+
34+
### Invoices
35+
36+
- **digitalocean-invoice-list**
37+
- List invoices with pagination.
38+
- Arguments:
39+
- `Page` (number, default: 1): Page number.
40+
- `PerPage` (number, default: 30): Items per page.
41+
42+
### SSH Keys
43+
44+
- **digitalocean-key-create**
45+
- Create a new SSH key.
46+
- Arguments:
47+
- `Name` (string, required): Name of the SSH key.
48+
- `PublicKey` (string, required): Public key content.
49+
50+
- **digitalocean-key-delete**
51+
- Delete an SSH key by its ID.
52+
- Arguments:
53+
- `ID` (number, required): ID of the SSH key to delete.
54+
55+
- **digitalocean-key-get**
56+
- Get a specific SSH key by its ID.
57+
- Arguments:
58+
- `ID` (number, required): ID of the SSH key.
59+
60+
- **digitalocean-key-list**
61+
- List SSH keys with pagination.
62+
- Arguments:
63+
- `Page` (number, default: 1): Page number.
64+
- `PerPage` (number, default: 30): Items per page.
65+
66+
### Account Information
67+
68+
- **digitalocean-account-get-information**
69+
- Retrieves account information for the current user.
70+
- Arguments: _none_
71+
72+
---
73+
74+
## Example Usage
75+
76+
- Get details for action ID 123456:
77+
- Tool: `digitalocean-action-get`
78+
- Arguments: `{ "ID": 123456 }`
79+
80+
- List actions (page 2, 50 per page):
81+
- Tool: `digitalocean-action-list`
82+
- Arguments: `{ "Page": 2, "PerPage": 50 }`
83+
84+
- Get current account balance:
85+
- Tool: `digitalocean-balance-get`
86+
- Arguments: `{}`
87+
88+
- List billing history (first page, 10 items per page):
89+
- Tool: `digitalocean-billing-history-list`
90+
- Arguments: `{ "Page": 1, "PerPage": 10 }`
91+
92+
- List invoices (default pagination):
93+
- Tool: `digitalocean-invoice-list`
94+
- Arguments: `{}`
95+
96+
- Create a new SSH key:
97+
- Tool: `digitalocean-key-create`
98+
- Arguments: `{ "Name": "my-key", "PublicKey": "ssh-rsa AAAA..." }`
99+
100+
- Delete SSH key with ID 98765:
101+
- Tool: `digitalocean-key-delete`
102+
- Arguments: `{ "ID": 98765 }`
103+
104+
- Get SSH key by ID:
105+
- Tool: `digitalocean-key-get`
106+
- Arguments: `{ "ID": 12345 }`
107+
108+
- List SSH keys (page 3, 20 per page):
109+
- Tool: `digitalocean-key-list`
110+
- Arguments: `{ "Page": 3, "PerPage": 20 }`
111+
112+
- Get current account information:
113+
- Tool: `digitalocean-account-get-information`
114+
- Arguments: `{}`
115+
116+
---
29117

30118
## Notes
31119

32-
- Most resources are read-only and provide information about your account and its usage.
33-
- The SSH key tools (`digitalocean-key-create` and `digitalocean-key-delete`) allow you to manage your account's SSH keys directly.
34-
- For endpoints that require an ID or a count (such as `{id}` or `{last}`), replace the placeholder with the appropriate value in your query.
120+
- All tools use argument-based input; do not use resource URIs.
121+
- Pagination is supported for list endpoints via `Page` and `PerPage` arguments.
122+
- All responses are returned as JSON-formatted text.
123+
- Error handling is consistent: errors are returned in the tool result with an error flag and message.

internal/account/account_resources.go

Lines changed: 0 additions & 57 deletions
This file was deleted.

internal/account/account_tools.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package account
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
8+
"github.com/digitalocean/godo"
9+
"github.com/mark3labs/mcp-go/mcp"
10+
"github.com/mark3labs/mcp-go/server"
11+
)
12+
13+
type AccountTools struct {
14+
client *godo.Client
15+
}
16+
17+
func NewAccountTools(client *godo.Client) *AccountTools {
18+
return &AccountTools{
19+
client: client,
20+
}
21+
}
22+
23+
func (a *AccountTools) getAccountInformation(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
24+
account, _, err := a.client.Account.Get(ctx)
25+
if err != nil {
26+
return mcp.NewToolResultErrorFromErr("api error", err), nil
27+
}
28+
29+
jsonData, err := json.MarshalIndent(account, "", " ")
30+
if err != nil {
31+
return nil, fmt.Errorf("error marshalling account: %w", err)
32+
}
33+
34+
return mcp.NewToolResultText(string(jsonData)), nil
35+
}
36+
37+
func (a *AccountTools) Tools() []server.ServerTool {
38+
return []server.ServerTool{
39+
{
40+
Handler: a.getAccountInformation,
41+
Tool: mcp.NewTool("digitalocean-account-get-information",
42+
mcp.WithDescription("Retrieves account information for the current user"),
43+
),
44+
},
45+
}
46+
}

internal/account/account_resources_test.go renamed to internal/account/account_tools_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import (
1111
"go.uber.org/mock/gomock"
1212
)
1313

14-
func setupAccountResourceWithMock(mockAccount *MockAccountService) *AccountMCPResource {
14+
func setupAccountToolsWithMock(mockAccount *MockAccountService) *AccountTools {
1515
client := &godo.Client{}
1616
client.Account = mockAccount
17-
return NewAccountMCPResource(client)
17+
return NewAccountTools(client)
1818
}
1919

20-
func TestAccountMCPResource_handleGetAccountResource(t *testing.T) {
20+
func TestAccountTools_handleGetAccountInformation(t *testing.T) {
2121
ctrl := gomock.NewController(t)
2222
defer ctrl.Finish()
2323

@@ -58,19 +58,19 @@ func TestAccountMCPResource_handleGetAccountResource(t *testing.T) {
5858
if tc.mockSetup != nil {
5959
tc.mockSetup(mockAccount)
6060
}
61-
resource := setupAccountResourceWithMock(mockAccount)
62-
req := mcp.ReadResourceRequest{}
63-
resp, err := resource.handleGetAccountResource(context.Background(), req)
61+
tool := setupAccountToolsWithMock(mockAccount)
62+
req := mcp.CallToolRequest{}
63+
resp, err := tool.getAccountInformation(context.Background(), req)
6464
if tc.expectError {
65-
require.Error(t, err)
65+
require.NotNil(t, resp)
66+
require.True(t, resp.IsError)
6667
return
6768
}
6869
require.NoError(t, err)
6970
require.NotNil(t, resp)
70-
require.Len(t, resp, 1)
71-
content, ok := resp[0].(mcp.TextResourceContents)
72-
require.True(t, ok)
73-
require.Equal(t, "application/json", content.MIMEType)
71+
require.False(t, resp.IsError)
72+
content := resp.Content[0].(mcp.TextContent).Text
73+
require.NotEmpty(t, content)
7474
})
7575
}
7676
}

0 commit comments

Comments
 (0)