Skip to content

Commit 282173e

Browse files
committed
WIP: Generic Tool Abstraction
Signed-off-by: Andrea Luzzardi <[email protected]>
1 parent 7e267e4 commit 282173e

File tree

3 files changed

+270
-90
lines changed

3 files changed

+270
-90
lines changed

mcpserver/args.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package mcpserver
2+
3+
import "github.com/mark3labs/mcp-go/mcp"
4+
5+
var (
6+
explainationArgument = mcp.WithString("explanation",
7+
mcp.Description("One sentence explanation for why this directory is being listed."),
8+
)
9+
environmentSourceArgument = mcp.WithString("environment_source",
10+
mcp.Description("Absolute path to the source git repository for the environment."),
11+
mcp.Required(),
12+
)
13+
environmentIDArgument = mcp.WithString("environment_id",
14+
mcp.Description("The ID of the environment for this command. Must call `environment_create` first."),
15+
mcp.Required(),
16+
)
17+
)
18+
19+
func newRepositoryTool(name string, description string, args ...mcp.ToolOption) mcp.Tool {
20+
opts := []mcp.ToolOption{
21+
mcp.WithDescription(description),
22+
explainationArgument,
23+
environmentSourceArgument,
24+
}
25+
opts = append(opts, args...)
26+
27+
return mcp.NewTool(name, opts...)
28+
}
29+
30+
func newEnvironmentTool(name string, description string, args ...mcp.ToolOption) mcp.Tool {
31+
opts := []mcp.ToolOption{
32+
mcp.WithDescription(description),
33+
explainationArgument,
34+
environmentSourceArgument,
35+
environmentIDArgument,
36+
}
37+
opts = append(opts, args...)
38+
39+
return mcp.NewTool(name, opts...)
40+
}

mcpserver/mcpserver.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package mcpserver
2+
3+
import (
4+
"context"
5+
6+
"dagger.io/dagger"
7+
"github.com/dagger/container-use/environment"
8+
"github.com/dagger/container-use/repository"
9+
"github.com/mark3labs/mcp-go/mcp"
10+
)
11+
12+
func dagFromContext(ctx context.Context) *dagger.Client {
13+
dag, ok := ctx.Value(daggerClientKey{}).(*dagger.Client)
14+
if !ok {
15+
panic("dagger client not found in context")
16+
}
17+
return dag
18+
}
19+
20+
type Request interface {
21+
isRequest()
22+
}
23+
24+
type BaseRequest struct {
25+
Explanation string `json:"explanation"`
26+
}
27+
28+
func (BaseRequest) isRequest() {}
29+
30+
type BaseRepositoryRequest struct {
31+
BaseRequest
32+
33+
EnvironmentSource string `json:"environment_source"`
34+
}
35+
36+
type BaseEnvironmentRequest struct {
37+
BaseRepositoryRequest
38+
39+
EnvironmentID string `json:"environment_id"`
40+
}
41+
42+
type Response any
43+
44+
type ToolResponse[T Response] struct {
45+
Message string
46+
Data T
47+
}
48+
49+
func openRepositoryFromRequest(ctx context.Context, request BaseRepositoryRequest) (*repository.Repository, error) {
50+
repo, err := repository.Open(ctx, request.EnvironmentSource)
51+
if err != nil {
52+
return nil, err
53+
}
54+
return repo, nil
55+
}
56+
57+
func openEnvironmentFromRequest(ctx context.Context, request BaseEnvironmentRequest) (*repository.Repository, *environment.Environment, error) {
58+
repo, err := openRepositoryFromRequest(ctx, request.BaseRepositoryRequest)
59+
if err != nil {
60+
return nil, nil, err
61+
}
62+
env, err := repo.Get(ctx, dagFromContext(ctx), request.EnvironmentID)
63+
if err != nil {
64+
return nil, nil, err
65+
}
66+
return repo, env, nil
67+
}
68+
69+
func parseBaseRequest(request mcp.CallToolRequest) (BaseRequest, error) {
70+
explanation, err := request.RequireString("explanation")
71+
if err != nil {
72+
return BaseRequest{}, err
73+
}
74+
return BaseRequest{
75+
Explanation: explanation,
76+
}, nil
77+
}
78+
79+
func parseBaseRepositoryRequest(request mcp.CallToolRequest) (BaseRepositoryRequest, error) {
80+
base, err := parseBaseRequest(request)
81+
if err != nil {
82+
return BaseRepositoryRequest{}, err
83+
}
84+
environmentSource, err := request.RequireString("environment_source")
85+
if err != nil {
86+
return BaseRepositoryRequest{}, err
87+
}
88+
return BaseRepositoryRequest{
89+
BaseRequest: base,
90+
EnvironmentSource: environmentSource,
91+
}, nil
92+
}
93+
94+
func parseBaseEnvironmentRequest(request mcp.CallToolRequest) (BaseEnvironmentRequest, error) {
95+
base, err := parseBaseRepositoryRequest(request)
96+
if err != nil {
97+
return BaseEnvironmentRequest{}, err
98+
}
99+
environmentID, err := request.RequireString("environment_id")
100+
if err != nil {
101+
return BaseEnvironmentRequest{}, err
102+
}
103+
return BaseEnvironmentRequest{
104+
BaseRepositoryRequest: base,
105+
EnvironmentID: environmentID,
106+
}, nil
107+
}

0 commit comments

Comments
 (0)